python-iterutils 0.1.8__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-iterutils
3
- Version: 0.1.8
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.0.10.1)
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,13 +2,14 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  __author__ = "ChenyangGao <https://chenyanggao.github.io>"
5
- __version__ = (0, 1, 8)
5
+ __version__ = (0, 1, 9)
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",
9
9
  "group_collect", "async_group_collect", "map", "filter", "reduce", "zip", "chunked",
10
10
  "iter_unique", "async_iter_unique", "wrap_iter", "wrap_aiter", "acc_step", "cut_iter",
11
- "run_gen_step", "run_gen_step_iter", "as_gen_step", "bfs_gen", "with_iter_next", "backgroud_loop",
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
@@ -52,6 +53,12 @@ class YieldBase(ABC):
52
53
  ...
53
54
 
54
55
 
56
+ class Reraised(BaseException):
57
+
58
+ def __init__(self, exc: BaseException, /):
59
+ self.exception = exc
60
+
61
+
55
62
  class Return(YieldBase):
56
63
  yield_type = 0
57
64
 
@@ -636,110 +643,124 @@ def _get_async(back: int = 2) -> bool:
636
643
  return False
637
644
 
638
645
 
639
- def run_gen_step[T](
640
- gen_step: Generator[Any, Any, T] | Callable[[], Generator[Any, Any, T]],
641
- *,
642
- async_: None | bool = None,
643
- threaded: bool = False,
644
- as_iter: bool = False,
645
- ) -> T:
646
- if async_ is None:
647
- async_ = _get_async()
646
+ def iter_gen_step(
647
+ gen_step: Generator | Callable[[], Generator],
648
+ ):
648
649
  if callable(gen_step):
649
650
  gen = gen_step()
650
- close = gen.close
651
651
  else:
652
652
  gen = gen_step
653
- close = None
654
653
  send = gen.send
655
654
  throw = gen.throw
656
- if async_:
657
- async def process():
655
+ close = gen.close
656
+ try:
657
+ value = send(None)
658
+ while True:
659
+ if isinstance(value, YieldBase):
660
+ raise StopIteration(value)
658
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)
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:
659
722
  if threaded:
660
- value = await to_thread(send, None)
723
+ value = await to_thread(value)
661
724
  else:
662
- value = send(None)
663
- while True:
664
- if isinstance(value, YieldBase):
665
- raise StopIteration(value)
666
- try:
667
- if callable(value):
668
- value = value()
669
- if isawaitable(value):
670
- value = await value
671
- except BaseException as e:
672
- if threaded:
673
- value = await to_thread(throw, e)
674
- else:
675
- value = throw(e)
676
- else:
677
- if threaded:
678
- value = await to_thread(send, value)
679
- else:
680
- value = send(value)
681
- except StopIteration as e:
682
- value = e.value
683
- identity = False
684
- try_call_me = True
685
- if isinstance(value, YieldBase):
686
- identity = value.identity
687
- try_call_me = value.try_call_me
688
- value = value.value
689
- if callable(value) and try_call_me:
690
725
  value = value()
691
- if not identity and isawaitable(value):
692
- value = await value
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
693
753
  return value
694
- finally:
695
- if close is not None:
696
- if threaded:
697
- await to_thread(close)
698
- else:
699
- close()
700
- result = process()
701
- if as_iter:
702
- async def wrap(result):
703
- iterable = await result
704
- try:
705
- iterable = aiter(iterable)
706
- except TypeError:
707
- for val in iter(iterable):
708
- if isawaitable(val):
709
- val = await val
710
- yield val
711
- else:
712
- async for val in iterable:
713
- yield val
714
- result = wrap(result)
715
- return result
754
+ except Reraised as e:
755
+ raise e.exception
756
+ return process()
716
757
  else:
717
758
  try:
718
- value = send(None)
719
- while True:
720
- if isinstance(value, YieldBase):
721
- raise StopIteration(value)
722
- try:
723
- if callable(value):
724
- value = value()
725
- except BaseException as e:
726
- value = throw(e)
727
- else:
728
- value = send(value)
729
- except StopIteration as e:
730
- value = e.value
731
- try_call_me = True
732
- if isinstance(value, YieldBase):
733
- try_call_me = value.try_call_me
734
- value = value.value
735
- if callable(value) and try_call_me:
736
- value = value()
737
- if as_iter:
738
- value = iter(value)
759
+ for value in iter_gen_step(gen_step):
760
+ pass
739
761
  return value
740
- finally:
741
- if close is not None:
742
- close()
762
+ except Reraised as e:
763
+ raise e.exception
743
764
 
744
765
 
745
766
  @overload
@@ -776,12 +797,11 @@ def run_gen_step_iter(
776
797
  async_ = _get_async()
777
798
  if callable(gen_step):
778
799
  gen = gen_step()
779
- close = gen.close
780
800
  else:
781
801
  gen = gen_step
782
- close = None
783
802
  send = gen.send
784
803
  throw = gen.throw
804
+ close = gen.close
785
805
  if async_:
786
806
  async def process():
787
807
  async def extract(value):
@@ -823,19 +843,24 @@ def run_gen_step_iter(
823
843
  else:
824
844
  value = send(value)
825
845
  except StopIteration as e:
826
- yield_type, value = await extract(e.value)
827
- match yield_type:
828
- case 1:
829
- yield value
830
- case 2:
831
- async for val in ensure_aiter(value, threaded=threaded):
832
- yield val
833
- finally:
834
- if close is not None:
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:
835
855
  if threaded:
836
- await to_thread(close)
856
+ await to_thread(throw, e)
837
857
  else:
838
- close()
858
+ throw(e)
859
+ finally:
860
+ if threaded:
861
+ await to_thread(close)
862
+ else:
863
+ close()
839
864
  else:
840
865
  def process():
841
866
  def extract(value, /):
@@ -865,17 +890,19 @@ def run_gen_step_iter(
865
890
  else:
866
891
  value = send(value)
867
892
  except StopIteration as e:
868
- yield_type, value = extract(e.value)
869
- match yield_type:
870
- case 1:
871
- yield value
872
- case 2:
873
- yield from value
874
- case _:
875
- return value
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)
876
904
  finally:
877
- if close is not None:
878
- close()
905
+ close()
879
906
  return process()
880
907
 
881
908
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-iterutils"
3
- version = "0.1.8"
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.0.10.1"
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"