diff options
author | Guido van Rossum <guido@python.org> | 1993-11-17 22:58:56 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1993-11-17 22:58:56 (GMT) |
commit | c45611d0e33ddd96fb9fffa8dc42a96384d5d270 (patch) | |
tree | 343959ada4542b5d4abc0a50802f434072da8e8b /Python | |
parent | 71e57d090d070686746ee63b855e38cb337dc5cc (diff) | |
download | cpython-c45611d0e33ddd96fb9fffa8dc42a96384d5d270.zip cpython-c45611d0e33ddd96fb9fffa8dc42a96384d5d270.tar.gz cpython-c45611d0e33ddd96fb9fffa8dc42a96384d5d270.tar.bz2 |
* 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].
Diffstat (limited to 'Python')
-rw-r--r-- | Python/import.c | 357 |
1 files changed, 185 insertions, 172 deletions
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 |