Use built-ins for all data-structure-type annotations

we_bein_all_matchy
Tyler Goodlet 2022-09-15 16:56:50 -04:00
parent a113e22bb9
commit 10eeda2d2b
14 changed files with 81 additions and 62 deletions

View File

@ -396,7 +396,7 @@ tasks spawned via multiple RPC calls to an actor can modify
# a per process cache # a per process cache
_actor_cache: Dict[str, bool] = {} _actor_cache: dict[str, bool] = {}
def ping_endpoints(endpoints: List[str]): def ping_endpoints(endpoints: List[str]):

View File

@ -9,7 +9,7 @@ is ``tractor``'s channels.
""" """
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from typing import List, Callable from typing import Callable
import itertools import itertools
import math import math
import time import time
@ -71,8 +71,8 @@ async def worker_pool(workers=4):
async def _map( async def _map(
worker_func: Callable[[int], bool], worker_func: Callable[[int], bool],
sequence: List[int] sequence: list[int]
) -> List[bool]: ) -> list[bool]:
# define an async (local) task to collect results from workers # define an async (local) task to collect results from workers
async def send_result(func, value, portal): async def send_result(func, value, portal):

View File

@ -5,7 +5,6 @@ Advanced streaming patterns using bidirectional streams and contexts.
from collections import Counter from collections import Counter
import itertools import itertools
import platform import platform
from typing import Set, Dict, List
import trio import trio
import tractor import tractor
@ -15,7 +14,7 @@ def is_win():
return platform.system() == 'Windows' return platform.system() == 'Windows'
_registry: Dict[str, Set[tractor.ReceiveMsgStream]] = { _registry: dict[str, set[tractor.ReceiveMsgStream]] = {
'even': set(), 'even': set(),
'odd': set(), 'odd': set(),
} }
@ -77,7 +76,7 @@ async def subscribe(
async def consumer( async def consumer(
subs: List[str], subs: list[str],
) -> None: ) -> None:

View File

@ -1,7 +1,7 @@
""" """
Spawning basics Spawning basics
""" """
from typing import Dict, Tuple, Optional from typing import Optional
import pytest import pytest
import trio import trio
@ -14,8 +14,8 @@ data_to_pass_down = {'doggy': 10, 'kitty': 4}
async def spawn( async def spawn(
is_arbiter: bool, is_arbiter: bool,
data: Dict, data: dict,
arb_addr: Tuple[str, int], arb_addr: tuple[str, int],
): ):
namespaces = [__name__] namespaces = [__name__]

View File

@ -6,7 +6,7 @@ from contextlib import asynccontextmanager
from functools import partial from functools import partial
from itertools import cycle from itertools import cycle
import time import time
from typing import Optional, List, Tuple from typing import Optional
import pytest import pytest
import trio import trio
@ -62,8 +62,8 @@ async def ensure_sequence(
@asynccontextmanager @asynccontextmanager
async def open_sequence_streamer( async def open_sequence_streamer(
sequence: List[int], sequence: list[int],
arb_addr: Tuple[str, int], arb_addr: tuple[str, int],
start_method: str, start_method: str,
) -> tractor.MsgStream: ) -> tractor.MsgStream:

View File

@ -25,7 +25,6 @@ import signal
from functools import partial from functools import partial
from contextlib import asynccontextmanager as acm from contextlib import asynccontextmanager as acm
from typing import ( from typing import (
Tuple,
Optional, Optional,
Callable, Callable,
AsyncIterator, AsyncIterator,
@ -74,7 +73,7 @@ class Lock:
local_task_in_debug: Optional[str] = None local_task_in_debug: Optional[str] = None
# actor tree-wide actor uid that supposedly has the tty lock # actor tree-wide actor uid that supposedly has the tty lock
global_actor_in_debug: Optional[Tuple[str, str]] = None global_actor_in_debug: Optional[tuple[str, str]] = None
local_pdb_complete: Optional[trio.Event] = None local_pdb_complete: Optional[trio.Event] = None
no_remote_has_tty: Optional[trio.Event] = None no_remote_has_tty: Optional[trio.Event] = None
@ -172,7 +171,7 @@ class MultiActorPdb(pdbpp.Pdb):
@acm @acm
async def _acquire_debug_lock_from_root_task( async def _acquire_debug_lock_from_root_task(
uid: Tuple[str, str] uid: tuple[str, str]
) -> AsyncIterator[trio.StrictFIFOLock]: ) -> AsyncIterator[trio.StrictFIFOLock]:
''' '''
@ -252,7 +251,7 @@ async def _acquire_debug_lock_from_root_task(
async def lock_tty_for_child( async def lock_tty_for_child(
ctx: tractor.Context, ctx: tractor.Context,
subactor_uid: Tuple[str, str] subactor_uid: tuple[str, str]
) -> str: ) -> str:
''' '''
@ -302,7 +301,7 @@ async def lock_tty_for_child(
async def wait_for_parent_stdin_hijack( async def wait_for_parent_stdin_hijack(
actor_uid: Tuple[str, str], actor_uid: tuple[str, str],
task_status: TaskStatus[trio.CancelScope] = trio.TASK_STATUS_IGNORED task_status: TaskStatus[trio.CancelScope] = trio.TASK_STATUS_IGNORED
): ):
''' '''
@ -732,7 +731,7 @@ async def _maybe_enter_pm(err):
@acm @acm
async def acquire_debug_lock( async def acquire_debug_lock(
subactor_uid: Tuple[str, str], subactor_uid: tuple[str, str],
) -> AsyncGenerator[None, tuple]: ) -> AsyncGenerator[None, tuple]:
''' '''
Grab root's debug lock on entry, release on exit. Grab root's debug lock on entry, release on exit.

View File

@ -18,7 +18,11 @@
Actor discovery API. Actor discovery API.
""" """
from typing import Tuple, Optional, Union, AsyncGenerator from typing import (
Optional,
Union,
AsyncGenerator,
)
from contextlib import asynccontextmanager as acm from contextlib import asynccontextmanager as acm
from ._ipc import _connect_chan, Channel from ._ipc import _connect_chan, Channel
@ -104,7 +108,7 @@ async def query_actor(
@acm @acm
async def find_actor( async def find_actor(
name: str, name: str,
arbiter_sockaddr: Tuple[str, int] = None arbiter_sockaddr: tuple[str, int] = None
) -> AsyncGenerator[Optional[Portal], None]: ) -> AsyncGenerator[Optional[Portal], None]:
''' '''
@ -130,7 +134,7 @@ async def find_actor(
@acm @acm
async def wait_for_actor( async def wait_for_actor(
name: str, name: str,
arbiter_sockaddr: Tuple[str, int] = None arbiter_sockaddr: tuple[str, int] = None
) -> AsyncGenerator[Portal, None]: ) -> AsyncGenerator[Portal, None]:
"""Wait on an actor to register with the arbiter. """Wait on an actor to register with the arbiter.

View File

@ -19,7 +19,7 @@ Sub-process entry points.
""" """
from functools import partial from functools import partial
from typing import Tuple, Any from typing import Any
import trio # type: ignore import trio # type: ignore
@ -35,10 +35,10 @@ log = get_logger(__name__)
def _mp_main( def _mp_main(
actor: 'Actor', # type: ignore actor: 'Actor', # type: ignore
accept_addr: Tuple[str, int], accept_addr: tuple[str, int],
forkserver_info: Tuple[Any, Any, Any, Any, Any], forkserver_info: tuple[Any, Any, Any, Any, Any],
start_method: str, start_method: str,
parent_addr: Tuple[str, int] = None, parent_addr: tuple[str, int] = None,
infect_asyncio: bool = False, infect_asyncio: bool = False,
) -> None: ) -> None:
@ -85,7 +85,7 @@ def _trio_main(
actor: Actor, # type: ignore actor: Actor, # type: ignore
*, *,
parent_addr: Tuple[str, int] = None, parent_addr: tuple[str, int] = None,
infect_asyncio: bool = False, infect_asyncio: bool = False,
) -> None: ) -> None:

View File

@ -18,7 +18,11 @@
Our classy exception set. Our classy exception set.
""" """
from typing import Dict, Any, Optional, Type from typing import (
Any,
Optional,
Type,
)
import importlib import importlib
import builtins import builtins
import traceback import traceback
@ -95,7 +99,7 @@ def pack_error(
exc: BaseException, exc: BaseException,
tb=None, tb=None,
) -> Dict[str, Any]: ) -> dict[str, Any]:
"""Create an "error message" for tranmission over """Create an "error message" for tranmission over
a channel (aka the wire). a channel (aka the wire).
""" """
@ -114,7 +118,7 @@ def pack_error(
def unpack_error( def unpack_error(
msg: Dict[str, Any], msg: dict[str, Any],
chan=None, chan=None,
err_type=RemoteActorError err_type=RemoteActorError

View File

@ -18,7 +18,10 @@
Per process state Per process state
""" """
from typing import Optional, Dict, Any from typing import (
Optional,
Any,
)
from collections.abc import Mapping from collections.abc import Mapping
import trio import trio
@ -27,7 +30,7 @@ from ._exceptions import NoRuntime
_current_actor: Optional['Actor'] = None # type: ignore # noqa _current_actor: Optional['Actor'] = None # type: ignore # noqa
_runtime_vars: Dict[str, Any] = { _runtime_vars: dict[str, Any] = {
'_debug_mode': False, '_debug_mode': False,
'_is_root': False, '_is_root': False,
'_root_mailbox': (None, None) '_root_mailbox': (None, None)

View File

@ -23,8 +23,10 @@ import inspect
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from dataclasses import dataclass from dataclasses import dataclass
from typing import ( from typing import (
Any, Optional, Callable, Any,
AsyncGenerator, Dict, Optional,
Callable,
AsyncGenerator,
AsyncIterator AsyncIterator
) )
@ -393,7 +395,7 @@ class Context:
async def _maybe_raise_from_remote_msg( async def _maybe_raise_from_remote_msg(
self, self,
msg: Dict[str, Any], msg: dict[str, Any],
) -> None: ) -> None:
''' '''

View File

@ -20,7 +20,10 @@
""" """
from functools import partial from functools import partial
import inspect import inspect
from typing import Tuple, List, Dict, Optional, TYPE_CHECKING from typing import (
Optional,
TYPE_CHECKING,
)
import typing import typing
import warnings import warnings
@ -43,7 +46,7 @@ if TYPE_CHECKING:
log = get_logger(__name__) log = get_logger(__name__)
_default_bind_addr: Tuple[str, int] = ('127.0.0.1', 0) _default_bind_addr: tuple[str, int] = ('127.0.0.1', 0)
class ActorNursery: class ActorNursery:
@ -79,15 +82,15 @@ class ActorNursery:
actor: Actor, actor: Actor,
ria_nursery: trio.Nursery, ria_nursery: trio.Nursery,
da_nursery: trio.Nursery, da_nursery: trio.Nursery,
errors: Dict[Tuple[str, str], Exception], errors: dict[tuple[str, str], Exception],
) -> None: ) -> None:
# self.supervisor = supervisor # TODO # self.supervisor = supervisor # TODO
self._actor: Actor = actor self._actor: Actor = actor
self._ria_nursery = ria_nursery self._ria_nursery = ria_nursery
self._da_nursery = da_nursery self._da_nursery = da_nursery
self._children: Dict[ self._children: dict[
Tuple[str, str], tuple[str, str],
Tuple[Actor, mp.Process, Optional[Portal]] tuple[Actor, mp.Process, Optional[Portal]]
] = {} ] = {}
# portals spawned with ``run_in_actor()`` are # portals spawned with ``run_in_actor()`` are
# cancelled when their "main" result arrives # cancelled when their "main" result arrives
@ -102,9 +105,9 @@ class ActorNursery:
self, self,
name: str, name: str,
*, *,
bind_addr: Tuple[str, int] = _default_bind_addr, bind_addr: tuple[str, int] = _default_bind_addr,
rpc_module_paths: List[str] = None, rpc_module_paths: list[str] = None,
enable_modules: List[str] = None, enable_modules: list[str] = None,
loglevel: str = None, # set log level per subactor loglevel: str = None, # set log level per subactor
nursery: trio.Nursery = None, nursery: trio.Nursery = None,
debug_mode: Optional[bool] = None, debug_mode: Optional[bool] = None,
@ -173,9 +176,9 @@ class ActorNursery:
*, *,
name: Optional[str] = None, name: Optional[str] = None,
bind_addr: Tuple[str, int] = _default_bind_addr, bind_addr: tuple[str, int] = _default_bind_addr,
rpc_module_paths: Optional[List[str]] = None, rpc_module_paths: Optional[list[str]] = None,
enable_modules: List[str] = None, enable_modules: list[str] = None,
loglevel: str = None, # set log level per subactor loglevel: str = None, # set log level per subactor
infect_asyncio: bool = False, infect_asyncio: bool = False,
@ -293,7 +296,7 @@ async def _open_and_supervise_one_cancels_all_nursery(
) -> typing.AsyncGenerator[ActorNursery, None]: ) -> typing.AsyncGenerator[ActorNursery, None]:
# the collection of errors retreived from spawned sub-actors # the collection of errors retreived from spawned sub-actors
errors: Dict[Tuple[str, str], Exception] = {} errors: dict[tuple[str, str], Exception] = {}
# This is the outermost level "deamon actor" nursery. It is awaited # This is the outermost level "deamon actor" nursery. It is awaited
# **after** the below inner "run in actor nursery". This allows for # **after** the below inner "run in actor nursery". This allows for

View File

@ -26,7 +26,10 @@ support provided by ``tractor.Context.open_stream()`` and friends.
from __future__ import annotations from __future__ import annotations
import inspect import inspect
import typing import typing
from typing import Dict, Any, Set, Callable, List, Tuple from typing import (
Any,
Callable,
)
from functools import partial from functools import partial
from async_generator import aclosing from async_generator import aclosing
@ -44,7 +47,7 @@ log = get_logger('messaging')
async def fan_out_to_ctxs( async def fan_out_to_ctxs(
pub_async_gen_func: typing.Callable, # it's an async gen ... gd mypy pub_async_gen_func: typing.Callable, # it's an async gen ... gd mypy
topics2ctxs: Dict[str, list], topics2ctxs: dict[str, list],
packetizer: typing.Callable = None, packetizer: typing.Callable = None,
) -> None: ) -> None:
''' '''
@ -61,7 +64,7 @@ async def fan_out_to_ctxs(
async for published in pub_gen: async for published in pub_gen:
ctx_payloads: List[Tuple[Context, Any]] = [] ctx_payloads: list[tuple[Context, Any]] = []
for topic, data in published.items(): for topic, data in published.items():
log.debug(f"publishing {topic, data}") log.debug(f"publishing {topic, data}")
@ -103,8 +106,8 @@ async def fan_out_to_ctxs(
def modify_subs( def modify_subs(
topics2ctxs: Dict[str, List[Context]], topics2ctxs: dict[str, list[Context]],
topics: Set[str], topics: set[str],
ctx: Context, ctx: Context,
) -> None: ) -> None:
@ -136,20 +139,20 @@ def modify_subs(
topics2ctxs.pop(topic) topics2ctxs.pop(topic)
_pub_state: Dict[str, dict] = {} _pub_state: dict[str, dict] = {}
_pubtask2lock: Dict[str, trio.StrictFIFOLock] = {} _pubtask2lock: dict[str, trio.StrictFIFOLock] = {}
def pub( def pub(
wrapped: typing.Callable = None, wrapped: typing.Callable = None,
*, *,
tasks: Set[str] = set(), tasks: set[str] = set(),
): ):
"""Publisher async generator decorator. """Publisher async generator decorator.
A publisher can be called multiple times from different actors but A publisher can be called multiple times from different actors but
will only spawn a finite set of internal tasks to stream values to will only spawn a finite set of internal tasks to stream values to
each caller. The ``tasks: Set[str]`` argument to the decorator each caller. The ``tasks: set[str]`` argument to the decorator
specifies the names of the mutex set of publisher tasks. When the specifies the names of the mutex set of publisher tasks. When the
publisher function is called, an argument ``task_name`` must be publisher function is called, an argument ``task_name`` must be
passed to specify which task (of the set named in ``tasks``) should passed to specify which task (of the set named in ``tasks``) should
@ -158,9 +161,9 @@ def pub(
necessary. necessary.
Values yielded from the decorated async generator must be Values yielded from the decorated async generator must be
``Dict[str, Dict[str, Any]]`` where the fist level key is the topic ``dict[str, dict[str, Any]]`` where the fist level key is the topic
string and determines which subscription the packet will be string and determines which subscription the packet will be
delivered to and the value is a packet ``Dict[str, Any]`` by default delivered to and the value is a packet ``dict[str, Any]`` by default
of the form: of the form:
.. ::python .. ::python
@ -186,7 +189,7 @@ def pub(
The publisher must be called passing in the following arguments: The publisher must be called passing in the following arguments:
- ``topics: Set[str]`` the topic sequence or "subscriptions" - ``topics: set[str]`` the topic sequence or "subscriptions"
- ``task_name: str`` the task to use (if ``tasks`` was passed) - ``task_name: str`` the task to use (if ``tasks`` was passed)
- ``ctx: Context`` the tractor context (only needed if calling the - ``ctx: Context`` the tractor context (only needed if calling the
pub func without a nursery, otherwise this is provided implicitly) pub func without a nursery, otherwise this is provided implicitly)
@ -231,7 +234,7 @@ def pub(
if wrapped is None: if wrapped is None:
return partial(pub, tasks=tasks) return partial(pub, tasks=tasks)
task2lock: Dict[str, trio.StrictFIFOLock] = {} task2lock: dict[str, trio.StrictFIFOLock] = {}
for name in tasks: for name in tasks:
task2lock[name] = trio.StrictFIFOLock() task2lock[name] = trio.StrictFIFOLock()
@ -243,7 +246,7 @@ def pub(
# `wrapt` docs # `wrapt` docs
async def _execute( async def _execute(
ctx: Context, ctx: Context,
topics: Set[str], topics: set[str],
*args, *args,
# *, # *,
task_name: str = None, # default: only one task allocated task_name: str = None, # default: only one task allocated

View File

@ -102,6 +102,8 @@ async def gather_contexts(
# deliver control once all managers have started up # deliver control once all managers have started up
await all_entered.wait() await all_entered.wait()
# NOTE: order *should* be preserved in the output values
# since ``dict``s are now implicitly ordered.
yield tuple(unwrapped.values()) yield tuple(unwrapped.values())
# we don't need a try/finally since cancellation will be triggered # we don't need a try/finally since cancellation will be triggered