python-iterutils 0.1.10__tar.gz → 0.1.11__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.1.10
3
+ Version: 0.1.11
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,7 +2,7 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 1, 10)
5
+ __version__ = (0, 1, 11)
6
6
  __all__ = [
7
7
  "Return", "Yield", "YieldFrom", "iterable", "async_iterable", "foreach", "async_foreach",
8
8
  "through", "async_through", "flatten", "async_flatten", "collect", "async_collect",
@@ -30,7 +30,7 @@ from sys import _getframe
30
30
  from _thread import start_new_thread
31
31
  from time import sleep, time
32
32
  from types import FrameType
33
- from typing import cast, overload, Any, AsyncContextManager, ContextManager, Literal
33
+ from typing import cast, overload, Any, AsyncContextManager, ContextManager, Literal, Protocol
34
34
 
35
35
  from asynctools import (
36
36
  async_filter, async_map, async_reduce, async_zip, async_batched, ensure_async, ensure_aiter,
@@ -41,6 +41,10 @@ from texttools import format_time
41
41
  from undefined import undefined, Undefined
42
42
 
43
43
 
44
+ class SupportsBool(Protocol):
45
+ def __bool__(self, /) -> bool: ...
46
+
47
+
44
48
  @dataclass(slots=True, frozen=True)
45
49
  class YieldBase(ABC):
46
50
  value: Any
@@ -778,28 +782,63 @@ async def iter_gen_step_async(
778
782
 
779
783
  def run_gen_step[T](
780
784
  gen_step: Generator | Callable[[], Generator],
785
+ threaded: bool = False,
786
+ running_flag: None | Callable[[], SupportsBool] | Callable[[], Awaitable[SupportsBool]] | SupportsBool = None,
781
787
  *,
782
788
  async_: None | bool = None,
783
- threaded: bool = False,
784
789
  ):
785
790
  if async_ is None:
786
791
  async_ = _get_async()
787
792
  if async_:
788
793
  async def process():
794
+ gen = iter_gen_step_async(gen_step, threaded=threaded)
789
795
  try:
790
- async for value in iter_gen_step_async(gen_step, threaded=threaded):
791
- pass
796
+ if running_flag is None:
797
+ async for value in gen:
798
+ pass
799
+ elif callable(running_flag):
800
+ pred = running_flag()
801
+ if not ((await pred) if isawaitable(pred) else pred):
802
+ raise RuntimeError("stop before starting", gen) from StopIteration()
803
+ async for value in gen:
804
+ pred = running_flag()
805
+ if not ((await pred) if isawaitable(pred) else pred):
806
+ raise RuntimeError("stop midway", gen) from StopIteration(value)
807
+ else:
808
+ if not running_flag:
809
+ raise RuntimeError("stop before starting", gen) from StopIteration()
810
+ async for value in gen:
811
+ if not running_flag:
812
+ raise RuntimeError("stop midway", gen) from StopIteration(value)
792
813
  return value
793
814
  except Reraised as e:
794
815
  raise e.exception
816
+ except KeyboardInterrupt as e:
817
+ e.args = gen,
818
+ e.add_note(f"stop iterating gen_step: {gen!r}")
819
+ raise
795
820
  return process()
796
821
  else:
822
+ gen = iter_gen_step(gen_step)
797
823
  try:
798
- for value in iter_gen_step(gen_step):
799
- pass
824
+ if running_flag is None:
825
+ for value in gen:
826
+ pass
827
+ else:
828
+ if not callable(running_flag):
829
+ running_flag = running_flag.__bool__
830
+ if not running_flag():
831
+ raise RuntimeError("stop before starting", gen) from StopIteration()
832
+ for value in gen:
833
+ if not running_flag():
834
+ raise RuntimeError("stop midway", gen) from StopIteration(value)
800
835
  return value
801
836
  except Reraised as e:
802
837
  raise e.exception
838
+ except KeyboardInterrupt as e:
839
+ e.args = gen,
840
+ e.add_note(f"stop iterating gen_step: {gen!r}")
841
+ raise
803
842
 
804
843
 
805
844
  @overload
@@ -946,16 +985,28 @@ def run_gen_step_iter(
946
985
  def as_gen_step(
947
986
  func: Callable,
948
987
  /,
949
- async_: None | bool = None,
950
988
  iter: bool = False,
989
+ threaded: bool = False,
990
+ running_flag: None | Callable[[], SupportsBool] | Callable[[], Awaitable[SupportsBool]] | SupportsBool = None,
991
+ *,
992
+ async_: None | bool = None,
951
993
  ) -> Callable:
952
994
  if async_ is None:
953
995
  async_ = _get_async()
954
996
  def wrapper(*args, **kwds):
955
997
  if iter:
956
- return run_gen_step_iter(func(*args, **kwds), async_=async_) # type: ignore
998
+ return run_gen_step_iter(
999
+ func(*args, **kwds),
1000
+ threaded=threaded,
1001
+ async_=async_, # type: ignore
1002
+ )
957
1003
  else:
958
- return run_gen_step(func(*args, **kwds), async_=async_)
1004
+ return run_gen_step(
1005
+ func(*args, **kwds),
1006
+ threaded=threaded,
1007
+ running_flag=running_flag,
1008
+ async_=async_,
1009
+ )
959
1010
  return wrapper
960
1011
 
961
1012
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-iterutils"
3
- version = "0.1.10"
3
+ version = "0.1.11"
4
4
  description = "Python another itertools."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"