]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-112729: Correctly fail when the process is out of memory during interpreter creati...
authorPeter Bierma <zintensitydev@gmail.com>
Fri, 19 Sep 2025 14:41:09 +0000 (10:41 -0400)
committerGitHub <noreply@github.com>
Fri, 19 Sep 2025 14:41:09 +0000 (10:41 -0400)
Lib/test/test_interpreters/test_stress.py
Misc/NEWS.d/next/Library/2025-09-19-09-36-42.gh-issue-112729.mmty0_.rst [new file with mode: 0644]
Python/pylifecycle.c

index e25e67a0d4f4453ee01f8c1c4a0b1e081173be69..6b40a536bd3c31987e2d59e3ae812e976a77cabb 100644 (file)
@@ -7,6 +7,7 @@ from test.support import threading_helper
 # Raise SkipTest if subinterpreters not supported.
 import_helper.import_module('_interpreters')
 from concurrent import interpreters
+from concurrent.interpreters import InterpreterError
 from .utils import TestBase
 
 
@@ -74,6 +75,14 @@ class StressTests(TestBase):
             start.set()
         support.gc_collect()
 
+    def test_create_interpreter_no_memory(self):
+        import _interpreters
+        _testcapi = import_helper.import_module("_testcapi")
+
+        with self.assertRaises(InterpreterError):
+            _testcapi.set_nomemory(0, 1)
+            _interpreters.create()
+
 
 if __name__ == '__main__':
     # Test needs to be a package, so we can do relative imports.
diff --git a/Misc/NEWS.d/next/Library/2025-09-19-09-36-42.gh-issue-112729.mmty0_.rst b/Misc/NEWS.d/next/Library/2025-09-19-09-36-42.gh-issue-112729.mmty0_.rst
new file mode 100644 (file)
index 0000000..950853a
--- /dev/null
@@ -0,0 +1,2 @@
+Fix crash when calling :func:`concurrent.interpreters.create` when the
+process is out of memory.
index 372318897406097c4ec1c585b8aea9d3ab79da48..37af58a68d7883f5797894cc0598f1680c65c046 100644 (file)
@@ -2411,18 +2411,17 @@ new_interpreter(PyThreadState **tstate_p,
        interpreters: disable PyGILState_Check(). */
     runtime->gilstate.check_enabled = 0;
 
-    PyInterpreterState *interp = PyInterpreterState_New();
+    // XXX Might new_interpreter() have been called without the GIL held?
+    PyThreadState *save_tstate = _PyThreadState_GET();
+    PyThreadState *tstate = NULL;
+    PyInterpreterState *interp;
+    status = _PyInterpreterState_New(save_tstate, &interp);
     if (interp == NULL) {
-        *tstate_p = NULL;
-        return _PyStatus_OK();
+        goto error;
     }
     _PyInterpreterState_SetWhence(interp, whence);
     interp->_ready = 1;
 
-    // XXX Might new_interpreter() have been called without the GIL held?
-    PyThreadState *save_tstate = _PyThreadState_GET();
-    PyThreadState *tstate = NULL;
-
     /* From this point until the init_interp_create_gil() call,
        we must not do anything that requires that the GIL be held
        (or otherwise exist).  That applies whether or not the new
@@ -2498,7 +2497,7 @@ error:
     *tstate_p = NULL;
     if (tstate != NULL) {
         Py_EndInterpreter(tstate);
-    } else {
+    } else if (interp != NULL) {
         PyInterpreterState_Delete(interp);
     }
     if (save_tstate != NULL) {