diff options
author | Alexandre Vassalotti <alexandre@peadrop.com> | 2013-11-30 09:05:51 (GMT) |
---|---|---|
committer | Alexandre Vassalotti <alexandre@peadrop.com> | 2013-11-30 09:05:51 (GMT) |
commit | cc6e87b2cf7613bc88791516bf4d6e0669d084d2 (patch) | |
tree | 66b368af1570b6940581946eb825bcc6aed7c45c /Objects | |
parent | 8ddd59e870c0a0624f54a415297350f57ac9b57f (diff) | |
parent | 1a83070d9e5e6f88fb422d442ad88574db63cb93 (diff) | |
download | cpython-cc6e87b2cf7613bc88791516bf4d6e0669d084d2.zip cpython-cc6e87b2cf7613bc88791516bf4d6e0669d084d2.tar.gz cpython-cc6e87b2cf7613bc88791516bf4d6e0669d084d2.tar.bz2 |
Issue #19088: Merge with 3.3.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/typeobject.c | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 42a0a58..8b2ea1c 100644 --- 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 @@ -79,9 +75,6 @@ void _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 PyGetSetDef object_getsets[] = { static PyObject * import_copyreg(void) { - static PyObject *copyreg_str; + PyObject *copyreg_str; + PyObject *copyreg_module; + PyInterpreterState *interp = PyThreadState_GET()->interp; + _Py_IDENTIFIER(copyreg); - if (!copyreg_str) { - copyreg_str = PyUnicode_InternFromString("copyreg"); - if (copyreg_str == NULL) - return NULL; + copyreg_str = _PyUnicode_FromId(&PyId_copyreg); + if (copyreg_str == NULL) { + return NULL; } - if (!cached_copyreg_module) { - cached_copyreg_module = PyImport_Import(copyreg_str); + /* 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; } - - Py_XINCREF(cached_copyreg_module); - return cached_copyreg_module; + return PyImport_Import(copyreg_str); } Py_LOCAL(PyObject *) |