From 688c38f7578185c563df75d01a5f0b5563308fde Mon Sep 17 00:00:00 2001 From: yihong0618 Date: Mon, 27 Oct 2025 16:22:25 +0800 Subject: [PATCH] fix: can not list_all after _interpchannels.close Signed-off-by: yihong0618 --- Lib/test/test__interpchannels.py | 14 ++++++++++++++ .../2025-10-27-16-17-43.gh-issue-140652.h_hnlb.rst | 1 + Modules/_interpchannelsmodule.c | 9 +++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/C_API/2025-10-27-16-17-43.gh-issue-140652.h_hnlb.rst diff --git a/Lib/test/test__interpchannels.py b/Lib/test/test__interpchannels.py index d7cf77368ef9f2..0db12aba936515 100644 --- a/Lib/test/test__interpchannels.py +++ b/Lib/test/test__interpchannels.py @@ -1208,6 +1208,20 @@ def test_channel_list_interpreters_invalid_args(self): with self.assertRaises(TypeError): _channels.list_interpreters(cid) + def test_channel_close_and_list_all(self): + # gh-140652 + cid1 = _channels.create(REPLACE) + cid2 = _channels.create(REPLACE) + cid3 = _channels.create(REPLACE) + + _channels.close(cid1) + _channels.close(cid2, force=True) + + all_channels = [cid for cid, _, _ in _channels.list_all()] + self.assertNotIn(cid1, all_channels) + self.assertNotIn(cid2, all_channels) + self.assertIn(cid3, all_channels) + class ChannelReleaseTests(TestBase): diff --git a/Misc/NEWS.d/next/C_API/2025-10-27-16-17-43.gh-issue-140652.h_hnlb.rst b/Misc/NEWS.d/next/C_API/2025-10-27-16-17-43.gh-issue-140652.h_hnlb.rst new file mode 100644 index 00000000000000..c51626b1f7d9b2 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2025-10-27-16-17-43.gh-issue-140652.h_hnlb.rst @@ -0,0 +1 @@ +Fix: can not ``list_all`` after ``_interpchannels.close(cid)`` diff --git a/Modules/_interpchannelsmodule.c b/Modules/_interpchannelsmodule.c index ef9cf01ecbec5e..b44a1dfc9c64db 100644 --- a/Modules/_interpchannelsmodule.c +++ b/Modules/_interpchannelsmodule.c @@ -1645,13 +1645,18 @@ _channels_list_all(_channels *channels, int64_t *count) goto done; } _channelref *ref = channels->head; - for (int64_t i=0; ref != NULL; ref = ref->next, i++) { + int64_t i = 0; + for (; ref != NULL; ref = ref->next) { + if (ref->chan == NULL) { + continue; + } ids[i] = (struct channel_id_and_info){ .id = ref->cid, .defaults = ref->chan->defaults, }; + i++; } - *count = channels->numopen; + *count = i; cids = ids; done: