python-iterutils 0.1.9__tar.gz → 0.1.10__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.9
3
+ Version: 0.1.10
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, 9)
5
+ __version__ = (0, 1, 10)
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",
@@ -643,6 +643,39 @@ def _get_async(back: int = 2) -> bool:
643
643
  return False
644
644
 
645
645
 
646
+ @overload
647
+ def call_as_async[**Args, T: Coroutine](
648
+ func: Callable[Args, T], /,
649
+ threaded: bool = False,
650
+ ) -> Callable[Args, T]:
651
+ ...
652
+ @overload
653
+ def call_as_async[**Args, T](
654
+ func: Callable[Args, T], /,
655
+ threaded: bool = False,
656
+ ) -> Callable[Args, Coroutine[Any, Any, T]]:
657
+ ...
658
+ def call_as_async[**Args, T](
659
+ func: Callable[Args, T],
660
+ /,
661
+ threaded: bool = False,
662
+ ) -> Callable[Args, T] | Callable[Args, Coroutine[Any, Any, T]]:
663
+ if iscoroutinefunction(func):
664
+ return func
665
+ def wraps(*args, **kwds):
666
+ try:
667
+ return func(*args, **kwds)
668
+ except (StopIteration, StopAsyncIteration) as e:
669
+ raise Reraised(e) from e
670
+ if threaded:
671
+ async def wrapper(*args, **kwds):
672
+ return await to_thread(wraps, *args, **kwds)
673
+ else:
674
+ async def wrapper(*args, **kwds):
675
+ return wraps(*args, **kwds)
676
+ return wrapper
677
+
678
+
646
679
  def iter_gen_step(
647
680
  gen_step: Generator | Callable[[], Generator],
648
681
  ):
@@ -650,7 +683,7 @@ def iter_gen_step(
650
683
  gen = gen_step()
651
684
  else:
652
685
  gen = gen_step
653
- send = gen.send
686
+ send = gen.send
654
687
  throw = gen.throw
655
688
  close = gen.close
656
689
  try:
@@ -681,6 +714,8 @@ def iter_gen_step(
681
714
  except BaseException as e:
682
715
  raise Reraised(e) from e
683
716
  yield value
717
+ except BaseException as e:
718
+ raise Reraised(e) from e
684
719
  finally:
685
720
  close()
686
721
 
@@ -693,9 +728,9 @@ async def iter_gen_step_async(
693
728
  gen = gen_step()
694
729
  else:
695
730
  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)
731
+ send: Callable = call_as_async(gen.send, threaded=threaded)
732
+ throw: Callable = call_as_async(gen.throw, threaded=threaded)
733
+ close: Callable = call_as_async(gen.close, threaded=threaded)
699
734
  try:
700
735
  value = await send(None)
701
736
  while True:
@@ -703,36 +738,40 @@ async def iter_gen_step_async(
703
738
  raise StopIteration(value)
704
739
  try:
705
740
  if callable(value):
706
- value = await ensure_async(value, threaded=threaded)()
741
+ value = await call_as_async(value, threaded=threaded)()
742
+ if isawaitable(value):
743
+ value = await value
707
744
  except BaseException as e:
745
+ if isinstance(e, Reraised):
746
+ e = e.exception
708
747
  value = await throw(e)
709
748
  else:
710
749
  value = await send(value)
711
750
  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:
722
- if threaded:
723
- value = await to_thread(value)
724
- else:
725
- value = value()
726
- if not identity and isawaitable(value):
727
- value = await value
728
- except BaseException as e:
751
+ except BaseException as e:
752
+ if isinstance(e, Reraised):
753
+ e = e.exception
754
+ if isinstance(e, StopIteration):
755
+ value = e.value
756
+ identity = False
757
+ try_call_me = True
758
+ if isinstance(value, YieldBase):
759
+ identity = value.identity
760
+ try_call_me = value.try_call_me
761
+ value = value.value
729
762
  try:
730
- value = await throw(e)
763
+ if callable(value) and try_call_me:
764
+ value = await call_as_async(value, threaded=threaded)()
765
+ if not identity and isawaitable(value):
766
+ value = await value
731
767
  except BaseException as e:
732
- raise Reraised(e) from e
733
- yield value
734
- except StopAsyncIteration as e:
735
- raise Reraised(e) from e
768
+ try:
769
+ value = await throw(e)
770
+ except BaseException as e:
771
+ raise Reraised(e) from e
772
+ yield value
773
+ else:
774
+ raise
736
775
  finally:
737
776
  await close()
738
777
 
@@ -799,30 +838,30 @@ def run_gen_step_iter(
799
838
  gen = gen_step()
800
839
  else:
801
840
  gen = gen_step
802
- send = gen.send
803
- throw = gen.throw
804
- close = gen.close
841
+ send: Callable = gen.send
842
+ throw: Callable = gen.throw
843
+ close: Callable = gen.close
805
844
  if async_:
845
+ send = call_as_async(send, threaded=threaded)
846
+ throw = call_as_async(throw, threaded=threaded)
847
+ close = call_as_async(close, threaded=threaded)
806
848
  async def process():
807
849
  async def extract(value):
808
850
  identity = False
809
851
  try_call_me = True
810
852
  yield_type = -1
811
853
  if isinstance(value, YieldBase):
812
- identity = value.identity
854
+ identity = value.identity
813
855
  try_call_me = value.try_call_me
814
- yield_type = value.yield_type
815
- value = value.value
856
+ yield_type = value.yield_type
857
+ value = value.value
816
858
  if try_call_me and callable(value):
817
- value = value()
859
+ value = await call_as_async(value, threaded=threaded)()
818
860
  if not identity and isawaitable(value):
819
861
  value = await value
820
862
  return yield_type, value
821
863
  try:
822
- if threaded:
823
- value = await to_thread(send, None)
824
- else:
825
- value = send(None)
864
+ value = await send(None)
826
865
  while True:
827
866
  try:
828
867
  yield_type, value = await extract(value)
@@ -833,34 +872,31 @@ def run_gen_step_iter(
833
872
  async for val in ensure_aiter(value, threaded=threaded):
834
873
  yield val
835
874
  except BaseException as e:
836
- if threaded:
837
- value = await to_thread(throw, e)
838
- else:
839
- value = throw(e)
875
+ if isinstance(e, Reraised):
876
+ e = e.exception
877
+ value = await throw(e)
840
878
  else:
841
- if threaded:
842
- value = await to_thread(send, value)
843
- else:
844
- value = send(value)
845
- except StopIteration as e:
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:
855
- if threaded:
856
- await to_thread(throw, e)
857
- else:
858
- throw(e)
859
- finally:
860
- if threaded:
861
- await to_thread(close)
879
+ value = await send(value)
880
+ except BaseException as e:
881
+ if isinstance(e, Reraised):
882
+ e = e.exception
883
+ if isinstance(e, StopIteration):
884
+ try:
885
+ yield_type, value = await extract(e.value)
886
+ match yield_type:
887
+ case 1:
888
+ yield value
889
+ case 2:
890
+ async for val in ensure_aiter(value, threaded=threaded):
891
+ yield val
892
+ except BaseException as e:
893
+ if isinstance(e, Reraised):
894
+ e = e.exception
895
+ await throw(e)
862
896
  else:
863
- close()
897
+ raise
898
+ finally:
899
+ await close()
864
900
  else:
865
901
  def process():
866
902
  def extract(value, /):
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-iterutils"
3
- version = "0.1.9"
3
+ version = "0.1.10"
4
4
  description = "Python another itertools."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"