python-iterutils 0.1.7__tar.gz → 0.1.9__tar.gz
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.
- {python_iterutils-0.1.7 → python_iterutils-0.1.9}/PKG-INFO +2 -2
- {python_iterutils-0.1.7 → python_iterutils-0.1.9}/iterutils/__init__.py +318 -126
- {python_iterutils-0.1.7 → python_iterutils-0.1.9}/pyproject.toml +2 -2
- {python_iterutils-0.1.7 → python_iterutils-0.1.9}/LICENSE +0 -0
- {python_iterutils-0.1.7 → python_iterutils-0.1.9}/iterutils/py.typed +0 -0
- {python_iterutils-0.1.7 → python_iterutils-0.1.9}/readme.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-iterutils
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9
|
|
4
4
|
Summary: Python another itertools.
|
|
5
5
|
Home-page: https://github.com/ChenyangGao/web-mount-packs/tree/main/python-module/python-iterutils
|
|
6
6
|
License: MIT
|
|
@@ -20,7 +20,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
20
20
|
Classifier: Topic :: Software Development
|
|
21
21
|
Classifier: Topic :: Software Development :: Libraries
|
|
22
22
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
-
Requires-Dist: python-asynctools (>=0.
|
|
23
|
+
Requires-Dist: python-asynctools (>=0.1.2)
|
|
24
24
|
Requires-Dist: python-decotools (>=0.0.2)
|
|
25
25
|
Requires-Dist: python-texttools (>=0.0.3)
|
|
26
26
|
Requires-Dist: python-undefined (>=0.0.3)
|
|
@@ -2,24 +2,27 @@
|
|
|
2
2
|
# encoding: utf-8
|
|
3
3
|
|
|
4
4
|
__author__ = "ChenyangGao <https://chenyanggao.github.io>"
|
|
5
|
-
__version__ = (0, 1,
|
|
5
|
+
__version__ = (0, 1, 9)
|
|
6
6
|
__all__ = [
|
|
7
7
|
"Return", "Yield", "YieldFrom", "iterable", "async_iterable", "foreach", "async_foreach",
|
|
8
|
-
"through", "async_through", "flatten", "async_flatten", "
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
8
|
+
"through", "async_through", "flatten", "async_flatten", "collect", "async_collect",
|
|
9
|
+
"group_collect", "async_group_collect", "map", "filter", "reduce", "zip", "chunked",
|
|
10
|
+
"iter_unique", "async_iter_unique", "wrap_iter", "wrap_aiter", "acc_step", "cut_iter",
|
|
11
|
+
"iter_gen_step", "iter_gen_step_async", "run_gen_step", "run_gen_step_iter",
|
|
12
|
+
"as_gen_step", "bfs_gen", "with_iter_next", "backgroud_loop",
|
|
12
13
|
]
|
|
13
14
|
|
|
14
15
|
from abc import ABC, abstractmethod
|
|
15
16
|
from asyncio import create_task, sleep as async_sleep, to_thread
|
|
16
17
|
from builtins import map as _map, filter as _filter, zip as _zip
|
|
17
|
-
from collections import deque
|
|
18
|
+
from collections import defaultdict, deque
|
|
18
19
|
from collections.abc import (
|
|
19
|
-
AsyncIterable, AsyncIterator, Awaitable, Buffer, Callable,
|
|
20
|
-
Iterable, Iterator,
|
|
20
|
+
AsyncIterable, AsyncIterator, Awaitable, Buffer, Callable, Collection, Container,
|
|
21
|
+
Coroutine, Generator, Iterable, Iterator, Mapping, MutableMapping, MutableSet,
|
|
22
|
+
MutableSequence, Sequence, ValuesView,
|
|
21
23
|
)
|
|
22
24
|
from contextlib import asynccontextmanager, contextmanager, ExitStack, AsyncExitStack
|
|
25
|
+
from copy import copy
|
|
23
26
|
from dataclasses import dataclass
|
|
24
27
|
from itertools import batched, pairwise
|
|
25
28
|
from inspect import isawaitable, iscoroutinefunction
|
|
@@ -27,10 +30,11 @@ from sys import _getframe
|
|
|
27
30
|
from _thread import start_new_thread
|
|
28
31
|
from time import sleep, time
|
|
29
32
|
from types import FrameType
|
|
30
|
-
from typing import overload, Any, AsyncContextManager, ContextManager, Literal
|
|
33
|
+
from typing import cast, overload, Any, AsyncContextManager, ContextManager, Literal
|
|
31
34
|
|
|
32
35
|
from asynctools import (
|
|
33
36
|
async_filter, async_map, async_reduce, async_zip, async_batched, ensure_async, ensure_aiter,
|
|
37
|
+
collect as async_collect,
|
|
34
38
|
)
|
|
35
39
|
from decotools import optional
|
|
36
40
|
from texttools import format_time
|
|
@@ -49,6 +53,12 @@ class YieldBase(ABC):
|
|
|
49
53
|
...
|
|
50
54
|
|
|
51
55
|
|
|
56
|
+
class Reraised(BaseException):
|
|
57
|
+
|
|
58
|
+
def __init__(self, exc: BaseException, /):
|
|
59
|
+
self.exception = exc
|
|
60
|
+
|
|
61
|
+
|
|
52
62
|
class Return(YieldBase):
|
|
53
63
|
yield_type = 0
|
|
54
64
|
|
|
@@ -96,7 +106,7 @@ async def async_foreach(
|
|
|
96
106
|
iterable: Iterable | AsyncIterable,
|
|
97
107
|
/,
|
|
98
108
|
*iterables: Iterable | AsyncIterable,
|
|
99
|
-
threaded: bool =
|
|
109
|
+
threaded: bool = False,
|
|
100
110
|
):
|
|
101
111
|
value = ensure_async(value, threaded=threaded)
|
|
102
112
|
if iterables:
|
|
@@ -127,7 +137,7 @@ async def async_through(
|
|
|
127
137
|
iterable: Iterable | AsyncIterable,
|
|
128
138
|
/,
|
|
129
139
|
take_while: None | Callable = None,
|
|
130
|
-
threaded: bool =
|
|
140
|
+
threaded: bool = False,
|
|
131
141
|
):
|
|
132
142
|
iterable = ensure_aiter(iterable, threaded=threaded)
|
|
133
143
|
if take_while is None:
|
|
@@ -177,7 +187,7 @@ async def async_flatten(
|
|
|
177
187
|
iterable: Iterable | AsyncIterable,
|
|
178
188
|
/,
|
|
179
189
|
exclude_types: type | tuple[type, ...] = (Buffer, str),
|
|
180
|
-
threaded: bool =
|
|
190
|
+
threaded: bool = False,
|
|
181
191
|
) -> AsyncIterator:
|
|
182
192
|
async for e in ensure_aiter(iterable, threaded=threaded):
|
|
183
193
|
if isinstance(e, (Iterable, AsyncIterable)) and not isinstance(e, exclude_types):
|
|
@@ -187,6 +197,168 @@ async def async_flatten(
|
|
|
187
197
|
yield e
|
|
188
198
|
|
|
189
199
|
|
|
200
|
+
@overload
|
|
201
|
+
def collect[K, V](
|
|
202
|
+
iterable: Iterable[tuple[K, V]] | Mapping[K, V],
|
|
203
|
+
/,
|
|
204
|
+
rettype: Callable[[Iterable[tuple[K, V]]], MutableMapping[K, V]],
|
|
205
|
+
) -> MutableMapping[K, V]:
|
|
206
|
+
...
|
|
207
|
+
@overload
|
|
208
|
+
def collect[T](
|
|
209
|
+
iterable: Iterable[T],
|
|
210
|
+
/,
|
|
211
|
+
rettype: Callable[[Iterable[T]], Collection[T]] = list,
|
|
212
|
+
) -> Collection[T]:
|
|
213
|
+
...
|
|
214
|
+
@overload
|
|
215
|
+
def collect[K, V](
|
|
216
|
+
iterable: AsyncIterable[tuple[K, V]],
|
|
217
|
+
/,
|
|
218
|
+
rettype: Callable[[Iterable[tuple[K, V]]], MutableMapping[K, V]],
|
|
219
|
+
) -> Coroutine[Any, Any, MutableMapping[K, V]]:
|
|
220
|
+
...
|
|
221
|
+
@overload
|
|
222
|
+
def collect[T](
|
|
223
|
+
iterable: AsyncIterable[T],
|
|
224
|
+
/,
|
|
225
|
+
rettype: Callable[[Iterable[T]], Collection[T]] = list,
|
|
226
|
+
) -> Coroutine[Any, Any, Collection[T]]:
|
|
227
|
+
...
|
|
228
|
+
def collect(
|
|
229
|
+
iterable: Iterable | AsyncIterable | Mapping,
|
|
230
|
+
/,
|
|
231
|
+
rettype: Callable[[Iterable], Collection] = list,
|
|
232
|
+
) -> Collection | Coroutine[Any, Any, Collection]:
|
|
233
|
+
if not isinstance(iterable, Iterable):
|
|
234
|
+
return async_collect(iterable, rettype)
|
|
235
|
+
return rettype(iterable)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
@overload
|
|
239
|
+
def group_collect[K, V, C: Container](
|
|
240
|
+
iterable: Iterable[tuple[K, V]],
|
|
241
|
+
mapping: None = None,
|
|
242
|
+
factory: None | C | Callable[[], C] = None,
|
|
243
|
+
) -> dict[K, C]:
|
|
244
|
+
...
|
|
245
|
+
@overload
|
|
246
|
+
def group_collect[K, V, C: Container, M: MutableMapping](
|
|
247
|
+
iterable: Iterable[tuple[K, V]],
|
|
248
|
+
mapping: M,
|
|
249
|
+
factory: None | C | Callable[[], C] = None,
|
|
250
|
+
) -> M:
|
|
251
|
+
...
|
|
252
|
+
@overload
|
|
253
|
+
def group_collect[K, V, C: Container](
|
|
254
|
+
iterable: AsyncIterable[tuple[K, V]],
|
|
255
|
+
mapping: None = None,
|
|
256
|
+
factory: None | C | Callable[[], C] = None,
|
|
257
|
+
) -> Coroutine[Any, Any, dict[K, C]]:
|
|
258
|
+
...
|
|
259
|
+
@overload
|
|
260
|
+
def group_collect[K, V, C: Container, M: MutableMapping](
|
|
261
|
+
iterable: AsyncIterable[tuple[K, V]],
|
|
262
|
+
mapping: M,
|
|
263
|
+
factory: None | C | Callable[[], C] = None,
|
|
264
|
+
) -> Coroutine[Any, Any, M]:
|
|
265
|
+
...
|
|
266
|
+
def group_collect[K, V, C: Container, M: MutableMapping](
|
|
267
|
+
iterable: Iterable[tuple[K, V]] | AsyncIterable[tuple[K, V]],
|
|
268
|
+
mapping: None | M = None,
|
|
269
|
+
factory: None | C | Callable[[], C] = None,
|
|
270
|
+
) -> dict[K, C] | M | Coroutine[Any, Any, dict[K, C]] | Coroutine[Any, Any, M]:
|
|
271
|
+
if not isinstance(iterable, Iterable):
|
|
272
|
+
return async_group_collect(iterable, mapping, factory)
|
|
273
|
+
if factory is None:
|
|
274
|
+
if isinstance(mapping, defaultdict):
|
|
275
|
+
factory = mapping.default_factory
|
|
276
|
+
elif mapping:
|
|
277
|
+
factory = type(next(iter(ValuesView(mapping))))
|
|
278
|
+
else:
|
|
279
|
+
factory = cast(type[C], list)
|
|
280
|
+
elif callable(factory):
|
|
281
|
+
pass
|
|
282
|
+
elif isinstance(factory, Container):
|
|
283
|
+
factory = cast(Callable[[], C], lambda _obj=factory: copy(_obj))
|
|
284
|
+
else:
|
|
285
|
+
raise ValueError("can't determine factory")
|
|
286
|
+
factory = cast(Callable[[], C], factory)
|
|
287
|
+
if isinstance(factory, type):
|
|
288
|
+
factory_type = factory
|
|
289
|
+
else:
|
|
290
|
+
factory_type = type(factory())
|
|
291
|
+
if issubclass(factory_type, MutableSequence):
|
|
292
|
+
add = getattr(factory_type, "append")
|
|
293
|
+
else:
|
|
294
|
+
add = getattr(factory_type, "add")
|
|
295
|
+
if mapping is None:
|
|
296
|
+
mapping = cast(M, {})
|
|
297
|
+
for k, v in iterable:
|
|
298
|
+
try:
|
|
299
|
+
c = mapping[k]
|
|
300
|
+
except LookupError:
|
|
301
|
+
c = mapping[k] = factory()
|
|
302
|
+
add(c, v)
|
|
303
|
+
return mapping
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
@overload
|
|
307
|
+
async def async_group_collect[K, V, C: Container](
|
|
308
|
+
iterable: Iterable[tuple[K, V]] | AsyncIterable[tuple[K, V]],
|
|
309
|
+
mapping: None = None,
|
|
310
|
+
factory: None | C | Callable[[], C] = None,
|
|
311
|
+
threaded: bool = False,
|
|
312
|
+
) -> dict[K, C]:
|
|
313
|
+
...
|
|
314
|
+
@overload
|
|
315
|
+
async def async_group_collect[K, V, C: Container, M: MutableMapping](
|
|
316
|
+
iterable: Iterable[tuple[K, V]] | AsyncIterable[tuple[K, V]],
|
|
317
|
+
mapping: M,
|
|
318
|
+
factory: None | C | Callable[[], C] = None,
|
|
319
|
+
threaded: bool = False,
|
|
320
|
+
) -> M:
|
|
321
|
+
...
|
|
322
|
+
async def async_group_collect[K, V, C: Container, M: MutableMapping](
|
|
323
|
+
iterable: Iterable[tuple[K, V]] | AsyncIterable[tuple[K, V]],
|
|
324
|
+
mapping: None | M = None,
|
|
325
|
+
factory: None | C | Callable[[], C] = None,
|
|
326
|
+
threaded: bool = False,
|
|
327
|
+
) -> dict[K, C] | M:
|
|
328
|
+
iterable = ensure_aiter(iterable, threaded=threaded)
|
|
329
|
+
if factory is None:
|
|
330
|
+
if isinstance(mapping, defaultdict):
|
|
331
|
+
factory = mapping.default_factory
|
|
332
|
+
elif mapping:
|
|
333
|
+
factory = type(next(iter(ValuesView(mapping))))
|
|
334
|
+
else:
|
|
335
|
+
factory = cast(type[C], list)
|
|
336
|
+
elif callable(factory):
|
|
337
|
+
pass
|
|
338
|
+
elif isinstance(factory, Container):
|
|
339
|
+
factory = cast(Callable[[], C], lambda _obj=factory: copy(_obj))
|
|
340
|
+
else:
|
|
341
|
+
raise ValueError("can't determine factory")
|
|
342
|
+
factory = cast(Callable[[], C], factory)
|
|
343
|
+
if isinstance(factory, type):
|
|
344
|
+
factory_type = factory
|
|
345
|
+
else:
|
|
346
|
+
factory_type = type(factory())
|
|
347
|
+
if issubclass(factory_type, MutableSequence):
|
|
348
|
+
add = getattr(factory_type, "append")
|
|
349
|
+
else:
|
|
350
|
+
add = getattr(factory_type, "add")
|
|
351
|
+
if mapping is None:
|
|
352
|
+
mapping = cast(M, {})
|
|
353
|
+
async for k, v in iterable:
|
|
354
|
+
try:
|
|
355
|
+
c = mapping[k]
|
|
356
|
+
except LookupError:
|
|
357
|
+
c = mapping[k] = factory()
|
|
358
|
+
add(c, v)
|
|
359
|
+
return mapping
|
|
360
|
+
|
|
361
|
+
|
|
190
362
|
def map(
|
|
191
363
|
function: None | Callable,
|
|
192
364
|
iterable: Iterable | AsyncIterable,
|
|
@@ -400,7 +572,7 @@ async def wrap_aiter[T](
|
|
|
400
572
|
callnext: None | Callable[[T], Any] = None,
|
|
401
573
|
callenter: None | Callable[[Iterable[T] | AsyncIterable[T]], Any] = None,
|
|
402
574
|
callexit: None | Callable[[Iterable[T] | AsyncIterable[T], None | BaseException], Any] = None,
|
|
403
|
-
threaded: bool =
|
|
575
|
+
threaded: bool = False,
|
|
404
576
|
) -> AsyncIterator[T]:
|
|
405
577
|
callprev = ensure_async(callprev, threaded=threaded) if callable(callprev) else None
|
|
406
578
|
callnext = ensure_async(callnext, threaded=threaded) if callable(callnext) else None
|
|
@@ -471,110 +643,124 @@ def _get_async(back: int = 2) -> bool:
|
|
|
471
643
|
return False
|
|
472
644
|
|
|
473
645
|
|
|
474
|
-
def
|
|
475
|
-
gen_step: Generator
|
|
476
|
-
|
|
477
|
-
async_: None | bool = None,
|
|
478
|
-
threaded: bool = False,
|
|
479
|
-
as_iter: bool = False,
|
|
480
|
-
) -> T:
|
|
481
|
-
if async_ is None:
|
|
482
|
-
async_ = _get_async()
|
|
646
|
+
def iter_gen_step(
|
|
647
|
+
gen_step: Generator | Callable[[], Generator],
|
|
648
|
+
):
|
|
483
649
|
if callable(gen_step):
|
|
484
650
|
gen = gen_step()
|
|
485
|
-
close = gen.close
|
|
486
651
|
else:
|
|
487
652
|
gen = gen_step
|
|
488
|
-
close = None
|
|
489
653
|
send = gen.send
|
|
490
654
|
throw = gen.throw
|
|
491
|
-
|
|
492
|
-
|
|
655
|
+
close = gen.close
|
|
656
|
+
try:
|
|
657
|
+
value = send(None)
|
|
658
|
+
while True:
|
|
659
|
+
if isinstance(value, YieldBase):
|
|
660
|
+
raise StopIteration(value)
|
|
661
|
+
try:
|
|
662
|
+
if callable(value):
|
|
663
|
+
value = value()
|
|
664
|
+
except BaseException as e:
|
|
665
|
+
value = throw(e)
|
|
666
|
+
else:
|
|
667
|
+
value = send(value)
|
|
668
|
+
yield value
|
|
669
|
+
except StopIteration as e:
|
|
670
|
+
value = e.value
|
|
671
|
+
try_call_me = True
|
|
672
|
+
if isinstance(value, YieldBase):
|
|
673
|
+
try_call_me = value.try_call_me
|
|
674
|
+
value = value.value
|
|
675
|
+
if callable(value) and try_call_me:
|
|
676
|
+
try:
|
|
677
|
+
value = value()
|
|
678
|
+
except BaseException as e:
|
|
679
|
+
try:
|
|
680
|
+
value = throw(e)
|
|
681
|
+
except BaseException as e:
|
|
682
|
+
raise Reraised(e) from e
|
|
683
|
+
yield value
|
|
684
|
+
finally:
|
|
685
|
+
close()
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
async def iter_gen_step_async(
|
|
689
|
+
gen_step: Generator | Callable[[], Generator],
|
|
690
|
+
threaded: bool = False,
|
|
691
|
+
):
|
|
692
|
+
if callable(gen_step):
|
|
693
|
+
gen = gen_step()
|
|
694
|
+
else:
|
|
695
|
+
gen = gen_step
|
|
696
|
+
send = ensure_async(gen.send, threaded=threaded)
|
|
697
|
+
throw = ensure_async(gen.throw, threaded=threaded)
|
|
698
|
+
close = ensure_async(gen.close, threaded=threaded)
|
|
699
|
+
try:
|
|
700
|
+
value = await send(None)
|
|
701
|
+
while True:
|
|
702
|
+
if isinstance(value, YieldBase):
|
|
703
|
+
raise StopIteration(value)
|
|
493
704
|
try:
|
|
705
|
+
if callable(value):
|
|
706
|
+
value = await ensure_async(value, threaded=threaded)()
|
|
707
|
+
except BaseException as e:
|
|
708
|
+
value = await throw(e)
|
|
709
|
+
else:
|
|
710
|
+
value = await send(value)
|
|
711
|
+
yield value
|
|
712
|
+
except StopIteration as e:
|
|
713
|
+
value = e.value
|
|
714
|
+
identity = False
|
|
715
|
+
try_call_me = True
|
|
716
|
+
if isinstance(value, YieldBase):
|
|
717
|
+
identity = value.identity
|
|
718
|
+
try_call_me = value.try_call_me
|
|
719
|
+
value = value.value
|
|
720
|
+
try:
|
|
721
|
+
if callable(value) and try_call_me:
|
|
494
722
|
if threaded:
|
|
495
|
-
value = await to_thread(
|
|
723
|
+
value = await to_thread(value)
|
|
496
724
|
else:
|
|
497
|
-
value = send(None)
|
|
498
|
-
while True:
|
|
499
|
-
if isinstance(value, YieldBase):
|
|
500
|
-
raise StopIteration(value)
|
|
501
|
-
try:
|
|
502
|
-
if callable(value):
|
|
503
|
-
value = value()
|
|
504
|
-
if isawaitable(value):
|
|
505
|
-
value = await value
|
|
506
|
-
except BaseException as e:
|
|
507
|
-
if threaded:
|
|
508
|
-
value = await to_thread(throw, e)
|
|
509
|
-
else:
|
|
510
|
-
value = throw(e)
|
|
511
|
-
else:
|
|
512
|
-
if threaded:
|
|
513
|
-
value = await to_thread(send, value)
|
|
514
|
-
else:
|
|
515
|
-
value = send(value)
|
|
516
|
-
except StopIteration as e:
|
|
517
|
-
value = e.value
|
|
518
|
-
identity = False
|
|
519
|
-
try_call_me = True
|
|
520
|
-
if isinstance(value, YieldBase):
|
|
521
|
-
identity = value.identity
|
|
522
|
-
try_call_me = value.try_call_me
|
|
523
|
-
value = value.value
|
|
524
|
-
if callable(value) and try_call_me:
|
|
525
725
|
value = value()
|
|
526
|
-
|
|
527
|
-
|
|
726
|
+
if not identity and isawaitable(value):
|
|
727
|
+
value = await value
|
|
728
|
+
except BaseException as e:
|
|
729
|
+
try:
|
|
730
|
+
value = await throw(e)
|
|
731
|
+
except BaseException as e:
|
|
732
|
+
raise Reraised(e) from e
|
|
733
|
+
yield value
|
|
734
|
+
except StopAsyncIteration as e:
|
|
735
|
+
raise Reraised(e) from e
|
|
736
|
+
finally:
|
|
737
|
+
await close()
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
def run_gen_step[T](
|
|
741
|
+
gen_step: Generator | Callable[[], Generator],
|
|
742
|
+
*,
|
|
743
|
+
async_: None | bool = None,
|
|
744
|
+
threaded: bool = False,
|
|
745
|
+
):
|
|
746
|
+
if async_ is None:
|
|
747
|
+
async_ = _get_async()
|
|
748
|
+
if async_:
|
|
749
|
+
async def process():
|
|
750
|
+
try:
|
|
751
|
+
async for value in iter_gen_step_async(gen_step, threaded=threaded):
|
|
752
|
+
pass
|
|
528
753
|
return value
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
await to_thread(close)
|
|
533
|
-
else:
|
|
534
|
-
close()
|
|
535
|
-
result = process()
|
|
536
|
-
if as_iter:
|
|
537
|
-
async def wrap(result):
|
|
538
|
-
iterable = await result
|
|
539
|
-
try:
|
|
540
|
-
iterable = aiter(iterable)
|
|
541
|
-
except TypeError:
|
|
542
|
-
for val in iter(iterable):
|
|
543
|
-
if isawaitable(val):
|
|
544
|
-
val = await val
|
|
545
|
-
yield val
|
|
546
|
-
else:
|
|
547
|
-
async for val in iterable:
|
|
548
|
-
yield val
|
|
549
|
-
result = wrap(result)
|
|
550
|
-
return result
|
|
754
|
+
except Reraised as e:
|
|
755
|
+
raise e.exception
|
|
756
|
+
return process()
|
|
551
757
|
else:
|
|
552
758
|
try:
|
|
553
|
-
value
|
|
554
|
-
|
|
555
|
-
if isinstance(value, YieldBase):
|
|
556
|
-
raise StopIteration(value)
|
|
557
|
-
try:
|
|
558
|
-
if callable(value):
|
|
559
|
-
value = value()
|
|
560
|
-
except BaseException as e:
|
|
561
|
-
value = throw(e)
|
|
562
|
-
else:
|
|
563
|
-
value = send(value)
|
|
564
|
-
except StopIteration as e:
|
|
565
|
-
value = e.value
|
|
566
|
-
try_call_me = True
|
|
567
|
-
if isinstance(value, YieldBase):
|
|
568
|
-
try_call_me = value.try_call_me
|
|
569
|
-
value = value.value
|
|
570
|
-
if callable(value) and try_call_me:
|
|
571
|
-
value = value()
|
|
572
|
-
if as_iter:
|
|
573
|
-
value = iter(value)
|
|
759
|
+
for value in iter_gen_step(gen_step):
|
|
760
|
+
pass
|
|
574
761
|
return value
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
close()
|
|
762
|
+
except Reraised as e:
|
|
763
|
+
raise e.exception
|
|
578
764
|
|
|
579
765
|
|
|
580
766
|
@overload
|
|
@@ -611,12 +797,11 @@ def run_gen_step_iter(
|
|
|
611
797
|
async_ = _get_async()
|
|
612
798
|
if callable(gen_step):
|
|
613
799
|
gen = gen_step()
|
|
614
|
-
close = gen.close
|
|
615
800
|
else:
|
|
616
801
|
gen = gen_step
|
|
617
|
-
close = None
|
|
618
802
|
send = gen.send
|
|
619
803
|
throw = gen.throw
|
|
804
|
+
close = gen.close
|
|
620
805
|
if async_:
|
|
621
806
|
async def process():
|
|
622
807
|
async def extract(value):
|
|
@@ -658,19 +843,24 @@ def run_gen_step_iter(
|
|
|
658
843
|
else:
|
|
659
844
|
value = send(value)
|
|
660
845
|
except StopIteration as e:
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
846
|
+
try:
|
|
847
|
+
yield_type, value = await extract(e.value)
|
|
848
|
+
match yield_type:
|
|
849
|
+
case 1:
|
|
850
|
+
yield value
|
|
851
|
+
case 2:
|
|
852
|
+
async for val in ensure_aiter(value, threaded=threaded):
|
|
853
|
+
yield val
|
|
854
|
+
except BaseException as e:
|
|
670
855
|
if threaded:
|
|
671
|
-
await to_thread(
|
|
856
|
+
await to_thread(throw, e)
|
|
672
857
|
else:
|
|
673
|
-
|
|
858
|
+
throw(e)
|
|
859
|
+
finally:
|
|
860
|
+
if threaded:
|
|
861
|
+
await to_thread(close)
|
|
862
|
+
else:
|
|
863
|
+
close()
|
|
674
864
|
else:
|
|
675
865
|
def process():
|
|
676
866
|
def extract(value, /):
|
|
@@ -700,17 +890,19 @@ def run_gen_step_iter(
|
|
|
700
890
|
else:
|
|
701
891
|
value = send(value)
|
|
702
892
|
except StopIteration as e:
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
893
|
+
try:
|
|
894
|
+
yield_type, value = extract(e.value)
|
|
895
|
+
match yield_type:
|
|
896
|
+
case 1:
|
|
897
|
+
yield value
|
|
898
|
+
case 2:
|
|
899
|
+
yield from value
|
|
900
|
+
case _:
|
|
901
|
+
return value
|
|
902
|
+
except BaseException as e:
|
|
903
|
+
throw(e)
|
|
711
904
|
finally:
|
|
712
|
-
|
|
713
|
-
close()
|
|
905
|
+
close()
|
|
714
906
|
return process()
|
|
715
907
|
|
|
716
908
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "python-iterutils"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.9"
|
|
4
4
|
description = "Python another itertools."
|
|
5
5
|
authors = ["ChenyangGao <wosiwujm@gmail.com>"]
|
|
6
6
|
license = "MIT"
|
|
@@ -27,7 +27,7 @@ include = [
|
|
|
27
27
|
|
|
28
28
|
[tool.poetry.dependencies]
|
|
29
29
|
python = "^3.12"
|
|
30
|
-
python-asynctools = ">=0.
|
|
30
|
+
python-asynctools = ">=0.1.2"
|
|
31
31
|
python-decotools = ">=0.0.2"
|
|
32
32
|
python-texttools = ">=0.0.3"
|
|
33
33
|
python-undefined = ">=0.0.3"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|