https://github.com/python/cpython/commit/b383aa6e1a8ea53fdeed88c71fbc34d8b2d1fde9
commit: b383aa6e1a8ea53fdeed88c71fbc34d8b2d1fde9
branch: main
author: Steve Stagg <[email protected]>
committer: sobolevn <[email protected]>
date: 2026-06-30T13:57:28+03:00
summary:

gh-152635: Raise MemoryError when the lock allocation fails in 
`_interpchannels.create()` (#152642)

Previously, an allocation failure when creating
the lock for a channel in `_interpchannels` would trigger an assert.
Caused by `handle_channel_error` being passed an error code of -1
which is only allowed if an exception has been set.
(in this case, no exception was set)

`channelsmod_create` now forwards the error code from `channel_create`
which `handle_channel_error` already handled.

Co-authored-by: sobolevn <[email protected]>

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-23-29-14.gh-issue-152635.O21J0O.rst
M Modules/_interpchannelsmodule.c

diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-23-29-14.gh-issue-152635.O21J0O.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-23-29-14.gh-issue-152635.O21J0O.rst
new file mode 100644
index 00000000000000..dadb25fc7c4477
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-23-29-14.gh-issue-152635.O21J0O.rst
@@ -0,0 +1,2 @@
+Fix a crash caused when running out of memory creating a
+:mod:`!_interpchannels` channel. Now a :exc:`MemoryError` is correctly raised.
diff --git a/Modules/_interpchannelsmodule.c b/Modules/_interpchannelsmodule.c
index 05957081079d4a..358d51cf13f1af 100644
--- a/Modules/_interpchannelsmodule.c
+++ b/Modules/_interpchannelsmodule.c
@@ -354,7 +354,7 @@ clear_module_state(module_state *state)
 #define ERR_CHANNEL_INTERP_CLOSED -4
 #define ERR_CHANNEL_EMPTY -5
 #define ERR_CHANNEL_NOT_EMPTY -6
-#define ERR_CHANNEL_MUTEX_INIT -7
+#define ERR_CHANNEL_MUTEX_INIT -7  // currently unused
 #define ERR_CHANNELS_MUTEX_INIT -8
 #define ERR_NO_NEXT_CHANNEL_ID -9
 #define ERR_CHANNEL_CLOSED_WAITING -10
@@ -427,10 +427,6 @@ handle_channel_error(int err, PyObject *mod, int64_t cid)
                      "if not empty (try force=True)",
                      cid);
     }
-    else if (err == ERR_CHANNEL_MUTEX_INIT) {
-        PyErr_SetString(state->ChannelError,
-                        "can't initialize mutex for new channel");
-    }
     else if (err == ERR_CHANNELS_MUTEX_INIT) {
         PyErr_SetString(state->ChannelError,
                         "can't initialize mutex for channel management");
@@ -1744,7 +1740,8 @@ channel_create(_channels *channels, struct 
_channeldefaults defaults)
 {
     PyThread_type_lock mutex = PyThread_allocate_lock();
     if (mutex == NULL) {
-        return ERR_CHANNEL_MUTEX_INIT;
+        PyErr_NoMemory();
+        return -1;
     }
     _channel_state *chan = _channel_new(mutex, defaults);
     if (chan == NULL) {
@@ -2938,7 +2935,7 @@ channelsmod_create(PyObject *self, PyObject *args, 
PyObject *kwds)
 
     int64_t cid = channel_create(&_globals.channels, defaults);
     if (cid < 0) {
-        (void)handle_channel_error(-1, self, cid);
+        (void)handle_channel_error(cid, self, cid);
         return NULL;
     }
     module_state *state = get_module_state(self);

_______________________________________________
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