]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
* import.c (get_module): total rewrite, to ensure proper search order: for
authorGuido van Rossum <guido@python.org>
Wed, 17 Nov 1993 22:58:56 +0000 (22:58 +0000)
committerGuido van Rossum <guido@python.org>
Wed, 17 Nov 1993 22:58:56 +0000 (22:58 +0000)
  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
Objects/moduleobject.c
Python/import.c

index 1fff814a39fb2d9242d34811992cec0ae3b0ab2c..fc81cffded6f40f0f6047928eef5004e211b3ffa 100644 (file)
@@ -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))
index dca5543eb10b4a5cc3ba0ee1c224af4d8f6327a2..9a687b4c3bfdc150be1fd4188214dd9eb3198b65 100644 (file)
@@ -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))
index b81a41e463bfaf5afd8f8c16721735fc7c1062b9..2fc3995a01f6b6f6188d56a050f9296af11cf38c 100644 (file)
@@ -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