From d35cbf6e61cdf048a5ffe5413832eda970c277d8 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 6 Jan 2009 19:02:24 +0000 Subject: Merged revisions 68360-68361 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r68360 | antoine.pitrou | 2009-01-06 19:10:47 +0100 (mar., 06 janv. 2009) | 7 lines Issue #1180193: When importing a module from a .pyc (or .pyo) file with an existing .py counterpart, override the co_filename attributes of all code objects if the original filename is obsolete (which can happen if the file has been renamed, moved, or if it is accessed through different paths). Patch by Ziga Seilnacht and Jean-Paul Calderone. ........ r68361 | antoine.pitrou | 2009-01-06 19:34:08 +0100 (mar., 06 janv. 2009) | 3 lines Use shutil.rmtree rather than os.rmdir. ........ --- Python/import.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'Python/import.c') diff --git a/Python/import.c b/Python/import.c index d7858ef1bf..a486383c76 100644 --- a/Python/import.c +++ b/Python/import.c @@ -959,6 +959,49 @@ write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat) PySys_WriteStderr("# wrote %s\n", cpathname); } +static void +update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname) +{ + PyObject *constants, *tmp; + Py_ssize_t i, n; + + if (PyUnicode_Compare(co->co_filename, oldname)) + return; + + tmp = co->co_filename; + co->co_filename = newname; + Py_INCREF(co->co_filename); + Py_DECREF(tmp); + + constants = co->co_consts; + n = PyTuple_GET_SIZE(constants); + for (i = 0; i < n; i++) { + tmp = PyTuple_GET_ITEM(constants, i); + if (PyCode_Check(tmp)) + update_code_filenames((PyCodeObject *)tmp, + oldname, newname); + } +} + +static int +update_compiled_module(PyCodeObject *co, char *pathname) +{ + PyObject *oldname, *newname; + + if (!PyUnicode_CompareWithASCIIString(co->co_filename, pathname)) + return 0; + + newname = PyUnicode_FromString(pathname); + if (newname == NULL) + return -1; + + oldname = co->co_filename; + Py_INCREF(oldname); + update_code_filenames(co, oldname, newname); + Py_DECREF(oldname); + Py_DECREF(newname); + return 1; +} /* Load a source module from a given file and return its module object WITH INCREMENTED REFERENCE COUNT. If there's a matching @@ -999,6 +1042,8 @@ load_source_module(char *name, char *pathname, FILE *fp) fclose(fpc); if (co == NULL) return NULL; + if (update_compiled_module(co, pathname) < 0) + return NULL; if (Py_VerboseFlag) PySys_WriteStderr("import %s # precompiled from %s\n", name, cpathname); -- cgit v1.2.1