From f96657f4d8fcfe825d6a6639632e4c2b547c930e Mon Sep 17 00:00:00 2001 From: William Barnhart Date: Fri, 2 Dec 2022 12:13:50 -0500 Subject: [PATCH] Bring back changes to services.py from 0.3.1 just fix import logic --- mode/services.py | 58 ++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/mode/services.py b/mode/services.py index ddd13579..3e364244 100644 --- a/mode/services.py +++ b/mode/services.py @@ -8,13 +8,14 @@ from types import TracebackType from typing import ( Any, + AsyncContextManager, AsyncIterator, Awaitable, Callable, ClassVar, ContextManager, + Coroutine, Dict, - Generator, Iterable, List, Mapping, @@ -40,26 +41,17 @@ from .utils.tracebacks import format_task_stack from .utils.trees import Node from .utils.types.trees import NodeT -from .utils.typing import AsyncContextManager -__all__ = [ - "ServiceBase", - "Service", - "Diag", - "task", - "timer", -] +__all__ = ["ServiceBase", "Service", "Diag", "task", "timer", "crontab"] ClockArg = Callable[[], float] #: Future type: Different types of awaitables. -FutureT = Union[asyncio.Future, Generator[Any, None, Any], Awaitable] +FutureT = Union[asyncio.Future, Coroutine[Any, None, Any], Awaitable] #: Argument type for ``Service.wait(*events)`` #: Wait can take any number of futures or events to wait for. -WaitArgT = Union[FutureT, asyncio.Event, Event] - -EVENT_TYPES = (asyncio.Event, Event) +WaitArgT = Union[FutureT, Event] class WaitResults(NamedTuple): @@ -96,10 +88,10 @@ class ServiceBase(ServiceT): # the None to logger. logger: logging.Logger = cast(logging.Logger, None) - def __init_subclass__(self) -> None: - if self.abstract: - self.abstract = False - self._init_subclass_logger() + def __init_subclass__(cls) -> None: + if cls.abstract: + cls.abstract = False + cls._init_subclass_logger() @classmethod def _init_subclass_logger(cls) -> None: @@ -146,11 +138,11 @@ def _repr_name(self) -> str: @property def loop(self) -> asyncio.AbstractEventLoop: if self._loop is None: - self._loop = asyncio.get_event_loop() + self._loop = asyncio.get_event_loop_policy().get_event_loop() return self._loop @loop.setter - def loop(self, loop: Optional[asyncio.AbstractEventLoop]) -> None: + def loop(self, loop: asyncio.AbstractEventLoop) -> None: self._loop = loop @@ -231,7 +223,7 @@ class ServiceCallbacks: When calling ``await service.start()`` this happens: - .. sourcecode:: text + .. code-block:: text +--------------------+ | INIT (not started) | @@ -255,7 +247,7 @@ class ServiceCallbacks: When stopping and ``wait_for_shutdown`` is unset, this happens: - .. sourcecode:: text + .. code-block:: text .-----------------------. / await service.stop() | @@ -272,7 +264,7 @@ class ServiceCallbacks: When stopping and ``wait_for_shutdown`` is set, the stop operation will wait for something to set the shutdown flag ``self.set_shutdown()``: - .. sourcecode:: text + .. code-block:: text .-----------------------. / await service.stop() | @@ -293,7 +285,7 @@ class ServiceCallbacks: When restarting the order is as follows (assuming ``wait_for_shutdown`` unset): - .. sourcecode:: text + .. code-block:: text .-------------------------. / await service.restart() | @@ -511,13 +503,13 @@ async def _and_transition(self: ServiceT, *args: Any, **kwargs: Any) -> Any: return _decorate - def __init_subclass__(self) -> None: + def __init_subclass__(cls) -> None: # Every new subclass adds @Service.task decorated methods # to the class-local `_tasks` list. - if self.abstract: - self.abstract = False - self._init_subclass_logger() - self._init_subclass_tasks() + if cls.abstract: + cls.abstract = False + cls._init_subclass_logger() + cls._init_subclass_tasks() @classmethod def _init_subclass_tasks(cls) -> None: @@ -640,7 +632,7 @@ def add_future(self, coro: Awaitable) -> asyncio.Future: """ fut = asyncio.ensure_future(self._execute_task(coro), loop=self.loop) try: - fut.set_name(repr(coro)) # type: ignore + fut.set_name(repr(coro)) except AttributeError: pass fut.__wrapped__ = coro # type: ignore @@ -698,13 +690,11 @@ async def join_services(self, services: Sequence[ServiceT]) -> None: for service in reversed(services): await service.stop() - async def sleep( - self, n: Seconds, *, loop: asyncio.AbstractEventLoop = None - ) -> None: + async def sleep(self, n: Seconds) -> None: """Sleep for ``n`` seconds, or until service stopped.""" try: await asyncio.wait_for( - asyncio.ensure_future(self._stopped.wait(), loop=self.loop), + self._stopped.wait(), timeout=want_seconds(n), ) except asyncio.TimeoutError: @@ -749,7 +739,7 @@ async def wait_first( futures = { coro: asyncio.ensure_future( - (coro.wait() if isinstance(coro, EVENT_TYPES) else coro), + coro if isinstance(coro, Awaitable) else coro.wait(), loop=loop, ) for coro in coros