[Python-checkins] cpython (3.3): Issue #19088: Fix incorrect caching of the copyreg module.

alexandre.vassalotti python-checkins at python.org
Sat Nov 30 10:06:16 CET 2013


http://hg.python.org/cpython/rev/96d1207d33d0
changeset:   87652:96d1207d33d0
branch:      3.3
parent:      87645:63f3e8670fa6
user:        Alexandre Vassalotti <alexandre at peadrop.com>
date:        Sat Nov 30 00:53:09 2013 -0800
summary:
  Issue #19088: Fix incorrect caching of the copyreg module.

This fix does not cause any degradation in performance.

files:
  Misc/NEWS            |   3 ++
  Objects/typeobject.c |  43 +++++++++++++++++--------------
  2 files changed, 26 insertions(+), 20 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,9 @@
 Library
 -------
 
+- Issue #19088: Fixed incorrect caching of the copyreg module in
+  object.__reduce__() and object.__reduce_ex__().
+
 - Issue #11508: Fixed uuid.getnode() and uuid.uuid1() on environment with
   virtual interface.  Original patch by Kent Frazier.
 
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -7,10 +7,6 @@
 #include <ctype.h>
 
 
-/* Cached lookup of the copyreg module, for faster __reduce__ calls */
-
-static PyObject *cached_copyreg_module = NULL;
-
 /* Support type attribute cache */
 
 /* The cache can keep references to the names alive for longer than
@@ -73,9 +69,6 @@
 _PyType_Fini(void)
 {
     PyType_ClearCache();
-    /* Need to forget our obsolete instance of the copyreg module at
-     * interpreter shutdown (issue #17408). */
-    Py_CLEAR(cached_copyreg_module);
 }
 
 void
@@ -3348,19 +3341,29 @@
 static PyObject *
 import_copyreg(void)
 {
-    static PyObject *copyreg_str;
-
-    if (!copyreg_str) {
-        copyreg_str = PyUnicode_InternFromString("copyreg");
-        if (copyreg_str == NULL)
-            return NULL;
-    }
-    if (!cached_copyreg_module) {
-        cached_copyreg_module = PyImport_Import(copyreg_str);
-    }
-
-    Py_XINCREF(cached_copyreg_module);
-    return cached_copyreg_module;
+    PyObject *copyreg_str;
+    PyObject *copyreg_module;
+    PyInterpreterState *interp = PyThreadState_GET()->interp;
+    _Py_IDENTIFIER(copyreg);
+
+    copyreg_str = _PyUnicode_FromId(&PyId_copyreg);
+    if (copyreg_str == NULL) {
+        return NULL;
+    }
+    /* Try to fetch cached copy of copyreg from sys.modules first in an
+       attempt to avoid the import overhead. Previously this was implemented
+       by storing a reference to the cached module in a static variable, but
+       this broke when multiple embeded interpreters were in use (see issue
+       #17408 and #19088). */
+    copyreg_module = PyDict_GetItemWithError(interp->modules, copyreg_str);
+    if (copyreg_module != NULL) {
+        Py_INCREF(copyreg_module);
+        return copyreg_module;
+    }
+    if (PyErr_Occurred()) {
+        return NULL;
+    }
+    return PyImport_Import(copyreg_str);
 }
 
 static PyObject *

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list