Merged revisions 68360 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.
........
This commit is contained in:
Antoine Pitrou 2009-01-06 19:00:59 +00:00
parent 8fe413119c
commit 5b0767c31d
3 changed files with 144 additions and 1 deletions

View file

@ -910,6 +910,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
@ -950,6 +993,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);