summaryrefslogtreecommitdiff
path: root/Python
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2009-01-06 18:10:47 +0000
committerAntoine Pitrou <solipsis@pitrou.net>2009-01-06 18:10:47 +0000
commite96d4ea4e235645452ae8a6c8ab557d31d2bb485 (patch)
tree20802b2b4711f32d21d422a7335cfdac7ddc4f34 /Python
parent3741bfdd3c789704f95b7969afa52f1053660e90 (diff)
downloadcpython-git-e96d4ea4e235645452ae8a6c8ab557d31d2bb485.tar.gz
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.
Diffstat (limited to 'Python')
-rw-r--r--Python/import.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/Python/import.c b/Python/import.c
index 08024b21db..e9ff922fd0 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -909,6 +909,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 (!_PyString_Eq(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 (strcmp(PyString_AsString(co->co_filename), pathname) == 0)
+ return 0;
+
+ newname = PyString_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
@@ -949,6 +992,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);