https://github.com/python/cpython/commit/c1891e225e9b95e8484acfb2645e7ef1cf1dff7d
commit: c1891e225e9b95e8484acfb2645e7ef1cf1dff7d
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: ericsnowcurrently <[email protected]>
date: 2024-07-08T21:34:58Z
summary:

[3.13] gh-121110: Fix Extension Module Tests Under Py_TRACE_REFS Builds 
(gh-121517)

The change in gh-118157 (b2cd54a) should have also updated 
clear_singlephase_extension() but didn't.  We fix that here.  Note that 
clear_singlephase_extension() (AKA _PyImport_ClearExtension()) is only used in 
tests.

(cherry picked from commit 15d48aea02099ffc5bdc5511cc53ced460cb31b9, AKA 
gh-121503)

Co-authored-by: Eric Snow <[email protected]>

files:
M Lib/test/test_import/__init__.py
M Python/import.c

diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py
index 99324838355056..f9e8558d1a71c8 100644
--- a/Lib/test/test_import/__init__.py
+++ b/Lib/test/test_import/__init__.py
@@ -3053,13 +3053,6 @@ def 
test_basic_multiple_interpreters_deleted_no_reset(self):
     def test_basic_multiple_interpreters_reset_each(self):
         # resetting between each interpreter
 
-        if Py_TRACE_REFS:
-            # It's a Py_TRACE_REFS build.
-            # This test breaks interpreter isolation a little,
-            # which causes problems on Py_TRACE_REF builds.
-            # See gh-121110.
-            raise unittest.SkipTest('crashes on Py_TRACE_REFS builds')
-
         # At this point:
         #  * alive in 0 interpreters
         #  * module def may or may not be loaded already
diff --git a/Python/import.c b/Python/import.c
index 98ecaed36f0cdc..88f6a7ab57a20c 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1532,6 +1532,35 @@ switch_to_main_interpreter(PyThreadState *tstate)
     return main_tstate;
 }
 
+static void
+switch_back_from_main_interpreter(PyThreadState *tstate,
+                                  PyThreadState *main_tstate,
+                                  PyObject *tempobj)
+{
+    assert(main_tstate == PyThreadState_GET());
+    assert(_Py_IsMainInterpreter(main_tstate->interp));
+    assert(tstate->interp != main_tstate->interp);
+
+    /* Handle any exceptions, which we cannot propagate directly
+     * to the subinterpreter. */
+    if (PyErr_Occurred()) {
+        if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
+            /* We trust it will be caught again soon. */
+            PyErr_Clear();
+        }
+        else {
+            /* Printing the exception should be sufficient. */
+            PyErr_PrintEx(0);
+        }
+    }
+
+    Py_XDECREF(tempobj);
+
+    PyThreadState_Clear(main_tstate);
+    (void)PyThreadState_Swap(tstate);
+    PyThreadState_Delete(main_tstate);
+}
+
 static PyObject *
 get_core_module_dict(PyInterpreterState *interp,
                      PyObject *name, PyObject *path)
@@ -2027,27 +2056,10 @@ import_run_extension(PyThreadState *tstate, 
PyModInitFunction p0,
     /* Switch back to the subinterpreter. */
     if (switched) {
         assert(main_tstate != tstate);
-
-        /* Handle any exceptions, which we cannot propagate directly
-         * to the subinterpreter. */
-        if (PyErr_Occurred()) {
-            if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
-                /* We trust it will be caught again soon. */
-                PyErr_Clear();
-            }
-            else {
-                /* Printing the exception should be sufficient. */
-                PyErr_PrintEx(0);
-            }
-        }
-
+        switch_back_from_main_interpreter(tstate, main_tstate, mod);
         /* Any module we got from the init function will have to be
          * reloaded in the subinterpreter. */
-        Py_CLEAR(mod);
-
-        PyThreadState_Clear(main_tstate);
-        (void)PyThreadState_Swap(tstate);
-        PyThreadState_Delete(main_tstate);
+        mod = NULL;
     }
 
     /*****************************************************************/
@@ -2141,9 +2153,21 @@ clear_singlephase_extension(PyInterpreterState *interp,
         }
     }
 
+    /* We must use the main interpreter to clean up the cache.
+     * See the note in import_run_extension(). */
+    PyThreadState *tstate = PyThreadState_GET();
+    PyThreadState *main_tstate = switch_to_main_interpreter(tstate);
+    if (main_tstate == NULL) {
+        return -1;
+    }
+
     /* Clear the cached module def. */
     _extensions_cache_delete(path, name);
 
+    if (main_tstate != tstate) {
+        switch_back_from_main_interpreter(tstate, main_tstate, NULL);
+    }
+
     return 0;
 }
 

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to