changeset: 87653:1ceb6f84b617 parent: 87651:a0ec33efa743 parent: 87652:96d1207d33d0 user: Alexandre Vassalotti date: Sat Nov 30 01:05:51 2013 -0800 files: Misc/NEWS Objects/typeobject.c description: Issue #19088: Merge with 3.3. diff -r a0ec33efa743 -r 1ceb6f84b617 Misc/NEWS --- a/Misc/NEWS Sat Nov 30 18:35:32 2013 +1000 +++ b/Misc/NEWS Sat Nov 30 01:05:51 2013 -0800 @@ -22,6 +22,9 @@ constructor is given a str. Move the array module typecode documentation to the docstring of the constructor. +- Issue #19088: Fixed incorrect caching of the copyreg module in + object.__reduce__() and object.__reduce_ex__(). + - Issue #19698: Removed exec_module() methods from importlib.machinery.BuiltinImporter and ExtensionFileLoader. diff -r a0ec33efa743 -r 1ceb6f84b617 Objects/typeobject.c --- a/Objects/typeobject.c Sat Nov 30 18:35:32 2013 +1000 +++ b/Objects/typeobject.c Sat Nov 30 01:05:51 2013 -0800 @@ -7,10 +7,6 @@ #include -/* 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 @@ -79,9 +75,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 @@ -3390,19 +3383,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); } Py_LOCAL(PyObject *)