python-iterutils 0.0.4.5__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-iterutils
3
- Version: 0.0.4.5
3
+ Version: 0.0.5
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
@@ -2,10 +2,11 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 0, 4)
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)
@@ -238,7 +251,7 @@ def run_gen_step(
238
251
  func = send(None)
239
252
  while True:
240
253
  try:
241
- ret = func() if callable(func) else ret
254
+ ret = func() if callable(func) else func
242
255
  except BaseException as e:
243
256
  func = throw(e)
244
257
  else:
@@ -252,3 +265,112 @@ def run_gen_step(
252
265
  if close is not None:
253
266
  close()
254
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
+
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-iterutils"
3
- version = "0.0.4.5"
3
+ version = "0.0.5"
4
4
  description = "Python another itertools."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"