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.
- {python_iterutils-0.1.8 → python_iterutils-0.1.9}/PKG-INFO +2 -2
- {python_iterutils-0.1.8 → python_iterutils-0.1.9}/iterutils/__init__.py +142 -115
- {python_iterutils-0.1.8 → python_iterutils-0.1.9}/pyproject.toml +2 -2
- {python_iterutils-0.1.8 → python_iterutils-0.1.9}/LICENSE +0 -0
- {python_iterutils-0.1.8 → python_iterutils-0.1.9}/iterutils/py.typed +0 -0
- {python_iterutils-0.1.8 → python_iterutils-0.1.9}/readme.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-iterutils
|
|
3
|
-
Version: 0.1.
|
|
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.
|
|
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,
|
|
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
|
-
"
|
|
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
|
|
640
|
-
gen_step: Generator
|
|
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
|
-
|
|
657
|
-
|
|
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(
|
|
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
|
-
|
|
692
|
-
|
|
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
|
-
|
|
695
|
-
|
|
696
|
-
|
|
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
|
|
719
|
-
|
|
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
|
-
|
|
741
|
-
|
|
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
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
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(
|
|
856
|
+
await to_thread(throw, e)
|
|
837
857
|
else:
|
|
838
|
-
|
|
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
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|