python-iterutils 0.0.1__py3-none-any.whl → 0.0.2.1__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 +84 -61
- {python_iterutils-0.0.1.dist-info → python_iterutils-0.0.2.1.dist-info}/METADATA +1 -1
- python_iterutils-0.0.2.1.dist-info/RECORD +7 -0
- python_iterutils-0.0.1.dist-info/RECORD +0 -7
- {python_iterutils-0.0.1.dist-info → python_iterutils-0.0.2.1.dist-info}/LICENSE +0 -0
- {python_iterutils-0.0.1.dist-info → python_iterutils-0.0.2.1.dist-info}/WHEEL +0 -0
iterutils/__init__.py
CHANGED
|
@@ -2,16 +2,19 @@
|
|
|
2
2
|
# encoding: utf-8
|
|
3
3
|
|
|
4
4
|
__author__ = "ChenyangGao <https://chenyanggao.github.io>"
|
|
5
|
-
__version__ = (0, 0,
|
|
6
|
-
__all__ = [
|
|
5
|
+
__version__ = (0, 0, 2)
|
|
6
|
+
__all__ = [
|
|
7
|
+
"iterable", "async_iterable", "foreach", "async_foreach", "through", "async_through",
|
|
8
|
+
"wrap_iter", "wrap_aiter", "acc_step", "cut_iter",
|
|
9
|
+
]
|
|
7
10
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from typing import overload, Any, Optional, TypeVar
|
|
11
|
+
from collections.abc import AsyncIterable, AsyncIterator, Callable, Iterable, Iterator
|
|
12
|
+
from typing import Any, TypeVar
|
|
11
13
|
|
|
14
|
+
from asynctools import async_zip, ensure_async, ensure_aiter
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
|
|
17
|
+
T = TypeVar("T")
|
|
15
18
|
|
|
16
19
|
|
|
17
20
|
def iterable(it, /) -> bool:
|
|
@@ -28,9 +31,77 @@ def async_iterable(it, /) -> bool:
|
|
|
28
31
|
return False
|
|
29
32
|
|
|
30
33
|
|
|
34
|
+
def foreach(func: Callable, iterable, /, *iterables):
|
|
35
|
+
if iterables:
|
|
36
|
+
for args in zip(iterable, *iterables):
|
|
37
|
+
func(*args)
|
|
38
|
+
else:
|
|
39
|
+
for arg in iterable:
|
|
40
|
+
func(arg)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
async def async_foreach(func: Callable, iterable, /, *iterables, threaded: bool = True):
|
|
44
|
+
func = ensure_async(func, threaded=threaded)
|
|
45
|
+
if iterables:
|
|
46
|
+
async for args in async_zip(iterable, *iterables, threaded=threaded):
|
|
47
|
+
await func(*args)
|
|
48
|
+
else:
|
|
49
|
+
async for arg in ensure_aiter(iterable, threaded=threaded):
|
|
50
|
+
await func(arg)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def through(it: Iterable, /):
|
|
54
|
+
for _ in it:
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
async def async_through(
|
|
59
|
+
it: Iterable | AsyncIterable,
|
|
60
|
+
/,
|
|
61
|
+
threaded: bool = True,
|
|
62
|
+
):
|
|
63
|
+
async for _ in ensure_aiter(it, threaded=threaded):
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def wrap_iter(
|
|
68
|
+
it: Iterable[T],
|
|
69
|
+
/,
|
|
70
|
+
callprev: None | Callable[[T], Any] = None,
|
|
71
|
+
callnext: None | Callable[[T], Any] = None,
|
|
72
|
+
) -> Iterator[T]:
|
|
73
|
+
if not callable(callprev):
|
|
74
|
+
callprev = None
|
|
75
|
+
if not callable(callnext):
|
|
76
|
+
callnext = None
|
|
77
|
+
for e in it:
|
|
78
|
+
if callprev:
|
|
79
|
+
callprev(e)
|
|
80
|
+
yield e
|
|
81
|
+
if callnext:
|
|
82
|
+
callnext(e)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
async def wrap_aiter(
|
|
86
|
+
it: Iterable[T] | AsyncIterable[T],
|
|
87
|
+
/,
|
|
88
|
+
callprev: None | Callable[[T], Any] = None,
|
|
89
|
+
callnext: None | Callable[[T], Any] = None,
|
|
90
|
+
threaded: bool = True,
|
|
91
|
+
) -> AsyncIterator[T]:
|
|
92
|
+
callprev = ensure_async(callprev) if callable(callprev) else None
|
|
93
|
+
callnext = ensure_async(callnext) if callable(callnext) else None
|
|
94
|
+
async for e in ensure_aiter(it, threaded=threaded):
|
|
95
|
+
if callprev:
|
|
96
|
+
await callprev(e)
|
|
97
|
+
yield e
|
|
98
|
+
if callnext:
|
|
99
|
+
await callnext(e)
|
|
100
|
+
|
|
101
|
+
|
|
31
102
|
def acc_step(
|
|
32
103
|
start: int,
|
|
33
|
-
stop:
|
|
104
|
+
stop: None | int = None,
|
|
34
105
|
step: int = 1,
|
|
35
106
|
) -> Iterator[tuple[int, int, int]]:
|
|
36
107
|
if stop is None:
|
|
@@ -43,7 +114,7 @@ def acc_step(
|
|
|
43
114
|
|
|
44
115
|
def cut_iter(
|
|
45
116
|
start: int,
|
|
46
|
-
stop:
|
|
117
|
+
stop: None | int = None,
|
|
47
118
|
step: int = 1,
|
|
48
119
|
) -> Iterator[tuple[int, int]]:
|
|
49
120
|
if stop is None:
|
|
@@ -54,56 +125,8 @@ def cut_iter(
|
|
|
54
125
|
yield stop, stop - start
|
|
55
126
|
|
|
56
127
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
async def _asyncify_iter(it, /, wait_for_thread: bool = False):
|
|
62
|
-
if wait_for_thread:
|
|
63
|
-
if isinstance(it, Generator):
|
|
64
|
-
send = it.send
|
|
65
|
-
def nextval(val):
|
|
66
|
-
try:
|
|
67
|
-
return send(val), None
|
|
68
|
-
except BaseException as e:
|
|
69
|
-
return None, e
|
|
70
|
-
else:
|
|
71
|
-
getnext = iter(it).__next__
|
|
72
|
-
def nextval(val):
|
|
73
|
-
try:
|
|
74
|
-
return getnext(), None
|
|
75
|
-
except BaseException as e:
|
|
76
|
-
return None, e
|
|
77
|
-
val = None
|
|
78
|
-
while True:
|
|
79
|
-
yield_val, exc = await to_thread(nextval, val)
|
|
80
|
-
if exc is None:
|
|
81
|
-
yield yield_val
|
|
82
|
-
elif isinstance(exc, StopIteration):
|
|
83
|
-
break
|
|
84
|
-
else:
|
|
85
|
-
raise exc
|
|
86
|
-
elif isinstance(it, Generator):
|
|
87
|
-
send = it.send
|
|
88
|
-
val = None
|
|
89
|
-
try:
|
|
90
|
-
while True:
|
|
91
|
-
val = yield send(val)
|
|
92
|
-
except StopIteration:
|
|
93
|
-
pass
|
|
94
|
-
else:
|
|
95
|
-
for val in it:
|
|
96
|
-
yield val
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
@overload
|
|
100
|
-
def asyncify_iter(it: AsyncIterable[TO], /, wait_for_thread: bool) -> AsyncIterable[TO]: ...
|
|
101
|
-
@overload
|
|
102
|
-
def asyncify_iter(it: Generator[TI, TO, Any], /, wait_for_thread: bool) -> AsyncGenerator[TI, TO]: ...
|
|
103
|
-
@overload
|
|
104
|
-
def asyncify_iter(it: Iterable[TO], /, wait_for_thread: bool) -> AsyncGenerator[Any, TO]: ...
|
|
105
|
-
def asyncify_iter(it, /, wait_for_thread: bool = False):
|
|
106
|
-
if isinstance(it, AsyncIterable):
|
|
107
|
-
return it
|
|
108
|
-
return _asyncify_iter(it, wait_for_thread=wait_for_thread)
|
|
128
|
+
async def iter_to_aiter():
|
|
129
|
+
for i in it:
|
|
130
|
+
yield i
|
|
131
|
+
|
|
109
132
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
|
2
|
+
iterutils/__init__.py,sha256=LAmaGvXXhdvqcFaTr92Fo6TpOQZb8lKYpkJEBRCxZiY,3182
|
|
3
|
+
iterutils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
python_iterutils-0.0.2.1.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
|
5
|
+
python_iterutils-0.0.2.1.dist-info/METADATA,sha256=MUJkvshBm0atNZmt37Mg3Z3ChsAANufUszjvTYDRVSs,1351
|
|
6
|
+
python_iterutils-0.0.2.1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
7
|
+
python_iterutils-0.0.2.1.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
|
2
|
-
iterutils/__init__.py,sha256=rlt5eSf9A7_58WR8dDYgS-Fe40nHMGiwurUeymnuyro,3123
|
|
3
|
-
iterutils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
python_iterutils-0.0.1.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
|
5
|
-
python_iterutils-0.0.1.dist-info/METADATA,sha256=wByxjlr3955Z05zMMiOncJ2dwkA86vHRsV72UXn2D1I,1349
|
|
6
|
-
python_iterutils-0.0.1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
7
|
-
python_iterutils-0.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|