summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1993-11-17 22:58:56 (GMT)
committerGuido van Rossum <guido@python.org>1993-11-17 22:58:56 (GMT)
commitc45611d0e33ddd96fb9fffa8dc42a96384d5d270 (patch)
tree343959ada4542b5d4abc0a50802f434072da8e8b
parent71e57d090d070686746ee63b855e38cb337dc5cc (diff)
downloadcpython-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].
-rw-r--r--Modules/stdwinmodule.c13
-rw-r--r--Objects/moduleobject.c51
-rw-r--r--Python/import.c357
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, "<module '%.80s'>", getstringvalue(m->md_name));
+ char *name = getmodulename((object *)m);
+ if (name == NULL) {
+ err_clear();
+ name = "?";
+ }
+ sprintf(buf, "<module '%.80s'>", 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