diff --git a/src/asynkit/compat.py b/src/asynkit/compat.py index 385d211..b487c3d 100644 --- a/src/asynkit/compat.py +++ b/src/asynkit/compat.py @@ -4,6 +4,7 @@ from asyncio import AbstractEventLoop, Handle, events from contextvars import Context from typing import TYPE_CHECKING, Any, Callable, Coroutine, Optional, TypeVar +from weakref import ReferenceType """Compatibility routines for earlier asyncio versions""" @@ -13,10 +14,16 @@ T = TypeVar("T") +# The following is needed for mypy to work with Python 3.8 +# which doesn't allow subscripting many types if TYPE_CHECKING: _TaskAny = asyncio.Task[Any] + FutureBool = asyncio.Future[bool] + ReferenceTypeTaskAny = ReferenceType[_TaskAny] else: _TaskAny = asyncio.Task + FutureBool = asyncio.Future + ReferenceTypeTaskAny = ReferenceType # create_task() got the name argument in 3.8 diff --git a/src/asynkit/experimental/priority.py b/src/asynkit/experimental/priority.py index bb2d5bc..6a94ef1 100644 --- a/src/asynkit/experimental/priority.py +++ b/src/asynkit/experimental/priority.py @@ -25,7 +25,7 @@ from typing_extensions import Literal -from asynkit.compat import LockHelper +from asynkit.compat import FutureBool, LockHelper, ReferenceTypeTaskAny from asynkit.loop.default import task_from_handle from asynkit.loop.schedulingloop import AbstractSchedulingLoop from asynkit.loop.types import TaskAny @@ -105,17 +105,13 @@ class PriorityLock(Lock, BasePriorityObject, LockHelper): of all waiting Tasks. """ - _waiters: Optional[ - PriorityQueue[ - float, Tuple[asyncio.Future[bool], weakref.ReferenceType[TaskAny]] - ] - ] + _waiters: Optional[PriorityQueue[float, Tuple[FutureBool, ReferenceTypeTaskAny]]] def __init__(self) -> None: # we use weakrefs to avoid reference cycles. Tasks _own_ locks, # but locks don't own tasks. These are _backrefs_. super().__init__() - self._owning: Optional[weakref.ReferenceType[TaskAny]] = None + self._owning: Optional[ReferenceTypeTaskAny] = None async def acquire(self) -> Literal[True]: """Acquire a lock. @@ -232,7 +228,7 @@ def propagate_priority(self, from_obj: Any) -> None: else: def key( - entry: Tuple[asyncio.Future[bool], weakref.ReferenceType[TaskAny]], + entry: Tuple[FutureBool, ReferenceTypeTaskAny], ) -> bool: fut, _ = entry return fut is from_obj @@ -249,7 +245,7 @@ class PriorityCondition(asyncio.Condition, LockHelper): def __init__(self, lock: Optional[asyncio.Lock] = None) -> None: lock = lock or self.LockType() super().__init__(lock=lock) - self._waiters: PriorityQueue[float, asyncio.Future[bool]] = PriorityQueue() + self._waiters: PriorityQueue[float, FutureBool] = PriorityQueue() async def wait(self) -> Literal[True]: if not self.locked(): # pragma: no cover diff --git a/tests/experimental/test_priority.py b/tests/experimental/test_priority.py index ef5dc89..a2d02cd 100644 --- a/tests/experimental/test_priority.py +++ b/tests/experimental/test_priority.py @@ -5,10 +5,10 @@ import pytest from asynkit.experimental.priority import ( + DefaultPriorityEventLoop, PosPriorityQueue, PriorityCondition, PriorityLock, - DefaultPriorityEventLoop, PriorityTask, )