python-iterutils 0.0.4.4__tar.gz → 0.0.5__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.0.4.4 → python_iterutils-0.0.5}/PKG-INFO +1 -1
- {python_iterutils-0.0.4.4 → python_iterutils-0.0.5}/iterutils/__init__.py +135 -8
- {python_iterutils-0.0.4.4 → python_iterutils-0.0.5}/pyproject.toml +1 -1
- {python_iterutils-0.0.4.4 → python_iterutils-0.0.5}/LICENSE +0 -0
- {python_iterutils-0.0.4.4 → python_iterutils-0.0.5}/iterutils/py.typed +0 -0
- {python_iterutils-0.0.4.4 → python_iterutils-0.0.5}/readme.md +0 -0
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
# encoding: utf-8
|
|
3
3
|
|
|
4
4
|
__author__ = "ChenyangGao <https://chenyanggao.github.io>"
|
|
5
|
-
__version__ = (0, 0,
|
|
5
|
+
__version__ = (0, 0, 5)
|
|
6
6
|
__all__ = [
|
|
7
7
|
"iterable", "async_iterable", "foreach", "async_foreach", "through", "async_through",
|
|
8
|
-
"wrap_iter", "wrap_aiter", "acc_step", "cut_iter", "run_gen_step",
|
|
8
|
+
"wrap_iter", "wrap_aiter", "acc_step", "cut_iter", "run_gen_step", "run_gen_step_iter",
|
|
9
|
+
"Yield", "YieldFrom",
|
|
9
10
|
]
|
|
10
11
|
|
|
11
12
|
from asyncio import to_thread
|
|
@@ -13,7 +14,7 @@ from collections.abc import (
|
|
|
13
14
|
AsyncIterable, AsyncIterator, Awaitable, Callable, Generator, Iterable, Iterator,
|
|
14
15
|
)
|
|
15
16
|
from inspect import isawaitable
|
|
16
|
-
from typing import Any, TypeVar
|
|
17
|
+
from typing import overload, Any, Literal, TypeVar
|
|
17
18
|
|
|
18
19
|
from asynctools import async_zip, ensure_async, ensure_aiter
|
|
19
20
|
|
|
@@ -21,6 +22,18 @@ from asynctools import async_zip, ensure_async, ensure_aiter
|
|
|
21
22
|
T = TypeVar("T")
|
|
22
23
|
|
|
23
24
|
|
|
25
|
+
class Yield:
|
|
26
|
+
|
|
27
|
+
def __init__(self, value, /):
|
|
28
|
+
self.value = value
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class YieldFrom:
|
|
32
|
+
|
|
33
|
+
def __init__(self, value, /):
|
|
34
|
+
self.value = value
|
|
35
|
+
|
|
36
|
+
|
|
24
37
|
def iterable(it, /) -> bool:
|
|
25
38
|
try:
|
|
26
39
|
return isinstance(iter(it), Iterable)
|
|
@@ -168,7 +181,7 @@ def cut_iter(
|
|
|
168
181
|
|
|
169
182
|
|
|
170
183
|
def run_gen_step(
|
|
171
|
-
gen_step: Generator[
|
|
184
|
+
gen_step: Generator[Any, Any, T] | Callable[[], Generator[Any, Any, T]],
|
|
172
185
|
*,
|
|
173
186
|
async_: bool = False,
|
|
174
187
|
threaded: bool = False,
|
|
@@ -191,9 +204,14 @@ def run_gen_step(
|
|
|
191
204
|
func = send(None)
|
|
192
205
|
while True:
|
|
193
206
|
try:
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
207
|
+
if isawaitable(func):
|
|
208
|
+
ret = await func
|
|
209
|
+
elif callable(func):
|
|
210
|
+
ret = func()
|
|
211
|
+
if isawaitable(ret):
|
|
212
|
+
ret = await ret
|
|
213
|
+
else:
|
|
214
|
+
ret = func
|
|
197
215
|
except BaseException as e:
|
|
198
216
|
if threaded:
|
|
199
217
|
func = await to_thread(throw, e)
|
|
@@ -233,7 +251,7 @@ def run_gen_step(
|
|
|
233
251
|
func = send(None)
|
|
234
252
|
while True:
|
|
235
253
|
try:
|
|
236
|
-
ret = func()
|
|
254
|
+
ret = func() if callable(func) else func
|
|
237
255
|
except BaseException as e:
|
|
238
256
|
func = throw(e)
|
|
239
257
|
else:
|
|
@@ -247,3 +265,112 @@ def run_gen_step(
|
|
|
247
265
|
if close is not None:
|
|
248
266
|
close()
|
|
249
267
|
|
|
268
|
+
|
|
269
|
+
@overload
|
|
270
|
+
def run_gen_step_iter(
|
|
271
|
+
gen_step: Generator | Callable[[], Generator],
|
|
272
|
+
threaded: bool = False,
|
|
273
|
+
*,
|
|
274
|
+
async_: Literal[False] = False,
|
|
275
|
+
) -> Iterator:
|
|
276
|
+
...
|
|
277
|
+
@overload
|
|
278
|
+
def run_gen_step_iter(
|
|
279
|
+
gen_step: Generator | Callable[[], Generator],
|
|
280
|
+
threaded: bool = False,
|
|
281
|
+
*,
|
|
282
|
+
async_: Literal[True],
|
|
283
|
+
) -> AsyncIterator:
|
|
284
|
+
...
|
|
285
|
+
def run_gen_step_iter(
|
|
286
|
+
gen_step: Generator | Callable[[], Generator],
|
|
287
|
+
threaded: bool = False,
|
|
288
|
+
*,
|
|
289
|
+
async_: bool = False,
|
|
290
|
+
) -> Iterator | AsyncIterator:
|
|
291
|
+
if callable(gen_step):
|
|
292
|
+
gen = gen_step()
|
|
293
|
+
close = gen.close
|
|
294
|
+
else:
|
|
295
|
+
gen = gen_step
|
|
296
|
+
close = None
|
|
297
|
+
send = gen.send
|
|
298
|
+
throw = gen.throw
|
|
299
|
+
if async_:
|
|
300
|
+
async def process():
|
|
301
|
+
try:
|
|
302
|
+
if threaded:
|
|
303
|
+
func = await to_thread(send, None)
|
|
304
|
+
else:
|
|
305
|
+
func = send(None)
|
|
306
|
+
while True:
|
|
307
|
+
yield_type = 0
|
|
308
|
+
if isinstance(func, Yield):
|
|
309
|
+
yield_type = 1
|
|
310
|
+
elif isinstance(func, YieldFrom):
|
|
311
|
+
yield_type = 2
|
|
312
|
+
if yield_type:
|
|
313
|
+
func = func.value
|
|
314
|
+
try:
|
|
315
|
+
if isawaitable(func):
|
|
316
|
+
ret = await func
|
|
317
|
+
elif callable(func):
|
|
318
|
+
ret = func()
|
|
319
|
+
if isawaitable(ret):
|
|
320
|
+
ret = await ret
|
|
321
|
+
else:
|
|
322
|
+
ret = func
|
|
323
|
+
except BaseException as e:
|
|
324
|
+
if threaded:
|
|
325
|
+
func = await to_thread(throw, e)
|
|
326
|
+
else:
|
|
327
|
+
func = throw(e)
|
|
328
|
+
else:
|
|
329
|
+
if yield_type == 1:
|
|
330
|
+
yield ret
|
|
331
|
+
elif yield_type == 2:
|
|
332
|
+
async for val in ensure_aiter(ret, threaded=threaded):
|
|
333
|
+
yield val
|
|
334
|
+
if threaded:
|
|
335
|
+
func = await to_thread(send, ret)
|
|
336
|
+
else:
|
|
337
|
+
func = send(ret)
|
|
338
|
+
except (StopIteration, GeneratorExit):
|
|
339
|
+
pass
|
|
340
|
+
finally:
|
|
341
|
+
if close is not None:
|
|
342
|
+
if threaded:
|
|
343
|
+
await to_thread(close)
|
|
344
|
+
else:
|
|
345
|
+
close()
|
|
346
|
+
else:
|
|
347
|
+
def process():
|
|
348
|
+
try:
|
|
349
|
+
func = send(None)
|
|
350
|
+
while True:
|
|
351
|
+
yield_type = 0
|
|
352
|
+
if isinstance(func, Yield):
|
|
353
|
+
yield_type = 1
|
|
354
|
+
elif isinstance(func, YieldFrom):
|
|
355
|
+
yield_type = 2
|
|
356
|
+
if yield_type:
|
|
357
|
+
func = func.value
|
|
358
|
+
try:
|
|
359
|
+
ret = func() if callable(func) else func
|
|
360
|
+
except BaseException as e:
|
|
361
|
+
func = throw(e)
|
|
362
|
+
else:
|
|
363
|
+
if yield_type == 1:
|
|
364
|
+
yield ret
|
|
365
|
+
elif yield_type == 2:
|
|
366
|
+
yield from ret
|
|
367
|
+
func = send(ret)
|
|
368
|
+
except StopIteration as e:
|
|
369
|
+
return e.value
|
|
370
|
+
except GeneratorExit:
|
|
371
|
+
pass
|
|
372
|
+
finally:
|
|
373
|
+
if close is not None:
|
|
374
|
+
close()
|
|
375
|
+
return process()
|
|
376
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|