aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/support/interpreters/queues.py
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2024-07-15 13:43:59 -0600
committerGitHub <noreply@github.com>2024-07-15 19:43:59 +0000
commit8b209fd4f8a9bf9603888bda2c44b5cfd4ebf47a (patch)
tree517e2f87dc7a278d390cfd51c91a03a694c6c7f2 /Lib/test/support/interpreters/queues.py
parentfd085a411ed2ccc9bde2338cf50068bc7f213ece (diff)
downloadcpython-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.py60
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):