diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2024-07-15 13:43:59 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-15 19:43:59 +0000 |
commit | 8b209fd4f8a9bf9603888bda2c44b5cfd4ebf47a (patch) | |
tree | 517e2f87dc7a278d390cfd51c91a03a694c6c7f2 /Lib/test/support/interpreters/queues.py | |
parent | fd085a411ed2ccc9bde2338cf50068bc7f213ece (diff) | |
download | cpython-8b209fd4f8a9bf9603888bda2c44b5cfd4ebf47a.tar.gz cpython-8b209fd4f8a9bf9603888bda2c44b5cfd4ebf47a.zip |
gh-76785: Expand How Interpreter Channels Handle Interpreter Finalization (gh-121805)
See 6b98b274b6 for an explanation of the problem and solution. Here I've applied the solution to channels.
Diffstat (limited to 'Lib/test/support/interpreters/queues.py')
-rw-r--r-- | Lib/test/support/interpreters/queues.py | 60 |
1 files changed, 14 insertions, 46 deletions
diff --git a/Lib/test/support/interpreters/queues.py b/Lib/test/support/interpreters/queues.py index 402ceffd1bb..deb8e8613af 100644 --- a/Lib/test/support/interpreters/queues.py +++ b/Lib/test/support/interpreters/queues.py @@ -5,11 +5,15 @@ import queue import time import weakref import _interpqueues as _queues +from . import _crossinterp # aliases: from _interpqueues import ( QueueError, QueueNotFoundError, ) +from ._crossinterp import ( + UNBOUND_ERROR, UNBOUND_REMOVE, +) __all__ = [ 'UNBOUND', 'UNBOUND_ERROR', 'UNBOUND_REMOVE', @@ -34,7 +38,8 @@ class QueueFull(QueueError, queue.Full): """ -class ItemInterpreterDestroyed(QueueError): +class ItemInterpreterDestroyed(QueueError, + _crossinterp.ItemInterpreterDestroyed): """Raised from get() and get_nowait().""" @@ -42,57 +47,20 @@ _SHARED_ONLY = 0 _PICKLED = 1 -class UnboundItem: - """Represents a Queue item no longer bound to an interpreter. - - An item is unbound when the interpreter that added it to the queue - is destroyed. - """ - - __slots__ = () - - def __new__(cls): - return UNBOUND - - def __repr__(self): - return f'interpreters.queues.UNBOUND' - - -UNBOUND = object.__new__(UnboundItem) -UNBOUND_ERROR = object() -UNBOUND_REMOVE = object() +UNBOUND = _crossinterp.UnboundItem.singleton('queue', __name__) -_UNBOUND_CONSTANT_TO_FLAG = { - UNBOUND_REMOVE: 1, - UNBOUND_ERROR: 2, - UNBOUND: 3, -} -_UNBOUND_FLAG_TO_CONSTANT = {v: k - for k, v in _UNBOUND_CONSTANT_TO_FLAG.items()} def _serialize_unbound(unbound): - op = unbound - try: - flag = _UNBOUND_CONSTANT_TO_FLAG[op] - except KeyError: - raise NotImplementedError(f'unsupported unbound replacement op {op!r}') - return flag, + if unbound is UNBOUND: + unbound = _crossinterp.UNBOUND + return _crossinterp.serialize_unbound(unbound) def _resolve_unbound(flag): - try: - op = _UNBOUND_FLAG_TO_CONSTANT[flag] - except KeyError: - raise NotImplementedError(f'unsupported unbound replacement op {flag!r}') - if op is UNBOUND_REMOVE: - # "remove" not possible here - raise NotImplementedError - elif op is UNBOUND_ERROR: - raise ItemInterpreterDestroyed("item's original interpreter destroyed") - elif op is UNBOUND: - return UNBOUND - else: - raise NotImplementedError(repr(op)) + resolved = _crossinterp.resolve_unbound(flag, ItemInterpreterDestroyed) + if resolved is _crossinterp.UNBOUND: + resolved = UNBOUND + return resolved def create(maxsize=0, *, syncobj=False, unbounditems=UNBOUND): |