https://github.com/python/cpython/commit/d06113c7a7cac76a28847702685e601b79f71bf8
commit: d06113c7a7cac76a28847702685e601b79f71bf8
branch: main
author: Peter Bierma <[email protected]>
committer: ZeroIntensity <[email protected]>
date: 2025-09-19T10:41:09-04:00
summary:

gh-112729: Correctly fail when the process is out of memory during interpreter 
creation (GH-139164)

files:
A Misc/NEWS.d/next/Library/2025-09-19-09-36-42.gh-issue-112729.mmty0_.rst
M Lib/test/test_interpreters/test_stress.py
M Python/pylifecycle.c

diff --git a/Lib/test/test_interpreters/test_stress.py 
b/Lib/test/test_interpreters/test_stress.py
index e25e67a0d4f445..6b40a536bd3c31 100644
--- a/Lib/test/test_interpreters/test_stress.py
+++ b/Lib/test/test_interpreters/test_stress.py
@@ -7,6 +7,7 @@
 # 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 @@ def run():
             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
index 00000000000000..950853a696f315
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-09-19-09-36-42.gh-issue-112729.mmty0_.rst
@@ -0,0 +1,2 @@
+Fix crash when calling :func:`concurrent.interpreters.create` when the
+process is out of memory.
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 37231889740609..37af58a68d7883 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -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 @@ new_interpreter(PyThreadState **tstate_p,
     *tstate_p = NULL;
     if (tstate != NULL) {
         Py_EndInterpreter(tstate);
-    } else {
+    } else if (interp != NULL) {
         PyInterpreterState_Delete(interp);
     }
     if (save_tstate != NULL) {

_______________________________________________
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