Makefile, import.c: Lance's alternative module search (allow .pyc file

without .py file); Bill's dynamic loading for SunOS using shared
libraries.

pwdmodule.c (mkgrent): remove DECREF of uninitialized variable.

classobject.c (instance_getattr): Fix case when class lookup returns
unbound method instead of function.
This commit is contained in:
Guido van Rossum 1993-10-15 13:01:11 +00:00
parent cbaddb52ae
commit 21d335ed9e
3 changed files with 130 additions and 104 deletions

View File

@ -120,7 +120,6 @@ static object *mkgrent(p)
object *v, *w; object *v, *w;
char **member; char **member;
if ((w = newlistobject(0)) == NULL) { if ((w = newlistobject(0)) == NULL) {
DECREF(v);
return NULL; return NULL;
} }
for (member = p->gr_mem; *member != NULL; member++) { for (member = p->gr_mem; *member != NULL; member++) {

View File

@ -379,11 +379,24 @@ instance_getattr(inst, name)
} }
else else
INCREF(v); INCREF(v);
if (is_funcobject(v) && class != NULL) { if (class != NULL) {
object *w = newinstancemethodobject(v, (object *)inst, if (is_funcobject(v)) {
(object *)class); object *w = newinstancemethodobject(v, (object *)inst,
DECREF(v); (object *)class);
v = w; DECREF(v);
v = w;
}
else if (is_instancemethodobject(v)) {
object *im_class = instancemethodgetclass(v);
/* Only if classes are compatible */
if (issubclass((object *)class, im_class)) {
object *im_func = instancemethodgetfunc(v);
object *w = newinstancemethodobject(im_func,
(object *)inst, im_class);
DECREF(v);
v = w;
}
}
} }
return v; return v;
} }

View File

@ -40,6 +40,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern int verbose; /* Defined in pythonmain.c */ extern int verbose; /* Defined in pythonmain.c */
extern long getmtime(); /* Defined in posixmodule.c */
#ifdef DEBUG #ifdef DEBUG
#define D(x) x #define D(x) x
#else #else
@ -47,7 +49,12 @@ extern int verbose; /* Defined in pythonmain.c */
#endif #endif
#ifdef USE_DL #ifdef USE_DL
#ifdef SUN_SHLIB
#include <dlfcn.h>
typedef void (*dl_funcptr)();
#else
#include "dl.h" #include "dl.h"
#endif /* SUN_SHLIB */
extern char *argv0; extern char *argv0;
#endif #endif
@ -94,44 +101,46 @@ add_module(name)
return m; return m;
} }
/* Suffixes used by open_module: */ /* Suffixes used by find_module: */
#define PY_SUFFIX ".py" #define PY_SUFFIX ".py"
#define PYC_SUFFIX ".pyc"
#ifdef USE_DL #ifdef USE_DL
#ifdef SUN_SHLIB
#define O_SUFFIX "module.so"
#else
#define O_SUFFIX "module.o" #define O_SUFFIX "module.o"
#endif /* SUN_SHLIB */
#endif #endif
/* Find and open a module file, using sys.path. /* This will search for a module named 'name' with the extension 'ext'
Return a NULL pointer if no module file is found. and return it in 'namebuf' and return the mtime of each in 'mtime'.
When dynamic loading is enabled, the contents of namebuf It returns a file pointer opened for 'mode' if successful, NULL if
is important when NULL is returned: if namebuf[0] != '\0' unsuccessful.
a dl-able object file was found and namebuf is its pathname. */ */
static FILE * static FILE *
open_module(name, namebuf) find_module(name, ext, mode, namebuf, mtime)
char *name; char *name;
char *namebuf; /* XXX No buffer overflow checks! */ char *ext;
char *mode;
char *namebuf;
long *mtime;
{ {
object *path; object *path;
FILE *fp; FILE *fp;
path = sysget("path"); path = sysget("path");
if (path == NULL || !is_listobject(path)) { if (path == NULL || !is_listobject(path)) {
/* No path -- at least try current directory */ /* No path -- at least try current directory */
#ifdef USE_DL
strcpy(namebuf, name); strcpy(namebuf, name);
strcat(namebuf, O_SUFFIX); strcat(namebuf, ext);
if (getmtime(namebuf) > 0) if ((fp = fopen(namebuf, mode)) == NULL)
return NULL; return NULL;
#endif *mtime = getmtime(namebuf);
strcpy(namebuf, name); return fp;
strcat(namebuf, PY_SUFFIX); } else {
fp = fopen(namebuf, "r");
}
else {
int npath = getlistsize(path); int npath = getlistsize(path);
int i; int i;
fp = NULL;
for (i = 0; i < npath; i++) { for (i = 0; i < npath; i++) {
object *v = getlistitem(path, i); object *v = getlistitem(path, i);
int len; int len;
@ -141,22 +150,16 @@ open_module(name, namebuf)
len = getstringsize(v); len = getstringsize(v);
if (len > 0 && namebuf[len-1] != SEP) if (len > 0 && namebuf[len-1] != SEP)
namebuf[len++] = SEP; namebuf[len++] = SEP;
#ifdef USE_DL
strcpy(namebuf+len, name); strcpy(namebuf+len, name);
strcat(namebuf, O_SUFFIX); strcat(namebuf, ext);
if (getmtime(namebuf) > 0) if ((fp = fopen(namebuf, mode)) == NULL)
return NULL; continue;
#endif *mtime = getmtime(namebuf);
strcpy(namebuf+len, name); return fp;
strcat(namebuf, PY_SUFFIX);
fp = fopen(namebuf, "r");
if (fp != NULL)
break;
} }
} }
if (fp == NULL) namebuf[0] = '\0';
namebuf[0] = '\0'; return NULL;
return fp;
} }
static object * static object *
@ -173,66 +176,63 @@ get_module(m, name, m_ret)
char namebuf[MAXPATHLEN+1]; char namebuf[MAXPATHLEN+1];
int namelen; int namelen;
long mtime; long mtime;
extern long getmtime();
fp = open_module(name, namebuf);
if (fp == NULL) {
#ifdef USE_DL #ifdef USE_DL
if (namebuf[0] != '\0') { if ((fpc = find_module(name, O_SUFFIX, "rb",
char funcname[258]; namebuf, &mtime)) != NULL) {
dl_funcptr p; char funcname[258];
D(fprintf(stderr, "Found %s\n", namebuf)); dl_funcptr p;
sprintf(funcname, "init%s", name); D(fprintf(stderr, "Found %s\n", namebuf));
p = dl_loadmod(argv0, namebuf, funcname); fclose(fpc);
if (p == NULL) { sprintf(funcname, "init%s", name);
D(fprintf(stderr, "dl_loadmod failed\n")); #ifdef SUN_SHLIB
} {
else { void *handle = dlopen (namebuf, 1);
if (verbose) p = (dl_funcptr) dlsym(handle, funcname);
fprintf(stderr, }
"import %s # dynamically loaded from \"%s\"\n", #else
name, namebuf); p = dl_loadmod(argv0, namebuf, funcname);
(*p)(); #endif /* SUN_SHLIB */
*m_ret = m = dictlookup(modules, name); if (p == NULL) {
if (m == NULL) { D(fprintf(stderr, "dl_loadmod failed\n"));
err_setstr(SystemError, } else {
"dynamic module missing"); if (verbose)
return NULL; fprintf(stderr,
} "import %s # dynamically loaded from \"%s\"\n",
else { name, namebuf);
D(fprintf(stderr, (*p)();
"module %s loaded!\n", name)); *m_ret = m = dictlookup(modules, name);
INCREF(None); if (m == NULL) {
return None; err_setstr(SystemError,
} "dynamic module missing");
return NULL;
} else {
D(fprintf(stderr,
"module %s loaded!\n", name));
INCREF(None);
return None;
} }
} }
#endif
if (m == NULL) {
sprintf(namebuf, "no module named %.200s", name);
err_setstr(ImportError, namebuf);
}
else {
sprintf(namebuf, "no source for module %.200s", name);
err_setstr(ImportError, namebuf);
}
return NULL;
} }
/* Get mtime -- always useful */ else
mtime = getmtime(namebuf); #endif
/* Check ".pyc" file first */ if ((fpc = find_module(name, PYC_SUFFIX, "rb",
namelen = strlen(namebuf); namebuf, &mtime)) != NULL) {
namebuf[namelen] = 'c';
namebuf[namelen+1] = '\0';
fpc = fopen(namebuf, "rb");
if (fpc != NULL) {
long pyc_mtime; long pyc_mtime;
long magic; long magic;
namebuf[(strlen(namebuf)-1)] = '\0';
mtime = getmtime(namebuf);
magic = rd_long(fpc); magic = rd_long(fpc);
pyc_mtime = rd_long(fpc); pyc_mtime = rd_long(fpc);
if (magic == MAGIC && pyc_mtime == mtime && mtime != 0 && mtime != -1) { if (mtime != -1 && mtime > pyc_mtime) {
fclose(fpc);
fp = fopen(namebuf, "rb");
goto read_py;
}
if (magic == MAGIC) {
v = rd_object(fpc); v = rd_object(fpc);
if (v == NULL || err_occurred() || !is_codeobject(v)) { if (v == NULL || err_occurred() ||
!is_codeobject(v)) {
err_clear(); err_clear();
XDECREF(v); XDECREF(v);
} }
@ -243,27 +243,41 @@ get_module(m, name, m_ret)
if (verbose) { if (verbose) {
if (co != NULL) if (co != NULL)
fprintf(stderr, fprintf(stderr,
"import %s # precompiled from \"%s\"\n", "import %s # precompiled from \"%s\"\n",
name, namebuf); name, namebuf);
else else
fprintf(stderr, fprintf(stderr,
"# invalid precompiled file \"%s\"\n", "# invalid precompiled file \"%s\"\n",
namebuf); namebuf);
} }
} }
namebuf[namelen] = '\0'; else if ((fp = find_module(name, PY_SUFFIX, "r",
if (co == NULL) { namebuf, &mtime)) != NULL) {
if (verbose) read_py:
fprintf(stderr, namelen = strlen(namebuf);
"import %s # from \"%s\"\n", if (co == NULL) {
name, namebuf); if (verbose)
err = parse_file(fp, namebuf, file_input, &n); fprintf(stderr,
"import %s # from \"%s\"\n",
name, namebuf);
err = parse_file(fp, namebuf, file_input, &n);
} else
err = E_DONE;
fclose(fp);
if (err != E_DONE) {
err_input(err);
return NULL;
}
} }
else else {
err = E_DONE; if (m == NULL) {
fclose(fp); sprintf(namebuf, "no module named %.200s", name);
if (err != E_DONE) { err_setstr(ImportError, namebuf);
err_input(err); }
else {
sprintf(namebuf, "no source for module %.200s", name);
err_setstr(ImportError, namebuf);
}
return NULL; return NULL;
} }
if (m == NULL) { if (m == NULL) {