Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/anyio/abc/_eventloop.py: 76%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from __future__ import annotations
3import math
4import sys
5from abc import ABCMeta, abstractmethod
6from collections.abc import (
7 AsyncIterator,
8 Awaitable,
9 Callable,
10 Coroutine,
11 Iterable,
12 Mapping,
13 Sequence,
14)
15from contextlib import AbstractContextManager
16from os import PathLike
17from signal import Signals
18from socket import AddressFamily, SocketKind, socket
19from typing import (
20 IO,
21 TYPE_CHECKING,
22 Any,
23 TypeAlias,
24 TypeVar,
25 overload,
26)
28if sys.version_info >= (3, 11):
29 from typing import TypeVarTuple, Unpack
30else:
31 from typing_extensions import TypeVarTuple, Unpack
33if TYPE_CHECKING:
34 from _typeshed import FileDescriptorLike
36 from .._core._synchronization import CapacityLimiter, Event, Lock, Semaphore
37 from .._core._tasks import CancelScope
38 from .._core._testing import TaskInfo
39 from ._sockets import (
40 ConnectedUDPSocket,
41 ConnectedUNIXDatagramSocket,
42 IPSockAddrType,
43 SocketListener,
44 SocketStream,
45 UDPSocket,
46 UNIXDatagramSocket,
47 UNIXSocketStream,
48 )
49 from ._subprocesses import Process
50 from ._tasks import TaskGroup
51 from ._testing import TestRunner
53T_Retval = TypeVar("T_Retval")
54T_co = TypeVar("T_co", covariant=True)
55PosArgsT = TypeVarTuple("PosArgsT")
56StrOrBytesPath: TypeAlias = str | bytes | PathLike[str] | PathLike[bytes]
59class AsyncBackend(metaclass=ABCMeta):
60 @classmethod
61 @abstractmethod
62 def run(
63 cls,
64 func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]],
65 args: tuple[Unpack[PosArgsT]],
66 kwargs: dict[str, Any],
67 options: dict[str, Any],
68 ) -> T_Retval:
69 """
70 Run the given coroutine function in an asynchronous event loop.
72 The current thread must not be already running an event loop.
74 :param func: a coroutine function
75 :param args: positional arguments to ``func``
76 :param kwargs: positional arguments to ``func``
77 :param options: keyword arguments to call the backend ``run()`` implementation
78 with
79 :return: the return value of the coroutine function
80 """
82 @classmethod
83 @abstractmethod
84 def current_token(cls) -> object:
85 """
86 Return an object that allows other threads to run code inside the event loop.
88 :return: a token object, specific to the event loop running in the current
89 thread
90 """
92 @classmethod
93 @abstractmethod
94 def current_time(cls) -> float:
95 """
96 Return the current value of the event loop's internal clock.
98 :return: the clock value (seconds)
99 """
101 @classmethod
102 @abstractmethod
103 def cancelled_exception_class(cls) -> type[BaseException]:
104 """Return the exception class that is raised in a task if it's cancelled."""
106 @classmethod
107 @abstractmethod
108 async def checkpoint(cls) -> None:
109 """
110 Check if the task has been cancelled, and allow rescheduling of other tasks.
112 This is effectively the same as running :meth:`checkpoint_if_cancelled` and then
113 :meth:`cancel_shielded_checkpoint`.
114 """
116 @classmethod
117 async def checkpoint_if_cancelled(cls) -> None:
118 """
119 Check if the current task group has been cancelled.
121 This will check if the task has been cancelled, but will not allow other tasks
122 to be scheduled if not.
124 """
125 if cls.current_effective_deadline() == -math.inf:
126 await cls.checkpoint()
128 @classmethod
129 async def cancel_shielded_checkpoint(cls) -> None:
130 """
131 Allow the rescheduling of other tasks.
133 This will give other tasks the opportunity to run, but without checking if the
134 current task group has been cancelled, unlike with :meth:`checkpoint`.
136 """
137 with cls.create_cancel_scope(shield=True):
138 await cls.sleep(0)
140 @classmethod
141 @abstractmethod
142 async def sleep(cls, delay: float) -> None:
143 """
144 Pause the current task for the specified duration.
146 :param delay: the duration, in seconds
147 """
149 @classmethod
150 @abstractmethod
151 def create_cancel_scope(
152 cls, *, deadline: float = math.inf, shield: bool = False
153 ) -> CancelScope:
154 pass
156 @classmethod
157 @abstractmethod
158 def current_effective_deadline(cls) -> float:
159 """
160 Return the nearest deadline among all the cancel scopes effective for the
161 current task.
163 :return:
164 - a clock value from the event loop's internal clock
165 - ``inf`` if there is no deadline in effect
166 - ``-inf`` if the current scope has been cancelled
167 :rtype: float
168 """
170 @classmethod
171 @abstractmethod
172 def create_task_group(cls) -> TaskGroup:
173 pass
175 @classmethod
176 @abstractmethod
177 def create_event(cls) -> Event:
178 pass
180 @classmethod
181 @abstractmethod
182 def create_lock(cls, *, fast_acquire: bool) -> Lock:
183 pass
185 @classmethod
186 @abstractmethod
187 def create_semaphore(
188 cls,
189 initial_value: int,
190 *,
191 max_value: int | None = None,
192 fast_acquire: bool = False,
193 ) -> Semaphore:
194 pass
196 @classmethod
197 @abstractmethod
198 def create_capacity_limiter(cls, total_tokens: float) -> CapacityLimiter:
199 pass
201 @classmethod
202 @abstractmethod
203 async def run_sync_in_worker_thread(
204 cls,
205 func: Callable[[Unpack[PosArgsT]], T_Retval],
206 args: tuple[Unpack[PosArgsT]],
207 abandon_on_cancel: bool = False,
208 limiter: CapacityLimiter | None = None,
209 ) -> T_Retval:
210 pass
212 @classmethod
213 @abstractmethod
214 def check_cancelled(cls) -> None:
215 pass
217 @classmethod
218 @abstractmethod
219 def run_async_from_thread(
220 cls,
221 func: Callable[[Unpack[PosArgsT]], Coroutine[Any, Any, T_co]],
222 args: tuple[Unpack[PosArgsT]],
223 token: object,
224 ) -> T_co:
225 pass
227 @classmethod
228 @abstractmethod
229 def run_sync_from_thread(
230 cls,
231 func: Callable[[Unpack[PosArgsT]], T_Retval],
232 args: tuple[Unpack[PosArgsT]],
233 token: object,
234 ) -> T_Retval:
235 pass
237 @classmethod
238 @abstractmethod
239 async def open_process(
240 cls,
241 command: StrOrBytesPath | Sequence[StrOrBytesPath],
242 *,
243 stdin: int | IO[Any] | None,
244 stdout: int | IO[Any] | None,
245 stderr: int | IO[Any] | None,
246 cwd: StrOrBytesPath | None = None,
247 env: Mapping[str, str] | None = None,
248 startupinfo: Any = None,
249 creationflags: int = 0,
250 start_new_session: bool = False,
251 pass_fds: Sequence[int] = (),
252 user: str | int | None = None,
253 group: str | int | None = None,
254 extra_groups: Iterable[str | int] | None = None,
255 umask: int = -1,
256 **kwargs: Any,
257 ) -> Process:
258 pass
260 @classmethod
261 @abstractmethod
262 def setup_process_pool_exit_at_shutdown(cls, workers: set[Process]) -> None:
263 pass
265 @classmethod
266 @abstractmethod
267 async def connect_tcp(
268 cls, host: str, port: int, local_address: IPSockAddrType | None = None
269 ) -> SocketStream:
270 pass
272 @classmethod
273 @abstractmethod
274 async def connect_unix(cls, path: str | bytes) -> UNIXSocketStream:
275 pass
277 @classmethod
278 @abstractmethod
279 def create_tcp_listener(cls, sock: socket) -> SocketListener:
280 pass
282 @classmethod
283 @abstractmethod
284 def create_unix_listener(cls, sock: socket) -> SocketListener:
285 pass
287 @classmethod
288 @abstractmethod
289 async def create_udp_socket(
290 cls,
291 family: AddressFamily,
292 local_address: IPSockAddrType | None,
293 remote_address: IPSockAddrType | None,
294 reuse_port: bool,
295 ) -> UDPSocket | ConnectedUDPSocket:
296 pass
298 @classmethod
299 @overload
300 async def create_unix_datagram_socket(
301 cls, raw_socket: socket, remote_path: None
302 ) -> UNIXDatagramSocket: ...
304 @classmethod
305 @overload
306 async def create_unix_datagram_socket(
307 cls, raw_socket: socket, remote_path: str | bytes
308 ) -> ConnectedUNIXDatagramSocket: ...
310 @classmethod
311 @abstractmethod
312 async def create_unix_datagram_socket(
313 cls, raw_socket: socket, remote_path: str | bytes | None
314 ) -> UNIXDatagramSocket | ConnectedUNIXDatagramSocket:
315 pass
317 @classmethod
318 @abstractmethod
319 async def getaddrinfo(
320 cls,
321 host: bytes | str | None,
322 port: str | int | None,
323 *,
324 family: int | AddressFamily = 0,
325 type: int | SocketKind = 0,
326 proto: int = 0,
327 flags: int = 0,
328 ) -> Sequence[
329 tuple[
330 AddressFamily,
331 SocketKind,
332 int,
333 str,
334 tuple[str, int] | tuple[str, int, int, int] | tuple[int, bytes],
335 ]
336 ]:
337 pass
339 @classmethod
340 @abstractmethod
341 async def getnameinfo(
342 cls, sockaddr: IPSockAddrType, flags: int = 0
343 ) -> tuple[str, str]:
344 pass
346 @classmethod
347 @abstractmethod
348 async def wait_readable(cls, obj: FileDescriptorLike) -> None:
349 pass
351 @classmethod
352 @abstractmethod
353 async def wait_writable(cls, obj: FileDescriptorLike) -> None:
354 pass
356 @classmethod
357 @abstractmethod
358 def notify_closing(cls, obj: FileDescriptorLike) -> None:
359 pass
361 @classmethod
362 @abstractmethod
363 async def wrap_listener_socket(cls, sock: socket) -> SocketListener:
364 pass
366 @classmethod
367 @abstractmethod
368 async def wrap_stream_socket(cls, sock: socket) -> SocketStream:
369 pass
371 @classmethod
372 @abstractmethod
373 async def wrap_unix_stream_socket(cls, sock: socket) -> UNIXSocketStream:
374 pass
376 @classmethod
377 @abstractmethod
378 async def wrap_udp_socket(cls, sock: socket) -> UDPSocket:
379 pass
381 @classmethod
382 @abstractmethod
383 async def wrap_connected_udp_socket(cls, sock: socket) -> ConnectedUDPSocket:
384 pass
386 @classmethod
387 @abstractmethod
388 async def wrap_unix_datagram_socket(cls, sock: socket) -> UNIXDatagramSocket:
389 pass
391 @classmethod
392 @abstractmethod
393 async def wrap_connected_unix_datagram_socket(
394 cls, sock: socket
395 ) -> ConnectedUNIXDatagramSocket:
396 pass
398 @classmethod
399 @abstractmethod
400 def current_default_thread_limiter(cls) -> CapacityLimiter:
401 pass
403 @classmethod
404 @abstractmethod
405 def open_signal_receiver(
406 cls, *signals: Signals
407 ) -> AbstractContextManager[AsyncIterator[Signals]]:
408 pass
410 @classmethod
411 @abstractmethod
412 def get_current_task(cls) -> TaskInfo:
413 pass
415 @classmethod
416 @abstractmethod
417 def get_running_tasks(cls) -> Sequence[TaskInfo]:
418 pass
420 @classmethod
421 @abstractmethod
422 async def wait_all_tasks_blocked(cls) -> None:
423 pass
425 @classmethod
426 @abstractmethod
427 def create_test_runner(cls, options: dict[str, Any]) -> TestRunner:
428 pass