|
7 | 7 | #include <ctype.h> |
8 | 8 |
|
9 | 9 |
|
10 | | -/* Cached lookup of the copyreg module, for faster __reduce__ calls */ |
11 | | - |
12 | | -static PyObject *cached_copyreg_module = NULL; |
13 | | - |
14 | 10 | /* Support type attribute cache */ |
15 | 11 |
|
16 | 12 | /* The cache can keep references to the names alive for longer than |
|
73 | 69 | _PyType_Fini(void) |
74 | 70 | { |
75 | 71 | PyType_ClearCache(); |
76 | | - /* Need to forget our obsolete instance of the copyreg module at |
77 | | - * interpreter shutdown (issue #17408). */ |
78 | | - Py_CLEAR(cached_copyreg_module); |
79 | 72 | } |
80 | 73 |
|
81 | 74 | void |
@@ -3348,19 +3341,29 @@ static PyGetSetDef object_getsets[] = { |
3348 | 3341 | static PyObject * |
3349 | 3342 | import_copyreg(void) |
3350 | 3343 | { |
3351 | | - static PyObject *copyreg_str; |
| 3344 | + PyObject *copyreg_str; |
| 3345 | + PyObject *copyreg_module; |
| 3346 | + PyInterpreterState *interp = PyThreadState_GET()->interp; |
| 3347 | + _Py_IDENTIFIER(copyreg); |
3352 | 3348 |
|
3353 | | - if (!copyreg_str) { |
3354 | | - copyreg_str = PyUnicode_InternFromString("copyreg"); |
3355 | | - if (copyreg_str == NULL) |
3356 | | - return NULL; |
| 3349 | + copyreg_str = _PyUnicode_FromId(&PyId_copyreg); |
| 3350 | + if (copyreg_str == NULL) { |
| 3351 | + return NULL; |
3357 | 3352 | } |
3358 | | - if (!cached_copyreg_module) { |
3359 | | - cached_copyreg_module = PyImport_Import(copyreg_str); |
| 3353 | + /* Try to fetch cached copy of copyreg from sys.modules first in an |
| 3354 | + attempt to avoid the import overhead. Previously this was implemented |
| 3355 | + by storing a reference to the cached module in a static variable, but |
| 3356 | + this broke when multiple embeded interpreters were in use (see issue |
| 3357 | + #17408 and #19088). */ |
| 3358 | + copyreg_module = PyDict_GetItemWithError(interp->modules, copyreg_str); |
| 3359 | + if (copyreg_module != NULL) { |
| 3360 | + Py_INCREF(copyreg_module); |
| 3361 | + return copyreg_module; |
| 3362 | + } |
| 3363 | + if (PyErr_Occurred()) { |
| 3364 | + return NULL; |
3360 | 3365 | } |
3361 | | - |
3362 | | - Py_XINCREF(cached_copyreg_module); |
3363 | | - return cached_copyreg_module; |
| 3366 | + return PyImport_Import(copyreg_str); |
3364 | 3367 | } |
3365 | 3368 |
|
3366 | 3369 | static PyObject * |
|
0 commit comments