diff Python/import.c @ 50619:2ff9910f1526

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. ........
author Antoine Pitrou <solipsis@pitrou.net>
date Tue, 06 Jan 2009 19:02:24 +0000
parents 4d1a68bd8076
children a823c9f3a452
line wrap: on
line diff
--- a/Python/import.c	Tue Jan 06 09:37:13 2009 +0000
+++ b/Python/import.c	Tue Jan 06 19:02:24 2009 +0000
@@ -959,6 +959,49 @@
 		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 @@
 		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);