omlish 0.0.0.dev255__py3-none-any.whl → 0.0.0.dev257__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
omlish/asyncs/anyio.py DELETED
@@ -1,273 +0,0 @@
1
- """
2
- TODO:
3
- - bane
4
- - owned lock
5
- - async once
6
-
7
- See:
8
- - https://github.com/davidbrochart/sqlite-anyio/blob/a3ba4c6ef0535b14a5a60071fcd6ed565a514963/sqlite_anyio/sqlite.py
9
- - https://github.com/rafalkrupinski/ratelimit-anyio/blob/2910a8a3d6fa54ed17ee6ba457686c9f7a4c4beb/src/ratelimit_anyio/__init__.py
10
- - https://github.com/nekitdev/async-extensions/tree/main/async_extensions
11
- - https://github.com/kinnay/anynet/tree/master/anynet
12
- - https://github.com/M-o-a-T/asyncscope
13
- - https://github.com/M-o-a-T/aevent
14
- - https://github.com/florimondmanca/aiometer
15
- - https://github.com/sanitizers/octomachinery/blob/b36c3d3d49da813ac46e361424132955a4e99ac8/octomachinery/utils/asynctools.py
16
-
17
- ==
18
-
19
- async def killer(shutdown: anyio.Event, sleep_s: float) -> None:
20
- log.warning('Killing in %d seconds', sleep_s)
21
- await anyio.sleep(sleep_s)
22
- log.warning('Killing')
23
- shutdown.set()
24
-
25
- """ # noqa
26
- import dataclasses as dc
27
- import signal
28
- import typing as ta
29
-
30
- import anyio.abc
31
- import anyio.streams.memory
32
- import anyio.streams.stapled
33
- import sniffio
34
-
35
- from .. import check
36
- from .. import lang
37
-
38
-
39
- T = ta.TypeVar('T')
40
-
41
- MemoryObjectReceiveStream: ta.TypeAlias = anyio.streams.memory.MemoryObjectReceiveStream
42
- MemoryObjectSendStream: ta.TypeAlias = anyio.streams.memory.MemoryObjectSendStream
43
-
44
- StapledByteStream: ta.TypeAlias = anyio.streams.stapled.StapledByteStream
45
- StapledObjectStream: ta.TypeAlias = anyio.streams.stapled.StapledObjectStream
46
-
47
-
48
- @dc.dataclass(eq=False)
49
- class MemoryStapledObjectStream(StapledObjectStream[T]):
50
- send_stream: MemoryObjectSendStream[T]
51
- receive_stream: MemoryObjectReceiveStream[T]
52
-
53
-
54
- ##
55
-
56
-
57
- async def anyio_eof_to_empty(fn: ta.Callable[..., ta.Awaitable[T]], *args: ta.Any, **kwargs: ta.Any) -> T | bytes:
58
- try:
59
- return await fn(*args, **kwargs)
60
- except anyio.EndOfStream:
61
- return b''
62
-
63
-
64
- async def gather(*fns: ta.Callable[..., ta.Awaitable[T]], take_first: bool = False) -> list[lang.Maybe[T]]:
65
- results: list[lang.Maybe[T]] = [lang.empty()] * len(fns)
66
-
67
- async def inner(fn, i):
68
- results[i] = lang.just(await fn())
69
- if take_first:
70
- tg.cancel_scope.cancel()
71
-
72
- async with anyio.create_task_group() as tg:
73
- for i, fn in enumerate(fns):
74
- tg.start_soon(inner, fn, i)
75
-
76
- return results
77
-
78
-
79
- async def first(*fns: ta.Callable[..., ta.Awaitable[T]], **kwargs: ta.Any) -> list[lang.Maybe[T]]:
80
- return await gather(*fns, take_first=True, **kwargs)
81
-
82
-
83
- ##
84
-
85
-
86
- def get_current_task() -> anyio.TaskInfo | None:
87
- try:
88
- return anyio.get_current_task()
89
- except sniffio.AsyncLibraryNotFoundError:
90
- return None
91
-
92
-
93
- #
94
-
95
-
96
- BackendTask: ta.TypeAlias = ta.Union[ # noqa
97
- # asyncio.tasks.Task,
98
- # trio.lowlevel.Task,
99
- ta.Any,
100
- ]
101
-
102
-
103
- def _is_class_named(obj: ta.Any, m: str, n: str) -> bool:
104
- cls = obj.__class__
105
- return cls.__module__ == m and cls.__name__ == n
106
-
107
-
108
- def get_backend_task(at: anyio.TaskInfo) -> BackendTask | None:
109
- if _is_class_named(at, 'anyio._backends._asyncio', 'AsyncIOTaskInfo'):
110
- # https://github.com/agronholm/anyio/blob/8907964926a24461840eee0925d3f355e729f15d/src/anyio/_backends/_asyncio.py#L1846 # noqa
111
- # weakref.ref
112
- obj = at._task() # type: ignore # noqa
113
- if obj is not None and not (
114
- _is_class_named(obj, '_asyncio', 'Task') or
115
- _is_class_named(obj, 'asyncio.tasks', 'Task')
116
- ):
117
- raise TypeError(obj)
118
- return obj
119
-
120
- elif _is_class_named(at, 'anyio._backends._trio', 'TrioTaskInfo'):
121
- # https://github.com/agronholm/anyio/blob/8907964926a24461840eee0925d3f355e729f15d/src/anyio/_backends/_trio.py#L850 # noqa
122
- # weakref.proxy
123
- # https://stackoverflow.com/a/62144308 :|
124
- obj = at._task.__repr__.__self__ # type: ignore # noqa
125
- if obj is not None and not _is_class_named(obj, 'trio.lowlevel', 'Task'):
126
- raise TypeError(obj)
127
- return obj
128
-
129
- else:
130
- raise TypeError(at)
131
-
132
-
133
- def get_current_backend_task() -> BackendTask | None:
134
- if (at := get_current_task()) is not None:
135
- return get_backend_task(at)
136
- else:
137
- return None
138
-
139
-
140
- ##
141
-
142
-
143
- def split_memory_object_streams(
144
- *args: anyio.create_memory_object_stream[T],
145
- ) -> tuple[
146
- MemoryObjectSendStream[T],
147
- MemoryObjectReceiveStream[T],
148
- ]:
149
- [tup] = args
150
- return tup
151
-
152
-
153
- def create_stapled_memory_object_stream(max_buffer_size: float = 0) -> MemoryStapledObjectStream:
154
- return MemoryStapledObjectStream(*anyio.create_memory_object_stream(max_buffer_size))
155
-
156
-
157
- # FIXME: https://github.com/python/mypy/issues/15238
158
- # FIXME: https://youtrack.jetbrains.com/issues?q=tag:%20%7BPEP%20695%7D
159
- def create_memory_object_stream[T](max_buffer_size: float = 0) -> tuple[
160
- MemoryObjectSendStream[T],
161
- MemoryObjectReceiveStream[T],
162
- ]:
163
- return anyio.create_memory_object_stream[T](max_buffer_size) # noqa
164
-
165
-
166
- def staple_memory_object_stream(
167
- *args: anyio.create_memory_object_stream[T],
168
- ) -> MemoryStapledObjectStream[T]:
169
- send, receive = args
170
- return MemoryStapledObjectStream(
171
- check.isinstance(send, MemoryObjectSendStream), # type: ignore
172
- check.isinstance(receive, MemoryObjectReceiveStream), # type: ignore
173
- )
174
-
175
-
176
- # FIXME: https://github.com/python/mypy/issues/15238
177
- # FIXME: https://youtrack.jetbrains.com/issues?q=tag:%20%7BPEP%20695%7D
178
- def staple_memory_object_stream2[T](max_buffer_size: float = 0) -> MemoryStapledObjectStream[T]:
179
- send, receive = anyio.create_memory_object_stream[T](max_buffer_size)
180
- return MemoryStapledObjectStream(
181
- check.isinstance(send, MemoryObjectSendStream), # type: ignore
182
- check.isinstance(receive, MemoryObjectReceiveStream), # type: ignore
183
- )
184
-
185
-
186
- ##
187
-
188
-
189
- class Once:
190
- def __init__(self) -> None:
191
- super().__init__()
192
- self._done = False
193
- self._lock = anyio.Lock()
194
-
195
- async def do(self, fn: ta.Callable[[], ta.Awaitable[None]]) -> bool:
196
- if self._done:
197
- return False
198
- async with self._lock:
199
- if self._done:
200
- return False # type: ignore
201
- try:
202
- await fn()
203
- finally:
204
- self._done = True
205
- return True
206
-
207
-
208
- class Lazy(ta.Generic[T]):
209
- def __init__(self) -> None:
210
- super().__init__()
211
- self._once = Once()
212
- self._v: lang.Maybe[T] = lang.empty()
213
-
214
- def peek(self) -> lang.Maybe[T]:
215
- return self._v
216
-
217
- def set(self, v: T) -> None:
218
- self._v = lang.just(v)
219
-
220
- async def get(self, fn: ta.Callable[[], ta.Awaitable[T]]) -> T:
221
- async def do():
222
- self._v = lang.just(await fn())
223
- await self._once.do(do)
224
- return self._v.must()
225
-
226
-
227
- class LazyFn(ta.Generic[T]):
228
- def __init__(self, fn: ta.Callable[[], ta.Awaitable[T]]) -> None:
229
- super().__init__()
230
- self._fn = fn
231
- self._once = Once()
232
- self._v: lang.Maybe[T] = lang.empty()
233
-
234
- def peek(self) -> lang.Maybe[T]:
235
- return self._v
236
-
237
- def set(self, v: T) -> None:
238
- self._v = lang.just(v)
239
-
240
- async def get(self) -> T:
241
- async def do():
242
- self._v = lang.just(await self._fn())
243
- await self._once.do(do)
244
- return self._v.must()
245
-
246
-
247
- ##
248
-
249
-
250
- async def install_shutdown_signal_handler(
251
- tg: anyio.abc.TaskGroup,
252
- event: anyio.Event | None = None,
253
- *,
254
- signals: ta.Iterable[int] = (signal.SIGINT, signal.SIGTERM),
255
- echo: bool = False,
256
- ) -> ta.Callable[..., ta.Awaitable[None]] | None:
257
- if event is None:
258
- event = anyio.Event()
259
-
260
- async def _handler(*, task_status=anyio.TASK_STATUS_IGNORED):
261
- with anyio.open_signal_receiver(*signals) as it: # type: ignore
262
- task_status.started()
263
- async for signum in it:
264
- if echo:
265
- if signum == signal.SIGINT:
266
- print('Ctrl+C pressed!')
267
- else:
268
- print('Terminated!')
269
- event.set()
270
- return
271
-
272
- await tg.start(_handler)
273
- return event.wait