From c45611d0e33ddd96fb9fffa8dc42a96384d5d270 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 17 Nov 1993 22:58:56 +0000 Subject: * import.c (get_module): total rewrite, to ensure proper search order: for each dir in sys.path, try each possible extension. (Note: C extensions are loaded before Python modules in the same directory, to allow having a C version used when dynamic loading is supported and a Python version as a back-up.) * import.c (reload_module): test for error from getmodulename() * moduleobject.c: implement module name as dict entry '__name__' instead of special-casing it in module_getattr(); this way a module (or function!) can access its own module name, and programs that know what they are doing can rename modules. * stdwinmodule.c (initstdwin): strip ".py" suffix of argv[0]. --- Modules/stdwinmodule.c | 13 ++ Objects/moduleobject.c | 51 ++++--- Python/import.c | 357 +++++++++++++++++++++++++------------------------ 3 files changed, 228 insertions(+), 193 deletions(-) diff --git a/Modules/stdwinmodule.c b/Modules/stdwinmodule.c index 1fff814..fc81cff 100644 --- a/Modules/stdwinmodule.c +++ b/Modules/stdwinmodule.c @@ -2598,6 +2598,7 @@ initstdwin() { object *m, *d; static int inited = 0; + char buf[1000]; if (!inited) { int argc = 0; @@ -2607,6 +2608,18 @@ initstdwin() if (!checkstringlist(sys_argv, &argv, &argc)) err_clear(); } + if (argc > 0) { + /* If argv[0] has a ".py" suffix, remove the suffix */ + char *p = strrchr(argv[0], '.'); + if (p != NULL && strcmp(p, ".py") == 0) { + int n = p - argv[0]; + if (n >= sizeof(buf)) + n = sizeof(buf)-1; + strncpy(buf, argv[0], n); + buf[n] = '\0'; + argv[0] = buf; + } + } winitargs(&argc, &argv); if (argv != NULL) { if (!putbackstringlist(sys_argv, argv, argc)) diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index dca5543..9a687b4 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -29,7 +29,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. typedef struct { OB_HEAD - object *md_name; object *md_dict; } moduleobject; @@ -37,16 +36,24 @@ object * newmoduleobject(name) char *name; { - moduleobject *m = NEWOBJ(moduleobject, &Moduletype); + moduleobject *m; + object *nameobj; + m = NEWOBJ(moduleobject, &Moduletype); if (m == NULL) return NULL; - m->md_name = newstringobject(name); + nameobj = newstringobject(name); m->md_dict = newdictobject(); - if (m->md_name == NULL || m->md_dict == NULL) { - DECREF(m); - return NULL; - } + if (m->md_dict == NULL || nameobj == NULL) + goto fail; + if (dictinsert(m->md_dict, "__name__", nameobj) != 0) + goto fail; + DECREF(nameobj); return (object *)m; + + fail: + XDECREF(nameobj); + DECREF(m); + return NULL; } object * @@ -64,11 +71,17 @@ char * getmodulename(m) object *m; { + object *nameobj; if (!is_moduleobject(m)) { err_badarg(); return NULL; } - return getstringvalue(((moduleobject *)m) -> md_name); + nameobj = dictlookup(((moduleobject *)m)->md_dict, "__name__"); + if (nameobj == NULL || !is_stringobject(nameobj)) { + err_setstr(SystemError, "nameless module"); + return NULL; + } + return getstringvalue(nameobj); } /* Methods */ @@ -77,8 +90,6 @@ static void module_dealloc(m) moduleobject *m; { - if (m->md_name != NULL) - DECREF(m->md_name); if (m->md_dict != NULL) DECREF(m->md_dict); free((char *)m); @@ -89,7 +100,12 @@ module_repr(m) moduleobject *m; { char buf[100]; - sprintf(buf, "", getstringvalue(m->md_name)); + char *name = getmodulename((object *)m); + if (name == NULL) { + err_clear(); + name = "?"; + } + sprintf(buf, "", name); return newstringobject(buf); } @@ -103,10 +119,6 @@ module_getattr(m, name) INCREF(m->md_dict); return m->md_dict; } - if (strcmp(name, "__name__") == 0) { - INCREF(m->md_name); - return m->md_name; - } res = dictlookup(m->md_dict, name); if (res == NULL) err_setstr(AttributeError, name); @@ -126,12 +138,9 @@ module_setattr(m, name, v) object *v; { object *ac; - if (name[0] == '_' && name[1] == '_') { - int n = strlen(name); - if (name[n-1] == '_' && name[n-2] == '_') { - err_setstr(TypeError, "read-only special attribute"); - return -1; - } + if (name[0] == '_' && strcmp(name, "__dict__") == 0) { + err_setstr(TypeError, "read-only special attribute"); + return -1; } ac = dictlookup(m->md_dict, name); if (ac != NULL && is_accessobject(ac)) diff --git a/Python/import.c b/Python/import.c index b81a41e..2fc3995 100644 --- a/Python/import.c +++ b/Python/import.c @@ -101,89 +101,188 @@ add_module(name) return m; } -/* Suffixes used by find_module: */ +enum filetype {SEARCH_ERROR, PY_SOURCE, PY_COMPILED, C_EXTENSION}; -#define PY_SUFFIX ".py" -#define PYC_SUFFIX ".pyc" +static struct filedescr { + char *suffix; + char *mode; + enum filetype type; +} filetab[] = { #ifdef USE_DL #ifdef SUN_SHLIB -#define O_SUFFIX "module.so" + {"module.so", "rb", C_EXTENSION}, #else -#define O_SUFFIX "module.o" + {"module.o", "rb", C_EXTENSION}, #endif /* SUN_SHLIB */ -#endif +#endif /* USE_DL */ + {".py", "r", PY_SOURCE}, + {".pyc", "rb", PY_COMPILED}, + {0, 0} +}; -/* This will search for a module named 'name' with the extension 'ext' - and return it in 'namebuf' and return the mtime of each in 'mtime'. - It returns a file pointer opened for 'mode' if successful, NULL if - unsuccessful. - */ -static FILE * -find_module(name, ext, mode, namebuf, mtime) +static object * +get_module(m, name, m_ret) + /*module*/object *m; char *name; - char *ext; - char *mode; - char *namebuf; - long *mtime; + object **m_ret; { - object *path; - FILE *fp; + int err, npath, i, len; + long magic; + long mtime, pyc_mtime; + char namebuf[MAXPATHLEN+1]; + struct filedescr *fdp; + FILE *fp = NULL, *fpc = NULL; + node *n = NULL; + object *path, *v, *d; + codeobject *co = NULL; path = sysget("path"); if (path == NULL || !is_listobject(path)) { - /* No path -- at least try current directory */ - strcpy(namebuf, name); - strcat(namebuf, ext); - if ((fp = fopen(namebuf, mode)) == NULL) - return NULL; - *mtime = getmtime(namebuf); - return fp; - } else { - int npath = getlistsize(path); - int i; - for (i = 0; i < npath; i++) { - object *v = getlistitem(path, i); - int len; - if (!is_stringobject(v)) - continue; - strcpy(namebuf, getstringvalue(v)); - len = getstringsize(v); - if (len > 0 && namebuf[len-1] != SEP) - namebuf[len++] = SEP; - strcpy(namebuf+len, name); - strcat(namebuf, ext); - if ((fp = fopen(namebuf, mode)) == NULL) - continue; - *mtime = getmtime(namebuf); - return fp; + err_setstr(ImportError, + "sys.path must be list of directory names"); + return NULL; + } + npath = getlistsize(path); + for (i = 0; i < npath; i++) { + v = getlistitem(path, i); + if (!is_stringobject(v)) + continue; + strcpy(namebuf, getstringvalue(v)); + len = getstringsize(v); + if (len > 0 && namebuf[len-1] != SEP) + namebuf[len++] = SEP; + strcpy(namebuf+len, name); + len += strlen(name); + for (fdp = filetab; fdp->suffix != NULL; fdp++) { + strcpy(namebuf+len, fdp->suffix); + if (verbose > 1) + fprintf(stderr, "# trying %s\n", namebuf); + fp = fopen(namebuf, fdp->mode); + if (fp != NULL) + break; } + if (fp != NULL) + break; + } + if (fp == NULL) { + sprintf(namebuf, "No module named %s", name); + err_setstr(ImportError, namebuf); + return NULL; } - namebuf[0] = '\0'; - return NULL; -} -static object * -get_module(m, name, m_ret) - /*module*/object *m; - char *name; - object **m_ret; -{ - codeobject *co = NULL; - object *v, *d; - FILE *fp, *fpc; - node *n; - int err; - char namebuf[MAXPATHLEN+1]; - int namelen; - long mtime; + switch (fdp->type) { + + case PY_SOURCE: + mtime = getmtime(namebuf); + strcat(namebuf, "c"); + fpc = fopen(namebuf, "rb"); + if (fpc != NULL) { + magic = rd_long(fpc); + if (magic != MAGIC) { + if (verbose) + fprintf(stderr, + "# %s.pyc has bad magic\n", + name); + } + else { + pyc_mtime = rd_long(fpc); + if (pyc_mtime != mtime) { + if (verbose) + fprintf(stderr, + "# %s.pyc has bad mtime\n", + name); + } + else { + fclose(fp); + fp = fpc; + if (verbose) + fprintf(stderr, + "# %s.pyc matches %s.py\n", + name, name); + goto use_compiled; + } + } + fclose(fpc); + } + err = parse_file(fp, namebuf, file_input, &n); + if (err != E_DONE) { + err_input(err); + return NULL; + } + co = compile(n, namebuf); + freetree(n); + if (co == NULL) + return NULL; + if (verbose) + fprintf(stderr, + "import %s # from %.*s\n", + name, strlen(namebuf)-1, namebuf); + /* Now write the code object to the ".pyc" file */ + fpc = fopen(namebuf, "wb"); + if (fpc == NULL) { + if (verbose) + fprintf(stderr, + "# can't create %s\n", namebuf); + } + else { + wr_long(MAGIC, fpc); + /* First write a 0 for mtime */ + wr_long(0L, fpc); + wr_object((object *)co, fpc); + if (ferror(fpc)) { + if (verbose) + fprintf(stderr, + "# can't write %s\n", namebuf); + /* Don't keep partial file */ + fclose(fpc); + (void) unlink(namebuf); + } + else { + /* Now write the true mtime */ + fseek(fpc, 4L, 0); + wr_long(mtime, fpc); + fflush(fpc); + fclose(fpc); + if (verbose) + fprintf(stderr, + "# wrote %s\n", namebuf); + } + } + break; + + case PY_COMPILED: + if (verbose) + fprintf(stderr, "# %s.pyc without %s.py\n", + name, name); + magic = rd_long(fp); + if (magic != MAGIC) { + err_setstr(ImportError, + "Bad magic number in .pyc file"); + return NULL; + } + (void) rd_long(fp); + use_compiled: + v = rd_object(fp); + fclose(fp); + if (v == NULL || !is_codeobject(v)) { + XDECREF(v); + err_setstr(ImportError, + "Bad code object in .pyc file"); + return NULL; + } + co = (codeobject *)v; + if (verbose) + fprintf(stderr, + "import %s # precompiled from %s\n", + name, namebuf); + break; #ifdef USE_DL - if ((fpc = find_module(name, O_SUFFIX, "rb", - namebuf, &mtime)) != NULL) { + case C_EXTENSION: + { char funcname[258]; dl_funcptr p; - D(fprintf(stderr, "Found %s\n", namebuf)); - fclose(fpc); + fclose(fp); sprintf(funcname, "init%s", name); #ifdef SUN_SHLIB { @@ -191,14 +290,10 @@ get_module(m, name, m_ret) p = (dl_funcptr) dlsym(handle, funcname); } #else - if (verbose) - fprintf(stderr, - "import %s # dynamically loaded from \"%s\"\n", - name, namebuf); p = dl_loadmod(argv0, namebuf, funcname); #endif /* SUN_SHLIB */ if (p == NULL) { - err_setstr(SystemError, + err_setstr(ImportError, "dynamic module does not define init function"); return NULL; } else { @@ -209,85 +304,27 @@ get_module(m, name, m_ret) "dynamic module not initialized properly"); return NULL; } else { - D(fprintf(stderr, - "module %s loaded!\n", name)); - INCREF(None); - return None; - } - } - } - else -#endif - if ((fpc = find_module(name, PYC_SUFFIX, "rb", - namebuf, &mtime)) != NULL) { - long pyc_mtime; - long magic; - namebuf[(strlen(namebuf)-1)] = '\0'; - mtime = getmtime(namebuf); - magic = rd_long(fpc); - pyc_mtime = rd_long(fpc); - if (mtime != -1 && mtime > pyc_mtime) { - fclose(fpc); - goto read_py; - } - if (magic == MAGIC) { - v = rd_object(fpc); - if (v == NULL || err_occurred() || - !is_codeobject(v)) { - err_clear(); - XDECREF(v); - } - else - co = (codeobject *)v; - } - fclose(fpc); - if (verbose) { - if (co != NULL) - fprintf(stderr, - "import %s # precompiled from \"%s\"\n", - name, namebuf); - else { - fprintf(stderr, - "# invalid precompiled file \"%s\"\n", - namebuf); - } - } - if (co == NULL) - goto read_py; - } - else { -read_py: - if ((fp = find_module(name, PY_SUFFIX, "r", - namebuf, &mtime)) != NULL) { - namelen = strlen(namebuf); - if (co == NULL) { if (verbose) fprintf(stderr, - "import %s # from \"%s\"\n", + "import %s # dynamically loaded 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 { - 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); + INCREF(None); + return None; } - return NULL; } + break; + } +#endif /* USE_DL */ + + default: + fclose(fp); + err_setstr(SystemError, + "search loop returned unexpected result"); + return NULL; + } + + /* We get here for either PY_SOURCE or PY_COMPILED */ if (m == NULL) { m = add_module(name); if (m == NULL) { @@ -297,34 +334,6 @@ read_py: *m_ret = m; } d = getmoduledict(m); - if (co == NULL) { - co = compile(n, namebuf); - freetree(n); - if (co == NULL) - return NULL; - /* Now write the code object to the ".pyc" file */ - namebuf[namelen] = 'c'; - namebuf[namelen+1] = '\0'; - fpc = fopen(namebuf, "wb"); - if (fpc != NULL) { - wr_long(MAGIC, fpc); - /* First write a 0 for mtime */ - wr_long(0L, fpc); - wr_object((object *)co, fpc); - if (ferror(fpc)) { - /* Don't keep partial file */ - fclose(fpc); - (void) unlink(namebuf); - } - else { - /* Now write the true mtime */ - fseek(fpc, 4L, 0); - wr_long(mtime, fpc); - fflush(fpc); - fclose(fpc); - } - } - } v = eval_code(co, d, d, d, (object *)NULL); DECREF(co); return v; @@ -367,12 +376,16 @@ object * reload_module(m) object *m; { + char *name; if (m == NULL || !is_moduleobject(m)) { err_setstr(TypeError, "reload() argument must be module"); return NULL; } + name = getmodulename(m); + if (name == NULL) + return NULL; /* XXX Ought to check for builtin modules -- can't reload these... */ - return get_module(m, getmodulename(m), (object **)NULL); + return get_module(m, name, (object **)NULL); } void -- cgit v0.12