python-iterutils 0.2__py3-none-any.whl → 0.2.2__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.
- iterutils/__init__.py +399 -311
- {python_iterutils-0.2.dist-info → python_iterutils-0.2.2.dist-info}/METADATA +1 -1
- python_iterutils-0.2.2.dist-info/RECORD +7 -0
- python_iterutils-0.2.dist-info/RECORD +0 -7
- {python_iterutils-0.2.dist-info → python_iterutils-0.2.2.dist-info}/LICENSE +0 -0
- {python_iterutils-0.2.dist-info → python_iterutils-0.2.2.dist-info}/WHEEL +0 -0
iterutils/__init__.py
CHANGED
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
# encoding: utf-8
|
|
3
3
|
|
|
4
4
|
__author__ = "ChenyangGao <https://chenyanggao.github.io>"
|
|
5
|
-
__version__ = (0, 2)
|
|
5
|
+
__version__ = (0, 2, 2)
|
|
6
6
|
__all__ = [
|
|
7
|
-
"Return", "Yield", "YieldFrom", "iterable", "async_iterable",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
7
|
+
"Return", "Yield", "YieldFrom", "iterable", "async_iterable",
|
|
8
|
+
"foreach", "async_foreach", "through", "async_through", "flatten",
|
|
9
|
+
"async_flatten", "collect", "async_collect", "group_collect",
|
|
10
|
+
"async_group_collect", "map", "filter", "reduce", "zip", "chunked",
|
|
11
|
+
"iter_unique", "async_iter_unique", "wrap_iter", "wrap_aiter",
|
|
12
|
+
"acc_step", "cut_iter", "iter_gen_step", "iter_gen_step_async",
|
|
13
|
+
"run_gen_step", "run_gen_step_sync_iter", "run_gen_step_async_iter",
|
|
14
|
+
"run_gen_step_iter", "as_gen_step", "bfs_gen", "with_iter_next",
|
|
15
|
+
"backgroud_loop",
|
|
13
16
|
]
|
|
14
17
|
|
|
15
18
|
from abc import ABC, abstractmethod
|
|
@@ -17,11 +20,14 @@ from asyncio import create_task, sleep as async_sleep, to_thread
|
|
|
17
20
|
from builtins import map as _map, filter as _filter, zip as _zip
|
|
18
21
|
from collections import defaultdict, deque
|
|
19
22
|
from collections.abc import (
|
|
20
|
-
AsyncIterable, AsyncIterator, Awaitable, Buffer, Callable,
|
|
21
|
-
Coroutine, Generator, Iterable, Iterator,
|
|
22
|
-
MutableSequence, Sequence,
|
|
23
|
+
AsyncIterable, AsyncIterator, Awaitable, Buffer, Callable,
|
|
24
|
+
Collection, Container, Coroutine, Generator, Iterable, Iterator,
|
|
25
|
+
Mapping, MutableMapping, MutableSet, MutableSequence, Sequence,
|
|
26
|
+
ValuesView,
|
|
27
|
+
)
|
|
28
|
+
from contextlib import (
|
|
29
|
+
asynccontextmanager, contextmanager, ExitStack, AsyncExitStack,
|
|
23
30
|
)
|
|
24
|
-
from contextlib import asynccontextmanager, contextmanager, ExitStack, AsyncExitStack
|
|
25
31
|
from copy import copy
|
|
26
32
|
from dataclasses import dataclass
|
|
27
33
|
from itertools import batched, pairwise
|
|
@@ -30,11 +36,14 @@ from sys import _getframe
|
|
|
30
36
|
from _thread import start_new_thread
|
|
31
37
|
from time import sleep, time
|
|
32
38
|
from types import FrameType
|
|
33
|
-
from typing import
|
|
39
|
+
from typing import (
|
|
40
|
+
cast, overload, Any, AsyncContextManager, ContextManager, Literal,
|
|
41
|
+
Protocol,
|
|
42
|
+
)
|
|
34
43
|
|
|
35
44
|
from asynctools import (
|
|
36
|
-
async_filter, async_map, async_reduce, async_zip, async_batched,
|
|
37
|
-
collect as async_collect,
|
|
45
|
+
async_filter, async_map, async_reduce, async_zip, async_batched,
|
|
46
|
+
ensure_async, ensure_aiter, collect as async_collect,
|
|
38
47
|
)
|
|
39
48
|
from decotools import optional
|
|
40
49
|
from texttools import format_time
|
|
@@ -42,22 +51,27 @@ from undefined import undefined
|
|
|
42
51
|
|
|
43
52
|
|
|
44
53
|
class SupportsBool(Protocol):
|
|
54
|
+
"""
|
|
55
|
+
"""
|
|
45
56
|
def __bool__(self, /) -> bool: ...
|
|
46
57
|
|
|
47
58
|
|
|
48
59
|
class Reraised(BaseException):
|
|
49
|
-
|
|
60
|
+
"""
|
|
61
|
+
"""
|
|
50
62
|
def __init__(self, exc: BaseException, /):
|
|
51
63
|
if isinstance(exc, Reraised):
|
|
52
64
|
exc = exc.exception
|
|
53
65
|
self.exception: BaseException = exc
|
|
54
66
|
|
|
55
67
|
|
|
56
|
-
@dataclass(slots=True, frozen=True)
|
|
68
|
+
@dataclass(slots=True, frozen=True, unsafe_hash=True)
|
|
57
69
|
class YieldBase(ABC):
|
|
70
|
+
"""
|
|
71
|
+
"""
|
|
58
72
|
value: Any
|
|
59
|
-
may_await: None | bool =
|
|
60
|
-
may_call: None | bool =
|
|
73
|
+
may_await: None | bool | Literal[1] = False
|
|
74
|
+
may_call: None | bool | Literal[1] = None
|
|
61
75
|
|
|
62
76
|
@property
|
|
63
77
|
@abstractmethod
|
|
@@ -66,18 +80,29 @@ class YieldBase(ABC):
|
|
|
66
80
|
|
|
67
81
|
|
|
68
82
|
class Return(YieldBase):
|
|
83
|
+
"""
|
|
84
|
+
"""
|
|
85
|
+
__slots__ = ()
|
|
69
86
|
yield_type = 0
|
|
70
87
|
|
|
71
88
|
|
|
72
89
|
class Yield(YieldBase):
|
|
90
|
+
"""
|
|
91
|
+
"""
|
|
92
|
+
__slots__ = ()
|
|
73
93
|
yield_type = 1
|
|
74
94
|
|
|
75
95
|
|
|
76
96
|
class YieldFrom(YieldBase):
|
|
97
|
+
"""
|
|
98
|
+
"""
|
|
99
|
+
__slots__ = ()
|
|
77
100
|
yield_type = 2
|
|
78
101
|
|
|
79
102
|
|
|
80
103
|
def iterable(iterable, /) -> bool:
|
|
104
|
+
"""
|
|
105
|
+
"""
|
|
81
106
|
try:
|
|
82
107
|
return isinstance(iter(iterable), Iterable)
|
|
83
108
|
except TypeError:
|
|
@@ -85,6 +110,8 @@ def iterable(iterable, /) -> bool:
|
|
|
85
110
|
|
|
86
111
|
|
|
87
112
|
def async_iterable(iterable, /) -> bool:
|
|
113
|
+
"""
|
|
114
|
+
"""
|
|
88
115
|
try:
|
|
89
116
|
return isinstance(iter(iterable), AsyncIterable)
|
|
90
117
|
except TypeError:
|
|
@@ -97,6 +124,8 @@ def foreach(
|
|
|
97
124
|
/,
|
|
98
125
|
*iterables: Iterable | AsyncIterable,
|
|
99
126
|
):
|
|
127
|
+
"""
|
|
128
|
+
"""
|
|
100
129
|
if not (isinstance(iterable, Iterable) and all(isinstance(it, Iterable) for it in iterables)):
|
|
101
130
|
return async_foreach(value, iterable, *iterables)
|
|
102
131
|
if iterables:
|
|
@@ -114,6 +143,8 @@ async def async_foreach(
|
|
|
114
143
|
*iterables: Iterable | AsyncIterable,
|
|
115
144
|
threaded: bool = False,
|
|
116
145
|
):
|
|
146
|
+
"""
|
|
147
|
+
"""
|
|
117
148
|
value = ensure_async(value, threaded=threaded)
|
|
118
149
|
if iterables:
|
|
119
150
|
async for args in async_zip(iterable, *iterables, threaded=threaded):
|
|
@@ -128,6 +159,8 @@ def through(
|
|
|
128
159
|
/,
|
|
129
160
|
take_while: None | Callable = None,
|
|
130
161
|
):
|
|
162
|
+
"""
|
|
163
|
+
"""
|
|
131
164
|
if not isinstance(iterable, Iterable):
|
|
132
165
|
return async_through(iterable, take_while)
|
|
133
166
|
if take_while is None:
|
|
@@ -145,6 +178,8 @@ async def async_through(
|
|
|
145
178
|
take_while: None | Callable = None,
|
|
146
179
|
threaded: bool = False,
|
|
147
180
|
):
|
|
181
|
+
"""
|
|
182
|
+
"""
|
|
148
183
|
iterable = ensure_aiter(iterable, threaded=threaded)
|
|
149
184
|
if take_while is None:
|
|
150
185
|
async for _ in iterable:
|
|
@@ -178,6 +213,8 @@ def flatten(
|
|
|
178
213
|
/,
|
|
179
214
|
exclude_types: type | tuple[type, ...] = (Buffer, str),
|
|
180
215
|
) -> Iterator | AsyncIterator:
|
|
216
|
+
"""
|
|
217
|
+
"""
|
|
181
218
|
if not isinstance(iterable, Iterable):
|
|
182
219
|
return async_flatten(iterable, exclude_types)
|
|
183
220
|
def gen(iterable):
|
|
@@ -195,6 +232,8 @@ async def async_flatten(
|
|
|
195
232
|
exclude_types: type | tuple[type, ...] = (Buffer, str),
|
|
196
233
|
threaded: bool = False,
|
|
197
234
|
) -> AsyncIterator:
|
|
235
|
+
"""
|
|
236
|
+
"""
|
|
198
237
|
async for e in ensure_aiter(iterable, threaded=threaded):
|
|
199
238
|
if isinstance(e, (Iterable, AsyncIterable)) and not isinstance(e, exclude_types):
|
|
200
239
|
async for e in async_flatten(e, exclude_types, threaded=threaded):
|
|
@@ -236,6 +275,8 @@ def collect(
|
|
|
236
275
|
/,
|
|
237
276
|
rettype: Callable[[Iterable], Collection] = list,
|
|
238
277
|
) -> Collection | Coroutine[Any, Any, Collection]:
|
|
278
|
+
"""
|
|
279
|
+
"""
|
|
239
280
|
if not isinstance(iterable, Iterable):
|
|
240
281
|
return async_collect(iterable, rettype)
|
|
241
282
|
return rettype(iterable)
|
|
@@ -274,6 +315,8 @@ def group_collect[K, V, C: Container, M: MutableMapping](
|
|
|
274
315
|
mapping: None | M = None,
|
|
275
316
|
factory: None | C | Callable[[], C] = None,
|
|
276
317
|
) -> dict[K, C] | M | Coroutine[Any, Any, dict[K, C]] | Coroutine[Any, Any, M]:
|
|
318
|
+
"""
|
|
319
|
+
"""
|
|
277
320
|
if not isinstance(iterable, Iterable):
|
|
278
321
|
return async_group_collect(iterable, mapping, factory)
|
|
279
322
|
if factory is None:
|
|
@@ -331,6 +374,8 @@ async def async_group_collect[K, V, C: Container, M: MutableMapping](
|
|
|
331
374
|
factory: None | C | Callable[[], C] = None,
|
|
332
375
|
threaded: bool = False,
|
|
333
376
|
) -> dict[K, C] | M:
|
|
377
|
+
"""
|
|
378
|
+
"""
|
|
334
379
|
iterable = ensure_aiter(iterable, threaded=threaded)
|
|
335
380
|
if factory is None:
|
|
336
381
|
if isinstance(mapping, defaultdict):
|
|
@@ -370,7 +415,9 @@ def map(
|
|
|
370
415
|
iterable: Iterable | AsyncIterable,
|
|
371
416
|
/,
|
|
372
417
|
*iterables: Iterable | AsyncIterable,
|
|
373
|
-
):
|
|
418
|
+
):
|
|
419
|
+
"""
|
|
420
|
+
"""
|
|
374
421
|
if (
|
|
375
422
|
iscoroutinefunction(function) or
|
|
376
423
|
isinstance(iterable, AsyncIterable) or
|
|
@@ -395,6 +442,8 @@ def filter(
|
|
|
395
442
|
iterable: Iterable | AsyncIterable,
|
|
396
443
|
/,
|
|
397
444
|
):
|
|
445
|
+
"""
|
|
446
|
+
"""
|
|
398
447
|
if iscoroutinefunction(function) or isinstance(iterable, AsyncIterable):
|
|
399
448
|
return async_filter(function, iterable)
|
|
400
449
|
return _filter(function, iterable)
|
|
@@ -406,6 +455,8 @@ def reduce(
|
|
|
406
455
|
initial: Any = undefined,
|
|
407
456
|
/,
|
|
408
457
|
):
|
|
458
|
+
"""
|
|
459
|
+
"""
|
|
409
460
|
if iscoroutinefunction(function) or isinstance(iterable, AsyncIterable):
|
|
410
461
|
return async_reduce(function, iterable, initial)
|
|
411
462
|
from functools import reduce
|
|
@@ -419,6 +470,8 @@ def zip(
|
|
|
419
470
|
/,
|
|
420
471
|
*iterables: Iterable | AsyncIterable,
|
|
421
472
|
):
|
|
473
|
+
"""
|
|
474
|
+
"""
|
|
422
475
|
if isinstance(iterable, AsyncIterable) or any(isinstance(i, AsyncIterable) for i in iterables):
|
|
423
476
|
return async_zip(iterable, *iterables)
|
|
424
477
|
return _zip(iterable, *iterables)
|
|
@@ -443,6 +496,8 @@ def chunked[T](
|
|
|
443
496
|
n: int = 1,
|
|
444
497
|
/,
|
|
445
498
|
) -> Iterator[Sequence[T]] | AsyncIterator[Sequence[T]]:
|
|
499
|
+
"""
|
|
500
|
+
"""
|
|
446
501
|
if n < 0:
|
|
447
502
|
n = 1
|
|
448
503
|
if isinstance(iterable, Sequence):
|
|
@@ -474,6 +529,8 @@ def iter_unique[T](
|
|
|
474
529
|
/,
|
|
475
530
|
seen: None | MutableSet = None,
|
|
476
531
|
) -> Iterator[T] | AsyncIterator[T]:
|
|
532
|
+
"""
|
|
533
|
+
"""
|
|
477
534
|
if not isinstance(iterable, Iterable):
|
|
478
535
|
return async_iter_unique(iterable, seen)
|
|
479
536
|
if seen is None:
|
|
@@ -493,6 +550,8 @@ async def async_iter_unique[T](
|
|
|
493
550
|
seen: None | MutableSet = None,
|
|
494
551
|
threaded: bool = False,
|
|
495
552
|
) -> AsyncIterator[T]:
|
|
553
|
+
"""
|
|
554
|
+
"""
|
|
496
555
|
if seen is None:
|
|
497
556
|
seen = set()
|
|
498
557
|
add = seen.add
|
|
@@ -508,8 +567,6 @@ def wrap_iter[T](
|
|
|
508
567
|
/,
|
|
509
568
|
callprev: None | Callable[[T], Any] = None,
|
|
510
569
|
callnext: None | Callable[[T], Any] = None,
|
|
511
|
-
callenter: None | Callable[[Iterable[T]], Any] = None,
|
|
512
|
-
callexit: None | Callable[[Iterable[T], None | BaseException], Any] = None,
|
|
513
570
|
) -> Iterator[T]:
|
|
514
571
|
...
|
|
515
572
|
@overload
|
|
@@ -518,8 +575,6 @@ def wrap_iter[T](
|
|
|
518
575
|
/,
|
|
519
576
|
callprev: None | Callable[[T], Any] = None,
|
|
520
577
|
callnext: None | Callable[[T], Any] = None,
|
|
521
|
-
callenter: None | Callable[[Iterable[T] | AsyncIterable[T]], Any] = None,
|
|
522
|
-
callexit: None | Callable[[Iterable[T] | AsyncIterable[T], None | BaseException], Any] = None,
|
|
523
578
|
) -> AsyncIterator[T]:
|
|
524
579
|
...
|
|
525
580
|
def wrap_iter[T](
|
|
@@ -527,47 +582,24 @@ def wrap_iter[T](
|
|
|
527
582
|
/,
|
|
528
583
|
callprev: None | Callable[[T], Any] = None,
|
|
529
584
|
callnext: None | Callable[[T], Any] = None,
|
|
530
|
-
callenter: None | Callable[[Iterable[T]], Any] | Callable[[Iterable[T] | AsyncIterable[T]], Any] = None,
|
|
531
|
-
callexit: ( None | Callable[[Iterable[T], None | BaseException], Any] |
|
|
532
|
-
Callable[[Iterable[T] | AsyncIterable[T], None | BaseException], Any] ) = None,
|
|
533
585
|
) -> Iterator[T] | AsyncIterator[T]:
|
|
586
|
+
"""
|
|
587
|
+
"""
|
|
534
588
|
if not isinstance(iterable, Iterable):
|
|
535
589
|
return wrap_aiter(
|
|
536
590
|
iterable,
|
|
537
591
|
callprev=callprev,
|
|
538
592
|
callnext=callnext,
|
|
539
|
-
callenter=callenter, # type: ignore
|
|
540
|
-
callexit=callexit, # type: ignore
|
|
541
593
|
)
|
|
542
594
|
if not callable(callprev):
|
|
543
595
|
callprev = None
|
|
544
596
|
if not callable(callnext):
|
|
545
597
|
callnext = None
|
|
546
598
|
def gen():
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
if callprev:
|
|
552
|
-
try:
|
|
553
|
-
callprev(e)
|
|
554
|
-
except (StopIteration, GeneratorExit):
|
|
555
|
-
break
|
|
556
|
-
yield e
|
|
557
|
-
if callnext:
|
|
558
|
-
try:
|
|
559
|
-
callnext(e)
|
|
560
|
-
except (StopIteration, GeneratorExit):
|
|
561
|
-
break
|
|
562
|
-
except BaseException as e:
|
|
563
|
-
if callable(callexit):
|
|
564
|
-
if not callexit(iterable, e):
|
|
565
|
-
raise
|
|
566
|
-
else:
|
|
567
|
-
raise
|
|
568
|
-
finally:
|
|
569
|
-
if callable(callexit):
|
|
570
|
-
callexit(iterable, None)
|
|
599
|
+
for e in iterable:
|
|
600
|
+
callprev and callprev(e)
|
|
601
|
+
yield e
|
|
602
|
+
callnext and callnext(e)
|
|
571
603
|
return gen()
|
|
572
604
|
|
|
573
605
|
|
|
@@ -576,34 +608,16 @@ async def wrap_aiter[T](
|
|
|
576
608
|
/,
|
|
577
609
|
callprev: None | Callable[[T], Any] = None,
|
|
578
610
|
callnext: None | Callable[[T], Any] = None,
|
|
579
|
-
callenter: None | Callable[[Iterable[T] | AsyncIterable[T]], Any] = None,
|
|
580
|
-
callexit: None | Callable[[Iterable[T] | AsyncIterable[T], None | BaseException], Any] = None,
|
|
581
611
|
threaded: bool = False,
|
|
582
612
|
) -> AsyncIterator[T]:
|
|
613
|
+
"""
|
|
614
|
+
"""
|
|
583
615
|
callprev = ensure_async(callprev, threaded=threaded) if callable(callprev) else None
|
|
584
616
|
callnext = ensure_async(callnext, threaded=threaded) if callable(callnext) else None
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
await callprev(e)
|
|
590
|
-
except (StopAsyncIteration, GeneratorExit):
|
|
591
|
-
break
|
|
592
|
-
yield e
|
|
593
|
-
if callnext:
|
|
594
|
-
try:
|
|
595
|
-
await callnext(e)
|
|
596
|
-
except (StopAsyncIteration, GeneratorExit):
|
|
597
|
-
break
|
|
598
|
-
except BaseException as e:
|
|
599
|
-
if callable(callexit):
|
|
600
|
-
if not await ensure_async(callexit, threaded=threaded)(iterable, e):
|
|
601
|
-
raise
|
|
602
|
-
else:
|
|
603
|
-
raise
|
|
604
|
-
finally:
|
|
605
|
-
if callable(callexit):
|
|
606
|
-
await ensure_async(callexit, threaded=threaded)(iterable, None)
|
|
617
|
+
async for e in ensure_aiter(iterable, threaded=threaded):
|
|
618
|
+
callprev and await callprev(e)
|
|
619
|
+
yield e
|
|
620
|
+
callnext and await callnext(e)
|
|
607
621
|
|
|
608
622
|
|
|
609
623
|
def acc_step(
|
|
@@ -611,6 +625,8 @@ def acc_step(
|
|
|
611
625
|
stop: None | int = None,
|
|
612
626
|
step: int = 1,
|
|
613
627
|
) -> Iterator[tuple[int, int, int]]:
|
|
628
|
+
"""
|
|
629
|
+
"""
|
|
614
630
|
if stop is None:
|
|
615
631
|
start, stop = 0, start
|
|
616
632
|
for i in range(start + step, stop, step):
|
|
@@ -624,6 +640,8 @@ def cut_iter(
|
|
|
624
640
|
stop: None | int = None,
|
|
625
641
|
step: int = 1,
|
|
626
642
|
) -> Iterator[tuple[int, int]]:
|
|
643
|
+
"""
|
|
644
|
+
"""
|
|
627
645
|
if stop is None:
|
|
628
646
|
start, stop = 0, start
|
|
629
647
|
for start in range(start + step, stop, step):
|
|
@@ -639,7 +657,7 @@ def _get_async(back: int = 2) -> bool:
|
|
|
639
657
|
f_locals = f.f_locals
|
|
640
658
|
if f_locals is f_globals:
|
|
641
659
|
return f_locals.get("async_") or False
|
|
642
|
-
while f_locals is not f_globals:
|
|
660
|
+
while f_locals is not None and f_locals is not f_globals:
|
|
643
661
|
if "async_" in f_locals:
|
|
644
662
|
return f_locals["async_"] or False
|
|
645
663
|
f = f.f_back
|
|
@@ -652,23 +670,25 @@ def _get_async(back: int = 2) -> bool:
|
|
|
652
670
|
@overload
|
|
653
671
|
def call_as_async[**Args, T: Coroutine](
|
|
654
672
|
func: Callable[Args, T], /,
|
|
655
|
-
may_await:
|
|
673
|
+
may_await: bool | Literal[1] = False,
|
|
656
674
|
threaded: bool = False,
|
|
657
675
|
) -> Callable[Args, T]:
|
|
658
676
|
...
|
|
659
677
|
@overload
|
|
660
678
|
def call_as_async[**Args, T](
|
|
661
679
|
func: Callable[Args, T], /,
|
|
662
|
-
may_await:
|
|
680
|
+
may_await: bool | Literal[1] = False,
|
|
663
681
|
threaded: bool = False,
|
|
664
682
|
) -> Callable[Args, Coroutine[Any, Any, T]]:
|
|
665
683
|
...
|
|
666
684
|
def call_as_async[**Args, T](
|
|
667
685
|
func: Callable[Args, T],
|
|
668
686
|
/,
|
|
669
|
-
may_await:
|
|
687
|
+
may_await: bool | Literal[1] = False,
|
|
670
688
|
threaded: bool = False,
|
|
671
689
|
) -> Callable[Args, T] | Callable[Args, Coroutine[Any, Any, T]]:
|
|
690
|
+
"""
|
|
691
|
+
"""
|
|
672
692
|
if iscoroutinefunction(func):
|
|
673
693
|
return func
|
|
674
694
|
def wraps(*args, **kwds):
|
|
@@ -681,7 +701,7 @@ def call_as_async[**Args, T](
|
|
|
681
701
|
value = await to_thread(wraps, *args, **kwds)
|
|
682
702
|
else:
|
|
683
703
|
value = wraps(*args, **kwds)
|
|
684
|
-
if may_await is
|
|
704
|
+
if may_await is 1 or may_await and isawaitable(value):
|
|
685
705
|
value = await value
|
|
686
706
|
return value
|
|
687
707
|
return wrapper
|
|
@@ -689,140 +709,131 @@ def call_as_async[**Args, T](
|
|
|
689
709
|
|
|
690
710
|
def iter_gen_step(
|
|
691
711
|
gen_step: Generator | Callable[[], Generator],
|
|
692
|
-
|
|
712
|
+
may_call: bool | Literal[1] = True,
|
|
693
713
|
):
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
714
|
+
"""
|
|
715
|
+
"""
|
|
716
|
+
if callable(gen_step):
|
|
717
|
+
gen_step = gen_step()
|
|
718
|
+
send = gen_step.send
|
|
719
|
+
throw = gen_step.throw
|
|
720
|
+
close = gen_step.close
|
|
698
721
|
value: Any = None
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
while True:
|
|
702
|
-
yield (value := send(value))
|
|
703
|
-
except StopIteration as e:
|
|
704
|
-
yield e.value
|
|
705
|
-
finally:
|
|
706
|
-
close()
|
|
707
|
-
else:
|
|
708
|
-
try:
|
|
709
|
-
while True:
|
|
710
|
-
if isinstance(value, YieldBase):
|
|
711
|
-
raise StopIteration(value)
|
|
712
|
-
try:
|
|
713
|
-
if callable(value):
|
|
714
|
-
value = value()
|
|
715
|
-
except BaseException as e:
|
|
716
|
-
value = throw(e)
|
|
717
|
-
else:
|
|
718
|
-
value = send(value)
|
|
719
|
-
yield value
|
|
720
|
-
except StopIteration as e:
|
|
721
|
-
may_call: None | bool = True
|
|
722
|
-
value = e.value
|
|
722
|
+
try:
|
|
723
|
+
while True:
|
|
723
724
|
if isinstance(value, YieldBase):
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
try:
|
|
725
|
+
raise StopIteration(value)
|
|
726
|
+
try:
|
|
727
|
+
if may_call is 1 or may_call and callable(value):
|
|
728
728
|
value = value()
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
raise Reraised(e) from e
|
|
729
|
+
except BaseException as e:
|
|
730
|
+
value = throw(e)
|
|
731
|
+
else:
|
|
732
|
+
value = send(value)
|
|
734
733
|
yield value
|
|
735
|
-
|
|
736
|
-
|
|
734
|
+
except StopIteration as e:
|
|
735
|
+
value = e.value
|
|
736
|
+
if isinstance(value, YieldBase):
|
|
737
|
+
maybe_callable = value.may_call
|
|
738
|
+
if maybe_callable is not None:
|
|
739
|
+
may_call = maybe_callable
|
|
740
|
+
value = value.value
|
|
741
|
+
if may_call is 1 or may_call and callable(value):
|
|
742
|
+
try:
|
|
743
|
+
value = value()
|
|
744
|
+
except BaseException as e:
|
|
745
|
+
try:
|
|
746
|
+
value = throw(e)
|
|
747
|
+
except BaseException as e:
|
|
748
|
+
raise Reraised(e) from e
|
|
749
|
+
yield value
|
|
750
|
+
finally:
|
|
751
|
+
close()
|
|
737
752
|
|
|
738
753
|
|
|
739
754
|
async def iter_gen_step_async(
|
|
740
755
|
gen_step: Generator | Callable[[], Generator],
|
|
756
|
+
may_await: bool | Literal[1] = True,
|
|
757
|
+
may_call: bool | Literal[1] = True,
|
|
741
758
|
threaded: bool = False,
|
|
742
|
-
simple: bool = False,
|
|
743
759
|
):
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
760
|
+
"""
|
|
761
|
+
"""
|
|
762
|
+
if callable(gen_step):
|
|
763
|
+
gen_step = gen_step()
|
|
764
|
+
send: Callable = call_as_async(gen_step.send, threaded=threaded)
|
|
765
|
+
throw: Callable = call_as_async(gen_step.throw, threaded=threaded)
|
|
766
|
+
close: Callable = call_as_async(gen_step.close, threaded=threaded)
|
|
748
767
|
value: Any = None
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
768
|
+
try:
|
|
769
|
+
while True:
|
|
770
|
+
if isinstance(value, YieldBase):
|
|
771
|
+
raise StopIteration(value)
|
|
772
|
+
try:
|
|
773
|
+
if may_call is 1 or may_call and callable(value):
|
|
774
|
+
value = await call_as_async(
|
|
775
|
+
value, may_await=may_await, threaded=threaded)()
|
|
776
|
+
elif may_await is 1 or may_await and isawaitable(value):
|
|
777
|
+
value = await value
|
|
778
|
+
except BaseException as e:
|
|
779
|
+
if isinstance(e, Reraised):
|
|
780
|
+
e = e.exception
|
|
781
|
+
value = await throw(e)
|
|
760
782
|
else:
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
783
|
+
value = await send(value)
|
|
784
|
+
yield value
|
|
785
|
+
except BaseException as e:
|
|
786
|
+
if isinstance(e, Reraised):
|
|
787
|
+
e = e.exception
|
|
788
|
+
if isinstance(e, StopIteration):
|
|
789
|
+
value = e.value
|
|
790
|
+
if isinstance(value, YieldBase):
|
|
791
|
+
maybe_awaitable = value.may_await
|
|
792
|
+
if maybe_awaitable is not None:
|
|
793
|
+
may_await = maybe_awaitable
|
|
794
|
+
maybe_callable = value.may_call
|
|
795
|
+
if maybe_callable is not None:
|
|
796
|
+
may_call = maybe_callable
|
|
797
|
+
value = value.value
|
|
798
|
+
try:
|
|
799
|
+
if may_call is 1 or may_call and callable(value):
|
|
800
|
+
value = await call_as_async(
|
|
801
|
+
value, may_await=may_await, threaded=threaded)()
|
|
802
|
+
elif may_await is 1 or may_await and isawaitable(value):
|
|
803
|
+
value = await value
|
|
804
|
+
except BaseException as e:
|
|
771
805
|
try:
|
|
772
|
-
if callable(value):
|
|
773
|
-
value = await call_as_async(
|
|
774
|
-
value, may_await=True, threaded=threaded)()
|
|
775
|
-
elif isawaitable(value):
|
|
776
|
-
value = await value
|
|
777
|
-
except BaseException as e:
|
|
778
|
-
if isinstance(e, Reraised):
|
|
779
|
-
e = e.exception
|
|
780
806
|
value = await throw(e)
|
|
781
|
-
else:
|
|
782
|
-
value = await send(value)
|
|
783
|
-
yield value
|
|
784
|
-
except BaseException as e:
|
|
785
|
-
if isinstance(e, Reraised):
|
|
786
|
-
e = e.exception
|
|
787
|
-
if isinstance(e, StopIteration):
|
|
788
|
-
may_await: None | bool = True
|
|
789
|
-
may_call: None | bool = True
|
|
790
|
-
value = e.value
|
|
791
|
-
if isinstance(value, YieldBase):
|
|
792
|
-
may_await = value.may_await
|
|
793
|
-
may_call = value.may_call
|
|
794
|
-
value = value.value
|
|
795
|
-
try:
|
|
796
|
-
if may_call is None or may_call and callable(value):
|
|
797
|
-
value = await call_as_async(
|
|
798
|
-
value, may_await=may_await, threaded=threaded)()
|
|
799
|
-
elif may_await is None or may_await and isawaitable(value):
|
|
800
|
-
value = await value
|
|
801
807
|
except BaseException as e:
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
raise
|
|
809
|
-
finally:
|
|
810
|
-
await close()
|
|
808
|
+
raise Reraised(e) from e
|
|
809
|
+
yield value
|
|
810
|
+
else:
|
|
811
|
+
raise
|
|
812
|
+
finally:
|
|
813
|
+
await close()
|
|
811
814
|
|
|
812
815
|
|
|
813
816
|
def run_gen_step(
|
|
814
817
|
gen_step: Generator | Callable[[], Generator],
|
|
815
|
-
|
|
818
|
+
may_await: bool | Literal[1] = True,
|
|
819
|
+
may_call: bool | Literal[1] = True,
|
|
816
820
|
threaded: bool = False,
|
|
817
821
|
running_flag: None | SupportsBool | Callable[[], SupportsBool] | Callable[[], Awaitable[SupportsBool]] = None,
|
|
818
822
|
*,
|
|
819
823
|
async_: None | bool = None,
|
|
820
824
|
):
|
|
825
|
+
"""
|
|
826
|
+
"""
|
|
821
827
|
if async_ is None:
|
|
822
828
|
async_ = _get_async()
|
|
823
829
|
if async_:
|
|
824
830
|
async def process():
|
|
825
|
-
gen = iter_gen_step_async(
|
|
831
|
+
gen = iter_gen_step_async(
|
|
832
|
+
gen_step,
|
|
833
|
+
may_await=may_await,
|
|
834
|
+
may_call=may_call,
|
|
835
|
+
threaded=threaded,
|
|
836
|
+
)
|
|
826
837
|
try:
|
|
827
838
|
if running_flag is None:
|
|
828
839
|
async for value in gen:
|
|
@@ -849,7 +860,7 @@ def run_gen_step(
|
|
|
849
860
|
raise
|
|
850
861
|
return process()
|
|
851
862
|
else:
|
|
852
|
-
gen = iter_gen_step(gen_step,
|
|
863
|
+
gen = iter_gen_step(gen_step, may_call=may_call)
|
|
853
864
|
try:
|
|
854
865
|
if running_flag is None:
|
|
855
866
|
for value in gen:
|
|
@@ -871,10 +882,136 @@ def run_gen_step(
|
|
|
871
882
|
raise
|
|
872
883
|
|
|
873
884
|
|
|
885
|
+
def run_gen_step_sync_iter(
|
|
886
|
+
gen_step: Generator | Callable[[], Generator],
|
|
887
|
+
may_call: bool | Literal[1] = True,
|
|
888
|
+
) -> Iterator:
|
|
889
|
+
"""
|
|
890
|
+
"""
|
|
891
|
+
if callable(gen_step):
|
|
892
|
+
gen_step = gen_step()
|
|
893
|
+
send: Callable = gen_step.send
|
|
894
|
+
throw: Callable = gen_step.throw
|
|
895
|
+
close: Callable = gen_step.close
|
|
896
|
+
def extract(value, may_call=may_call, /):
|
|
897
|
+
yield_type = -1
|
|
898
|
+
if isinstance(value, YieldBase):
|
|
899
|
+
yield_type = value.yield_type
|
|
900
|
+
maybe_callable = value.may_call
|
|
901
|
+
if maybe_callable is not None:
|
|
902
|
+
may_call = maybe_callable
|
|
903
|
+
value = value.value
|
|
904
|
+
if may_call is 1 or may_call and callable(value):
|
|
905
|
+
value = value()
|
|
906
|
+
return yield_type, value
|
|
907
|
+
try:
|
|
908
|
+
value = send(None)
|
|
909
|
+
while True:
|
|
910
|
+
try:
|
|
911
|
+
yield_type, value = extract(value)
|
|
912
|
+
match yield_type:
|
|
913
|
+
case 0:
|
|
914
|
+
return value
|
|
915
|
+
case 1:
|
|
916
|
+
yield value
|
|
917
|
+
case 2:
|
|
918
|
+
yield from value
|
|
919
|
+
except BaseException as e:
|
|
920
|
+
value = throw(e)
|
|
921
|
+
else:
|
|
922
|
+
value = send(value)
|
|
923
|
+
except StopIteration as e:
|
|
924
|
+
try:
|
|
925
|
+
yield_type, value = extract(e.value)
|
|
926
|
+
match yield_type:
|
|
927
|
+
case 1:
|
|
928
|
+
yield value
|
|
929
|
+
case 2:
|
|
930
|
+
yield from value
|
|
931
|
+
case _:
|
|
932
|
+
return value
|
|
933
|
+
except BaseException as e:
|
|
934
|
+
throw(e)
|
|
935
|
+
finally:
|
|
936
|
+
close()
|
|
937
|
+
|
|
938
|
+
|
|
939
|
+
async def run_gen_step_async_iter(
|
|
940
|
+
gen_step: Generator | Callable[[], Generator],
|
|
941
|
+
may_await: bool | Literal[1] = True,
|
|
942
|
+
may_call: bool | Literal[1] = True,
|
|
943
|
+
threaded: bool = False,
|
|
944
|
+
) -> AsyncIterator:
|
|
945
|
+
"""
|
|
946
|
+
"""
|
|
947
|
+
if callable(gen_step):
|
|
948
|
+
gen_step = gen_step()
|
|
949
|
+
send: Callable = call_as_async(gen_step.send, threaded=threaded)
|
|
950
|
+
throw: Callable = call_as_async(gen_step.throw, threaded=threaded)
|
|
951
|
+
close: Callable = call_as_async(gen_step.close, threaded=threaded)
|
|
952
|
+
async def extract(value, may_await=may_await, may_call=may_call, /):
|
|
953
|
+
yield_type = -1
|
|
954
|
+
if isinstance(value, YieldBase):
|
|
955
|
+
yield_type = value.yield_type
|
|
956
|
+
maybe_awaitable = value.may_await
|
|
957
|
+
if maybe_awaitable is not None:
|
|
958
|
+
may_await = maybe_awaitable
|
|
959
|
+
maybe_callable = value.may_call
|
|
960
|
+
if maybe_callable is not None:
|
|
961
|
+
may_call = maybe_callable
|
|
962
|
+
value = value.value
|
|
963
|
+
if may_call is 1 or may_call and callable(value):
|
|
964
|
+
value = await call_as_async(
|
|
965
|
+
value, may_await=may_await, threaded=threaded)()
|
|
966
|
+
elif may_await is 1 or may_await and isawaitable(value):
|
|
967
|
+
value = await value
|
|
968
|
+
return yield_type, value
|
|
969
|
+
try:
|
|
970
|
+
value = await send(None)
|
|
971
|
+
while True:
|
|
972
|
+
try:
|
|
973
|
+
yield_type, value = await extract(value)
|
|
974
|
+
match yield_type:
|
|
975
|
+
case 0:
|
|
976
|
+
return
|
|
977
|
+
case 1:
|
|
978
|
+
yield value
|
|
979
|
+
case 2:
|
|
980
|
+
async for val in ensure_aiter(value, threaded=threaded):
|
|
981
|
+
yield val
|
|
982
|
+
except BaseException as e:
|
|
983
|
+
if isinstance(e, Reraised):
|
|
984
|
+
e = e.exception
|
|
985
|
+
value = await throw(e)
|
|
986
|
+
else:
|
|
987
|
+
value = await send(value)
|
|
988
|
+
except BaseException as e:
|
|
989
|
+
if isinstance(e, Reraised):
|
|
990
|
+
e = e.exception
|
|
991
|
+
if isinstance(e, StopIteration):
|
|
992
|
+
try:
|
|
993
|
+
yield_type, value = await extract(e.value)
|
|
994
|
+
match yield_type:
|
|
995
|
+
case 1:
|
|
996
|
+
yield value
|
|
997
|
+
case 2:
|
|
998
|
+
async for val in ensure_aiter(value, threaded=threaded):
|
|
999
|
+
yield val
|
|
1000
|
+
except BaseException as e:
|
|
1001
|
+
if isinstance(e, Reraised):
|
|
1002
|
+
e = e.exception
|
|
1003
|
+
await throw(e)
|
|
1004
|
+
else:
|
|
1005
|
+
raise
|
|
1006
|
+
finally:
|
|
1007
|
+
await close()
|
|
1008
|
+
|
|
1009
|
+
|
|
874
1010
|
@overload
|
|
875
1011
|
def run_gen_step_iter(
|
|
876
1012
|
gen_step: Generator | Callable[[], Generator],
|
|
877
|
-
|
|
1013
|
+
may_await: bool | Literal[1] = True,
|
|
1014
|
+
may_call: bool | Literal[1] = True,
|
|
878
1015
|
threaded: bool = False,
|
|
879
1016
|
*,
|
|
880
1017
|
async_: None = None,
|
|
@@ -883,7 +1020,8 @@ def run_gen_step_iter(
|
|
|
883
1020
|
@overload
|
|
884
1021
|
def run_gen_step_iter(
|
|
885
1022
|
gen_step: Generator | Callable[[], Generator],
|
|
886
|
-
|
|
1023
|
+
may_await: bool | Literal[1] = True,
|
|
1024
|
+
may_call: bool | Literal[1] = True,
|
|
887
1025
|
threaded: bool = False,
|
|
888
1026
|
*,
|
|
889
1027
|
async_: Literal[False],
|
|
@@ -892,7 +1030,8 @@ def run_gen_step_iter(
|
|
|
892
1030
|
@overload
|
|
893
1031
|
def run_gen_step_iter(
|
|
894
1032
|
gen_step: Generator | Callable[[], Generator],
|
|
895
|
-
|
|
1033
|
+
may_await: bool | Literal[1] = True,
|
|
1034
|
+
may_call: bool | Literal[1] = True,
|
|
896
1035
|
threaded: bool = False,
|
|
897
1036
|
*,
|
|
898
1037
|
async_: Literal[True],
|
|
@@ -900,120 +1039,25 @@ def run_gen_step_iter(
|
|
|
900
1039
|
...
|
|
901
1040
|
def run_gen_step_iter(
|
|
902
1041
|
gen_step: Generator | Callable[[], Generator],
|
|
903
|
-
|
|
1042
|
+
may_await: bool | Literal[1] = True,
|
|
1043
|
+
may_call: bool | Literal[1] = True,
|
|
904
1044
|
threaded: bool = False,
|
|
905
1045
|
*,
|
|
906
1046
|
async_: None | bool = None,
|
|
907
1047
|
) -> Iterator | AsyncIterator:
|
|
1048
|
+
"""
|
|
1049
|
+
"""
|
|
908
1050
|
if async_ is None:
|
|
909
1051
|
async_ = _get_async()
|
|
910
|
-
gen = gen_step() if callable(gen_step) else gen_step
|
|
911
|
-
send: Callable = gen.send
|
|
912
|
-
throw: Callable = gen.throw
|
|
913
|
-
close: Callable = gen.close
|
|
914
1052
|
if async_:
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
yield_type = -1
|
|
922
|
-
if isinstance(value, YieldBase):
|
|
923
|
-
yield_type = value.yield_type
|
|
924
|
-
may_await = value.may_await
|
|
925
|
-
may_call = value.may_call
|
|
926
|
-
value = value.value
|
|
927
|
-
if may_call is None or may_call and callable(value):
|
|
928
|
-
value = await call_as_async(
|
|
929
|
-
value, may_await=may_await, threaded=threaded)()
|
|
930
|
-
elif may_await is None or may_await and isawaitable(value):
|
|
931
|
-
value = await value
|
|
932
|
-
return yield_type, value
|
|
933
|
-
async def aprocess():
|
|
934
|
-
try:
|
|
935
|
-
value = await send(None)
|
|
936
|
-
while True:
|
|
937
|
-
try:
|
|
938
|
-
yield_type, value = await aextract(value)
|
|
939
|
-
match yield_type:
|
|
940
|
-
case 0:
|
|
941
|
-
return
|
|
942
|
-
case 1:
|
|
943
|
-
yield value
|
|
944
|
-
case 2:
|
|
945
|
-
async for val in ensure_aiter(value, threaded=threaded):
|
|
946
|
-
yield val
|
|
947
|
-
except BaseException as e:
|
|
948
|
-
if isinstance(e, Reraised):
|
|
949
|
-
e = e.exception
|
|
950
|
-
value = await throw(e)
|
|
951
|
-
else:
|
|
952
|
-
value = await send(value)
|
|
953
|
-
except BaseException as e:
|
|
954
|
-
if isinstance(e, Reraised):
|
|
955
|
-
e = e.exception
|
|
956
|
-
if isinstance(e, StopIteration):
|
|
957
|
-
try:
|
|
958
|
-
yield_type, value = await aextract(e.value)
|
|
959
|
-
match yield_type:
|
|
960
|
-
case 1:
|
|
961
|
-
yield value
|
|
962
|
-
case 2:
|
|
963
|
-
async for val in ensure_aiter(value, threaded=threaded):
|
|
964
|
-
yield val
|
|
965
|
-
except BaseException as e:
|
|
966
|
-
if isinstance(e, Reraised):
|
|
967
|
-
e = e.exception
|
|
968
|
-
await throw(e)
|
|
969
|
-
else:
|
|
970
|
-
raise
|
|
971
|
-
finally:
|
|
972
|
-
await close()
|
|
973
|
-
return aprocess()
|
|
1053
|
+
return run_gen_step_async_iter(
|
|
1054
|
+
gen_step,
|
|
1055
|
+
may_await=may_await,
|
|
1056
|
+
may_call=may_call,
|
|
1057
|
+
threaded=threaded,
|
|
1058
|
+
)
|
|
974
1059
|
else:
|
|
975
|
-
|
|
976
|
-
may_call: None | bool = not simple
|
|
977
|
-
yield_type = -1
|
|
978
|
-
if isinstance(value, YieldBase):
|
|
979
|
-
yield_type = value.yield_type
|
|
980
|
-
may_call = value.may_call
|
|
981
|
-
value = value.value
|
|
982
|
-
if may_call is None or may_call and callable(value):
|
|
983
|
-
value = value()
|
|
984
|
-
return yield_type, value
|
|
985
|
-
def process():
|
|
986
|
-
try:
|
|
987
|
-
value = send(None)
|
|
988
|
-
while True:
|
|
989
|
-
try:
|
|
990
|
-
yield_type, value = extract(value)
|
|
991
|
-
match yield_type:
|
|
992
|
-
case 0:
|
|
993
|
-
return value
|
|
994
|
-
case 1:
|
|
995
|
-
yield value
|
|
996
|
-
case 2:
|
|
997
|
-
yield from value
|
|
998
|
-
except BaseException as e:
|
|
999
|
-
value = throw(e)
|
|
1000
|
-
else:
|
|
1001
|
-
value = send(value)
|
|
1002
|
-
except StopIteration as e:
|
|
1003
|
-
try:
|
|
1004
|
-
yield_type, value = extract(e.value)
|
|
1005
|
-
match yield_type:
|
|
1006
|
-
case 1:
|
|
1007
|
-
yield value
|
|
1008
|
-
case 2:
|
|
1009
|
-
yield from value
|
|
1010
|
-
case _:
|
|
1011
|
-
return value
|
|
1012
|
-
except BaseException as e:
|
|
1013
|
-
throw(e)
|
|
1014
|
-
finally:
|
|
1015
|
-
close()
|
|
1016
|
-
return process()
|
|
1060
|
+
return run_gen_step_sync_iter(gen_step, may_call=may_call)
|
|
1017
1061
|
|
|
1018
1062
|
|
|
1019
1063
|
@optional
|
|
@@ -1021,7 +1065,8 @@ def as_gen_step(
|
|
|
1021
1065
|
func: Callable,
|
|
1022
1066
|
/,
|
|
1023
1067
|
iter: bool = False,
|
|
1024
|
-
|
|
1068
|
+
may_await: bool | Literal[1] = True,
|
|
1069
|
+
may_call: bool | Literal[1] = True,
|
|
1025
1070
|
threaded: bool = False,
|
|
1026
1071
|
running_flag: None | SupportsBool | Callable[[], SupportsBool] | Callable[[], Awaitable[SupportsBool]] = None,
|
|
1027
1072
|
*,
|
|
@@ -1029,18 +1074,22 @@ def as_gen_step(
|
|
|
1029
1074
|
) -> Callable:
|
|
1030
1075
|
"""装饰器,构建一个 gen_step 函数
|
|
1031
1076
|
"""
|
|
1077
|
+
if async_ is None:
|
|
1078
|
+
async_ = _get_async()
|
|
1032
1079
|
def wrapper(*args, **kwds):
|
|
1033
1080
|
if iter:
|
|
1034
1081
|
return run_gen_step_iter(
|
|
1035
1082
|
func(*args, **kwds),
|
|
1036
|
-
|
|
1083
|
+
may_await=may_await,
|
|
1084
|
+
may_call=may_call,
|
|
1037
1085
|
threaded=threaded,
|
|
1038
1086
|
async_=async_, # type: ignore
|
|
1039
1087
|
)
|
|
1040
1088
|
else:
|
|
1041
1089
|
return run_gen_step(
|
|
1042
1090
|
func(*args, **kwds),
|
|
1043
|
-
|
|
1091
|
+
may_await=may_await,
|
|
1092
|
+
may_call=may_call,
|
|
1044
1093
|
threaded=threaded,
|
|
1045
1094
|
running_flag=running_flag,
|
|
1046
1095
|
async_=async_,
|
|
@@ -1094,29 +1143,36 @@ def bfs_gen[T](
|
|
|
1094
1143
|
def with_iter_next[T](
|
|
1095
1144
|
iterable: Iterable[T],
|
|
1096
1145
|
/,
|
|
1097
|
-
async_: Literal[False]
|
|
1146
|
+
async_: Literal[False],
|
|
1098
1147
|
) -> ContextManager[Callable[[], T]]:
|
|
1099
1148
|
...
|
|
1100
1149
|
@overload
|
|
1101
1150
|
def with_iter_next[T](
|
|
1102
|
-
iterable: AsyncIterable[T],
|
|
1151
|
+
iterable: Iterable[T] | AsyncIterable[T],
|
|
1103
1152
|
/,
|
|
1104
|
-
async_: Literal[
|
|
1153
|
+
async_: Literal[True],
|
|
1105
1154
|
) -> ContextManager[Callable[[], Awaitable[T]]]:
|
|
1106
1155
|
...
|
|
1107
1156
|
@overload
|
|
1108
1157
|
def with_iter_next[T](
|
|
1109
1158
|
iterable: Iterable[T] | AsyncIterable[T],
|
|
1110
1159
|
/,
|
|
1111
|
-
async_:
|
|
1112
|
-
) -> ContextManager[Callable[[], Awaitable[T]]]:
|
|
1160
|
+
async_: None = None,
|
|
1161
|
+
) -> ContextManager[Callable[[], T]] | ContextManager[Callable[[], Awaitable[T]]]:
|
|
1113
1162
|
...
|
|
1114
1163
|
@contextmanager
|
|
1115
1164
|
def with_iter_next[T](
|
|
1116
1165
|
iterable: Iterable[T] | AsyncIterable[T],
|
|
1117
1166
|
/,
|
|
1118
|
-
async_: Literal[False, True] =
|
|
1167
|
+
async_: None | Literal[False, True] = None,
|
|
1119
1168
|
):
|
|
1169
|
+
"""
|
|
1170
|
+
"""
|
|
1171
|
+
if async_ is None:
|
|
1172
|
+
if not isinstance(iterable, Iterable):
|
|
1173
|
+
async_ = True
|
|
1174
|
+
else:
|
|
1175
|
+
async_ = _get_async()
|
|
1120
1176
|
if async_:
|
|
1121
1177
|
get_next: Callable[[], T] | Callable[[], Awaitable[T]] = ensure_aiter(iterable).__anext__
|
|
1122
1178
|
elif isinstance(iterable, Iterable):
|
|
@@ -1140,7 +1196,7 @@ def with_iter_next[T](
|
|
|
1140
1196
|
def context[T](
|
|
1141
1197
|
func: Callable[..., T],
|
|
1142
1198
|
*ctxs: ContextManager,
|
|
1143
|
-
async_: Literal[False]
|
|
1199
|
+
async_: Literal[False],
|
|
1144
1200
|
) -> T:
|
|
1145
1201
|
...
|
|
1146
1202
|
@overload
|
|
@@ -1150,11 +1206,25 @@ def context[T](
|
|
|
1150
1206
|
async_: Literal[True],
|
|
1151
1207
|
) -> Coroutine[Any, Any, T]:
|
|
1152
1208
|
...
|
|
1209
|
+
@overload
|
|
1210
|
+
def context[T](
|
|
1211
|
+
func: Callable[..., T] | Callable[..., Awaitable[T]],
|
|
1212
|
+
*ctxs: ContextManager | AsyncContextManager,
|
|
1213
|
+
async_: None = None,
|
|
1214
|
+
) -> T | Coroutine[Any, Any, T]:
|
|
1215
|
+
...
|
|
1153
1216
|
def context[T](
|
|
1154
1217
|
func: Callable[..., T] | Callable[..., Awaitable[T]],
|
|
1155
1218
|
*ctxs: ContextManager | AsyncContextManager,
|
|
1156
|
-
async_: Literal[False, True] =
|
|
1219
|
+
async_: None | Literal[False, True] = None,
|
|
1157
1220
|
) -> T | Coroutine[Any, Any, T]:
|
|
1221
|
+
"""
|
|
1222
|
+
"""
|
|
1223
|
+
if async_ is None:
|
|
1224
|
+
if iscoroutinefunction(func):
|
|
1225
|
+
async_ = True
|
|
1226
|
+
else:
|
|
1227
|
+
async_ = _get_async()
|
|
1158
1228
|
if async_:
|
|
1159
1229
|
async def call():
|
|
1160
1230
|
args: list = []
|
|
@@ -1184,7 +1254,7 @@ def backgroud_loop(
|
|
|
1184
1254
|
/,
|
|
1185
1255
|
interval: int | float = 0.05,
|
|
1186
1256
|
*,
|
|
1187
|
-
async_: Literal[False]
|
|
1257
|
+
async_: Literal[False],
|
|
1188
1258
|
) -> ContextManager:
|
|
1189
1259
|
...
|
|
1190
1260
|
@overload
|
|
@@ -1196,13 +1266,29 @@ def backgroud_loop(
|
|
|
1196
1266
|
async_: Literal[True],
|
|
1197
1267
|
) -> AsyncContextManager:
|
|
1198
1268
|
...
|
|
1269
|
+
@overload
|
|
1270
|
+
def backgroud_loop(
|
|
1271
|
+
call: None | Callable = None,
|
|
1272
|
+
/,
|
|
1273
|
+
interval: int | float = 0.05,
|
|
1274
|
+
*,
|
|
1275
|
+
async_: None = None,
|
|
1276
|
+
) -> ContextManager | AsyncContextManager:
|
|
1277
|
+
...
|
|
1199
1278
|
def backgroud_loop(
|
|
1200
1279
|
call: None | Callable = None,
|
|
1201
1280
|
/,
|
|
1202
1281
|
interval: int | float = 0.05,
|
|
1203
1282
|
*,
|
|
1204
|
-
async_: Literal[False, True] =
|
|
1283
|
+
async_: None | Literal[False, True] = None,
|
|
1205
1284
|
) -> ContextManager | AsyncContextManager:
|
|
1285
|
+
"""
|
|
1286
|
+
"""
|
|
1287
|
+
if async_ is None:
|
|
1288
|
+
if iscoroutinefunction(call):
|
|
1289
|
+
async_ = True
|
|
1290
|
+
else:
|
|
1291
|
+
async_ = _get_async()
|
|
1206
1292
|
use_default_call = not callable(call)
|
|
1207
1293
|
if use_default_call:
|
|
1208
1294
|
start = time()
|
|
@@ -1221,6 +1307,7 @@ def backgroud_loop(
|
|
|
1221
1307
|
sleep(interval)
|
|
1222
1308
|
running = True
|
|
1223
1309
|
if async_:
|
|
1310
|
+
@asynccontextmanager
|
|
1224
1311
|
async def actx():
|
|
1225
1312
|
nonlocal running
|
|
1226
1313
|
try:
|
|
@@ -1231,8 +1318,9 @@ def backgroud_loop(
|
|
|
1231
1318
|
task.cancel()
|
|
1232
1319
|
if use_default_call:
|
|
1233
1320
|
print("\r\x1b[K", end="")
|
|
1234
|
-
return
|
|
1321
|
+
return actx()
|
|
1235
1322
|
else:
|
|
1323
|
+
@contextmanager
|
|
1236
1324
|
def ctx():
|
|
1237
1325
|
nonlocal running
|
|
1238
1326
|
try:
|
|
@@ -1241,5 +1329,5 @@ def backgroud_loop(
|
|
|
1241
1329
|
running = False
|
|
1242
1330
|
if use_default_call:
|
|
1243
1331
|
print("\r\x1b[K", end="")
|
|
1244
|
-
return
|
|
1332
|
+
return ctx()
|
|
1245
1333
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
|
2
|
+
iterutils/__init__.py,sha256=yCkEoGSY0n4E-_BvLRuoi50j4Kwuu-banqxIf-QloX4,37966
|
|
3
|
+
iterutils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
python_iterutils-0.2.2.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
|
5
|
+
python_iterutils-0.2.2.dist-info/METADATA,sha256=xWgHLL5Q8knQfbWJkn9nijnp14koK8cvm8lw-JGGGrE,1467
|
|
6
|
+
python_iterutils-0.2.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
7
|
+
python_iterutils-0.2.2.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
|
2
|
-
iterutils/__init__.py,sha256=LEkMyVkA2qLrVtJDuTXgUz0cUSexnjyEcJ0skHehf4M,38403
|
|
3
|
-
iterutils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
python_iterutils-0.2.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
|
5
|
-
python_iterutils-0.2.dist-info/METADATA,sha256=EYmtSSWyFbN7QMzuv79s2UKsPoJ3fNvr_SmLsL8SnlE,1465
|
|
6
|
-
python_iterutils-0.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
7
|
-
python_iterutils-0.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|