I quickly whipped up this (procastinating on my OSCON keynote slides :-):
Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.233 diff -c -u -r2.233 import.c --- import.c 27 Jun 2004 16:51:46 -0000 2.233 +++ import.c 28 Jul 2004 18:57:15 -0000 @@ -572,17 +572,23 @@ { PyObject *modules = PyImport_GetModuleDict(); PyObject *m, *d, *v; + int pre_existing = 0;
- m = PyImport_AddModule(name); - if (m == NULL) - return NULL; + if ((m = PyDict_GetItemString(modules, name)) != NULL && + PyModule_Check(m)) + pre_existing = 1; + else { + m = PyImport_AddModule(name); + if (m == NULL) + return NULL; + } /* If the module is being reloaded, we get the old module back and re-use its dict to exec the new code. */ d = PyModule_GetDict(m); if (PyDict_GetItemString(d, "__builtins__") == NULL) { if (PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins()) != 0) - return NULL; + goto error; } /* Remember the filename as the __file__ attribute */ v = NULL; @@ -601,7 +607,7 @@
v = PyEval_EvalCode((PyCodeObject *)co, d, d); if (v == NULL) - return NULL; + goto error; Py_DECREF(v);
if ((m = PyDict_GetItemString(modules, name)) == NULL) { @@ -614,6 +620,11 @@ Py_INCREF(m);
return m; + + error: + if (!pre_existing) + PyDict_DelItemString(modules, name); /* If it fails, too bad */ + return NULL; }
Superficial testing suggests it works fine, except for one problem in test_pkgimport which is testing specifically for the broken behavior.
BTW, building CVS Python gives these warnings for me:
/home/guido/projects/python/dist/src/Modules/cjkcodecs/_codecs_iso2022.c:120: array size missing in `designations' /home/guido/projects/python/dist/src/Modules/cjkcodecs/_codecs_iso2022.c: In function `iso2022processesc': /home/guido/projects/python/dist/src/Modules/cjkcodecs/_codecs_iso2022.c:306: warning: `esclen' might be used uninitialized in this function /home/guido/projects/python/dist/src/Modules/cjkcodecs/_codecs_iso2022.c: At top level: /home/guido/projects/python/dist/src/Modules/cjkcodecs/_codecs_iso2022.c:1053: warning: excess elements in array initializer /home/guido/projects/python/dist/src/Modules/cjkcodecs/_codecs_iso2022.c:1053: warning: (near initialization for `iso2022_kr_config.designations') /home/guido/projects/python/dist/src/Modules/cjkcodecs/_codecs_iso2022.c:1058: warning: excess elements in array initializer [and many more similar]
Red Hat 7.3 using gcc 2.96.
--Guido van Rossum (home page: http://www.python.org/~guido/)