Skip to content

Commit 269005e

Browse files
gh-110300: Fix Refleaks in test_interpreters and test__xxinterpchannels (gh-110318)
1 parent 625ecbe commit 269005e

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed

Lib/test/support/interpreters.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,5 @@ def close(self):
215215
_channels.close(self._id, send=True)
216216

217217

218-
_channels._register_end_types(SendChannel, RecvChannel)
218+
# XXX This is causing leaks (gh-110318):
219+
#_channels._register_end_types(SendChannel, RecvChannel)

Lib/test/test_interpreters.py

+19-7
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ def run():
6868

6969
class TestBase(unittest.TestCase):
7070

71+
def pipe(self):
72+
def ensure_closed(fd):
73+
try:
74+
os.close(fd)
75+
except OSError:
76+
pass
77+
r, w = os.pipe()
78+
self.addCleanup(lambda: ensure_closed(r))
79+
self.addCleanup(lambda: ensure_closed(w))
80+
return r, w
81+
7182
def tearDown(self):
7283
clean_up_interpreters()
7384

@@ -262,7 +273,7 @@ def test_subinterpreter(self):
262273
self.assertFalse(interp.is_running())
263274

264275
def test_finished(self):
265-
r, w = os.pipe()
276+
r, w = self.pipe()
266277
interp = interpreters.create()
267278
interp.run(f"""if True:
268279
import os
@@ -299,8 +310,8 @@ def test_bad_id(self):
299310
interp.is_running()
300311

301312
def test_with_only_background_threads(self):
302-
r_interp, w_interp = os.pipe()
303-
r_thread, w_thread = os.pipe()
313+
r_interp, w_interp = self.pipe()
314+
r_thread, w_thread = self.pipe()
304315

305316
DONE = b'D'
306317
FINISHED = b'F'
@@ -425,8 +436,8 @@ def test_still_running(self):
425436
self.assertTrue(interp.is_running())
426437

427438
def test_subthreads_still_running(self):
428-
r_interp, w_interp = os.pipe()
429-
r_thread, w_thread = os.pipe()
439+
r_interp, w_interp = self.pipe()
440+
r_thread, w_thread = self.pipe()
430441

431442
FINISHED = b'F'
432443

@@ -532,8 +543,8 @@ def test_bytes_for_script(self):
532543
interp.run(b'print("spam")')
533544

534545
def test_with_background_threads_still_running(self):
535-
r_interp, w_interp = os.pipe()
536-
r_thread, w_thread = os.pipe()
546+
r_interp, w_interp = self.pipe()
547+
r_thread, w_thread = self.pipe()
537548

538549
RAN = b'R'
539550
DONE = b'D'
@@ -822,6 +833,7 @@ def test_list_all(self):
822833
after = set(interpreters.list_all_channels())
823834
self.assertEqual(after, created)
824835

836+
@unittest.expectedFailure # See gh-110318:
825837
def test_shareable(self):
826838
rch, sch = interpreters.create_channel()
827839

Modules/_xxinterpchannelsmodule.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -1992,6 +1992,7 @@ _get_current_channel_end_type(int end)
19921992
return NULL;
19931993
}
19941994
}
1995+
Py_DECREF(highlevel);
19951996
if (end == CHANNEL_SEND) {
19961997
cls = state->send_channel_type;
19971998
}
@@ -2012,6 +2013,7 @@ _channel_end_from_xid(_PyCrossInterpreterData *data)
20122013
}
20132014
PyTypeObject *cls = _get_current_channel_end_type(cid->end);
20142015
if (cls == NULL) {
2016+
Py_DECREF(cid);
20152017
return NULL;
20162018
}
20172019
PyObject *obj = PyObject_CallOneArg((PyObject *)cls, (PyObject *)cid);
@@ -2027,7 +2029,9 @@ _channel_end_shared(PyThreadState *tstate, PyObject *obj,
20272029
if (cidobj == NULL) {
20282030
return -1;
20292031
}
2030-
if (_channelid_shared(tstate, cidobj, data) < 0) {
2032+
int res = _channelid_shared(tstate, cidobj, data);
2033+
Py_DECREF(cidobj);
2034+
if (res < 0) {
20312035
return -1;
20322036
}
20332037
data->new_object = _channel_end_from_xid;
@@ -2464,7 +2468,10 @@ channel__channel_id(PyObject *self, PyObject *args, PyObject *kwds)
24642468
return NULL;
24652469
}
24662470
PyTypeObject *cls = state->ChannelIDType;
2467-
assert(get_module_from_owned_type(cls) == self);
2471+
2472+
PyObject *mod = get_module_from_owned_type(cls);
2473+
assert(mod == self);
2474+
Py_DECREF(mod);
24682475

24692476
return _channelid_new(self, cls, args, kwds);
24702477
}

0 commit comments

Comments
 (0)