diff --git a/Lib/concurrent/interpreters/_queues.py b/Lib/concurrent/interpreters/_queues.py index ee159d7de63827..cb60be18b39e86 100644 --- a/Lib/concurrent/interpreters/_queues.py +++ b/Lib/concurrent/interpreters/_queues.py @@ -11,7 +11,7 @@ QueueError, QueueNotFoundError, ) from ._crossinterp import ( - UNBOUND_ERROR, UNBOUND_REMOVE, + UNBOUND, UNBOUND_ERROR, UNBOUND_REMOVE, ) __all__ = [ @@ -46,9 +46,6 @@ class ItemInterpreterDestroyed(QueueError, _PICKLED = 1 -UNBOUND = _crossinterp.UnboundItem.singleton('queue', __name__) - - def _serialize_unbound(unbound): if unbound is UNBOUND: unbound = _crossinterp.UNBOUND diff --git a/Lib/test/test_concurrent_futures/test_interpreter_pool.py b/Lib/test/test_concurrent_futures/test_interpreter_pool.py index 7241fcc4b1e74d..5c84a42d74fee4 100644 --- a/Lib/test/test_concurrent_futures/test_interpreter_pool.py +++ b/Lib/test/test_concurrent_futures/test_interpreter_pool.py @@ -427,6 +427,8 @@ def run(taskid, ready, blocker): ready.get(timeout=1) # blocking except interpreters.QueueEmpty: pass + except queues.QueueEmpty: + pass else: done += 1 pending -= done diff --git a/Lib/test/test_interpreters/test_queues.py b/Lib/test/test_interpreters/test_queues.py index 77334aea3836b9..c5e78235c855df 100644 --- a/Lib/test/test_interpreters/test_queues.py +++ b/Lib/test/test_interpreters/test_queues.py @@ -8,6 +8,7 @@ # Raise SkipTest if subinterpreters not supported. _queues = import_helper.import_module('_interpqueues') from concurrent import interpreters +from concurrent.futures import InterpreterPoolExecutor from concurrent.interpreters import _queues as queues, _crossinterp from .utils import _run_output, TestBase as _TestBase @@ -93,6 +94,14 @@ def test_bind_release(self): with self.assertRaises(queues.QueueError): _queues.release(qid) + def test_interpreter_pool_executor_after_reload(self): + # Regression test for gh-142414 (KeyError in serialize_unbound). + importlib.reload(queues) + code = "import struct" + with InterpreterPoolExecutor(max_workers=1) as executor: + results = executor.map(exec, [code] * 1) + self.assertEqual(list(results), [None] * 1) + class QueueTests(TestBase): diff --git a/Misc/NEWS.d/next/Library/2025-12-10-15-27-58.gh-issue-142414.zTHgP-.rst b/Misc/NEWS.d/next/Library/2025-12-10-15-27-58.gh-issue-142414.zTHgP-.rst new file mode 100644 index 00000000000000..147c6e4b5dee2c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-10-15-27-58.gh-issue-142414.zTHgP-.rst @@ -0,0 +1 @@ +Fix spurious :exc:`KeyError` when :mod:`concurrent.interpreters` is reloaded after import.