pythonic-fp.iterables 4.0.0__py3-none-any.whl → 5.1.0__py3-none-any.whl

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.
@@ -0,0 +1,146 @@
1
+ # Copyright 2023-2025 Geoffrey R. Scheller
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Module pythonic_fp.iterables.merging"""
16
+
17
+ from collections.abc import Iterable, Iterator
18
+ from enum import auto, Enum
19
+
20
+ __all__ = [
21
+ 'MergeEnum',
22
+ 'concat',
23
+ 'merge',
24
+ 'exhaust',
25
+ 'blend',
26
+ ]
27
+
28
+
29
+ class MergeEnum(Enum):
30
+ """Iterable Blending Enums.
31
+
32
+ - **MergeEnum.Concat:** Concatenate first to last
33
+ - **MergeEnum.Merge:** Merge until one is exhausted
34
+ - **MergeEnum.Exhaust:** Merge until all are exhausted
35
+
36
+ """
37
+
38
+ Concat = auto()
39
+ Merge = auto()
40
+ Exhaust = auto()
41
+
42
+
43
+ def concat[D](*iterables: Iterable[D]) -> Iterator[D]:
44
+ """Sequentially concatenate multiple iterables together.
45
+
46
+ .. warning::
47
+ An infinite iterable will prevent subsequent iterables from
48
+ yielding any values.
49
+
50
+ .. note::
51
+
52
+ Performant to the standard library's ``itertools.chain``.
53
+
54
+ :param iterables: iterables to concatenate
55
+ :return: iterator of concatenated values from the iterables
56
+
57
+ """
58
+ for iterator in map(lambda x: iter(x), iterables):
59
+ while True:
60
+ try:
61
+ value = next(iterator)
62
+ yield value
63
+ except StopIteration:
64
+ break
65
+
66
+
67
+ def merge[D](*iterables: Iterable[D], yield_partials: bool = False) -> Iterator[D]:
68
+ """Merge together ``iterables`` until one is exhausted.
69
+
70
+ .. note::
71
+
72
+ When ``yield_partials`` is true, then any unmatched values from other iterables
73
+ already yielded when the first iterable is exhausted are yielded. This prevents
74
+ data lose if any of the iterables are iterators with external references.
75
+
76
+ :param iterables: iterables to merge until one gets exhausted
77
+ :param yield_partials: yield any unpaired yielded values from other iterables
78
+ :return: iterator of merged values from the iterables until one is exhausted
79
+
80
+ """
81
+ iter_list = list(map(lambda x: iter(x), iterables))
82
+ values = []
83
+ if (num_iters := len(iter_list)) > 0:
84
+ while True:
85
+ try:
86
+ for ii in range(num_iters):
87
+ values.append(next(iter_list[ii]))
88
+ yield from values
89
+ values.clear()
90
+ except StopIteration:
91
+ break
92
+ if yield_partials:
93
+ yield from values
94
+
95
+
96
+ def exhaust[D](*iterables: Iterable[D]) -> Iterator[D]:
97
+ """Merge together multiple iterables until all are exhausted.
98
+
99
+ :param iterables: iterables to exhaustively merge
100
+ :return: iterator of merged values from the iterables until all are exhausted
101
+
102
+ """
103
+ iter_list = list(map(lambda x: iter(x), iterables))
104
+ if (num_iters := len(iter_list)) > 0:
105
+ ii = 0
106
+ values = []
107
+ while True:
108
+ try:
109
+ while ii < num_iters:
110
+ values.append(next(iter_list[ii]))
111
+ ii += 1
112
+ yield from values
113
+ ii = 0
114
+ values.clear()
115
+ except StopIteration:
116
+ num_iters -= 1
117
+ if num_iters < 1:
118
+ break
119
+ del iter_list[ii]
120
+
121
+ yield from values
122
+
123
+
124
+ def blend[D](
125
+ *iterables: Iterable[D],
126
+ merge_enum: MergeEnum = MergeEnum.Concat,
127
+ yield_partials: bool = False,
128
+ ) -> Iterator[D]:
129
+ """Base merge behavior on name only parameters.
130
+
131
+ :param iterables: iterables to blend together
132
+ :param merge_enum: MergeEnum to determine merging behavior
133
+ :param yield_partials: yield yielded unpaired values from other iterables
134
+ :return: an iterator of type D
135
+ :raises ValueError: when an unknown MergeEnum is given
136
+
137
+ """
138
+ match merge_enum:
139
+ case MergeEnum.Concat:
140
+ return concat(*iterables)
141
+ case MergeEnum.Merge:
142
+ return merge(*iterables, yield_partials=yield_partials)
143
+ case MergeEnum.Exhaust:
144
+ return exhaust(*iterables)
145
+
146
+ raise ValueError('Unknown MergeEnum given')
@@ -0,0 +1,38 @@
1
+ # Copyright 2023-2025 Geoffrey R. Scheller
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from collections.abc import Iterable, Iterator
16
+ from enum import auto, Enum
17
+
18
+ __all__ = [
19
+ 'MergeEnum',
20
+ 'concat',
21
+ 'merge',
22
+ 'exhaust',
23
+ 'blend',
24
+ ]
25
+
26
+ class MergeEnum(Enum):
27
+ Concat = auto()
28
+ Merge = auto()
29
+ Exhaust = auto()
30
+
31
+ def concat[D](*iterables: Iterable[D]) -> Iterator[D]: ...
32
+ def merge[D](*iterables: Iterable[D], yield_partials: bool = False) -> Iterator[D]: ...
33
+ def exhaust[D](*iterables: Iterable[D]) -> Iterator[D]: ...
34
+ def blend[D](
35
+ *iterables: Iterable[D],
36
+ merge_enum: MergeEnum = MergeEnum.Concat,
37
+ yield_partials: bool = False,
38
+ ) -> Iterator[D]: ...
File without changes
@@ -0,0 +1,61 @@
1
+ Metadata-Version: 2.4
2
+ Name: pythonic-fp-iterables
3
+ Version: 5.1.0
4
+ Summary: Library of functions for iterating iterables
5
+ Keywords: iterables,iterators
6
+ Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
7
+ Requires-Python: >=3.13
8
+ Description-Content-Type: text/x-rst
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Framework :: Pytest
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Typing :: Typed
16
+ License-File: LICENSE
17
+ Requires-Dist: pythonic-fp-fptools>=5.1.0
18
+ Requires-Dist: pythonic-fp-gadgets>=3.0.1
19
+ Requires-Dist: pythonic-fp-sentinels>=2.1.1
20
+ Requires-Dist: pytest>=8.4.1 ; extra == "test"
21
+ Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-iterables/blob/main/CHANGELOG.rst
22
+ Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/iterables/development/build/html/releases.html
23
+ Project-URL: Homepage, https://github.com/grscheller/pythonic-fp/blob/main/README.md
24
+ Project-URL: Source, https://github.com/grscheller/pythonic-fp-iterables
25
+ Provides-Extra: test
26
+
27
+ Pythonic FP - Tools for iterables
28
+ =================================
29
+
30
+ PyPI project
31
+ `pythonic-fp.iterators <https://pypi.org/project/pythonic-fp.iterables>`_.
32
+
33
+ Library of functions for iterating iterables.
34
+
35
+ - Concatenating and merging iterables
36
+ - Dropping and taking values from iterables
37
+ - Reducing and accumulating iterables
38
+ - Assumptions
39
+
40
+ - iterables are not necessarily iterators
41
+ - at all times iterator protocol is assumed to be followed
42
+
43
+ - all iterators are assumed to be iterable
44
+ - for all iterators ``foo`` we assume ``iter(foo) is foo``
45
+
46
+ This PyPI project is part of of the
47
+ `pythonic-fp namespace projects <https://github.com/grscheller/pythonic-fp/blob/main/README.md>`_
48
+
49
+ Documentation
50
+ -------------
51
+
52
+ Documentation for this project is hosted on
53
+ `GitHub Pages
54
+ <https://grscheller.github.io/pythonic-fp/iterables/development/build/html>`_.
55
+
56
+ Copyright and License
57
+ ---------------------
58
+
59
+ Copyright (c) 2023-2025 Geoffrey R. Scheller. Licensed under the Apache
60
+ License, Version 2.0. See the LICENSE file for details.
61
+
@@ -0,0 +1,12 @@
1
+ pythonic_fp/iterables/__init__.py,sha256=UTde8stsDVG_5Z7fo37yiYeTu8fhkkv0QsQcQb_ixTU,1590
2
+ pythonic_fp/iterables/drop_take.py,sha256=bHxVTJAY9vof570cFQNXNZZAUAtnWBDZgRu7df2aV9E,4707
3
+ pythonic_fp/iterables/drop_take.pyi,sha256=6BtavkUHIxMJmJfcvDAnds9R29OXrCRkDK12jG575VY,1276
4
+ pythonic_fp/iterables/folding.py,sha256=A4VoU7piryt6Fun6Inn1SJSr1IiN-aTqzeSs-mds5oQ,8604
5
+ pythonic_fp/iterables/folding.pyi,sha256=BUslV-cn9eOxlYAF_3wz09TcHDbMATUL0uqU7IjJyAM,2035
6
+ pythonic_fp/iterables/merging.py,sha256=tPVjw5Fr32gMTd4Uq3SKQPqdV9p5fs3xW-0elt8Yz8U,4462
7
+ pythonic_fp/iterables/merging.pyi,sha256=5QBH0NEoqWQwCvWMPBFVoUOWAwmMYqj2W4s2b1rn9J0,1189
8
+ pythonic_fp/iterables/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ pythonic_fp_iterables-5.1.0.dist-info/licenses/LICENSE,sha256=IJMkVWQUVy-SonK6SMaMotDQ6Zb-lVi2bUTiGp1GUO8,10774
10
+ pythonic_fp_iterables-5.1.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
11
+ pythonic_fp_iterables-5.1.0.dist-info/METADATA,sha256=FjgztLEfjG2VBYMtg_XUa0gyZTplavSKb523m746npY,2218
12
+ pythonic_fp_iterables-5.1.0.dist-info/RECORD,,