pythonic-fp.iterables 5.1.4__py3-none-any.whl → 6.0.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.
@@ -27,7 +27,7 @@
27
27
  - at all times iterator protocol is assumed to be followed
28
28
 
29
29
  - all iterators are assumed to be iterable
30
- - for all iterators ``foobar`` we assume ``iter(foobar) is foobar``
30
+ - for all iterators ``foo`` we assume ``iter(foo) is foo``
31
31
 
32
32
  """
33
33
 
@@ -34,7 +34,9 @@
34
34
  """
35
35
 
36
36
  from collections.abc import Callable, Iterable, Iterator
37
+
37
38
  from pythonic_fp.gadgets.box import Box
39
+
38
40
  from .merging import concat
39
41
 
40
42
  __all__ = [
@@ -74,7 +76,7 @@ def drop_while[D](iterable: Iterable[D], pred: Callable[[D], bool]) -> Iterator[
74
76
  Drop initial items from iterable while predicate is true.
75
77
 
76
78
  :param iterable: Iterable whose items are to be dropped.
77
- :param pred: Single argument Boolean items function, the "predicate".
79
+ :param pred: Single argument Boolean valued function.
78
80
  :yields: items starting when ``pred`` returns ``False``.
79
81
 
80
82
  """
@@ -117,7 +119,7 @@ def take_while[D](iterable: Iterable[D], pred: Callable[[D], bool]) -> Iterator[
117
119
  Return an iterator of items until predicate false.
118
120
 
119
121
  :param iterable: Iterable providing the items to be taken.
120
- :param pred: Single argument Boolean valued function, the "predicate".
122
+ :param pred: Single argument Boolean valued function.
121
123
  :yields: Items from iterable while predicate is true.
122
124
 
123
125
  .. warning::
@@ -146,7 +148,7 @@ def take_split[D](iterable: Iterable[D], n: int) -> tuple[Iterator[D], Iterator[
146
148
 
147
149
  .. admonition:: CONTRACT
148
150
 
149
- **CONTRACT:** Do not access the second iterator until
151
+ **IMPORTANT:** Do not access the second iterator until
150
152
  the first one is completely exhausted.
151
153
 
152
154
  :param iterable: Iterable providing the items to be taken.
@@ -172,7 +174,7 @@ def take_while_split[D](
172
174
 
173
175
  .. admonition:: CONTRACT
174
176
 
175
- **CONTRACT:** Do not access the second iterator until
177
+ **IMPORTANT:** Do not access the second iterator until
176
178
  the first one is completely exhausted.
177
179
 
178
180
  :param iterable: Iterable providing the items to be taken.
@@ -20,10 +20,13 @@
20
20
  """
21
21
 
22
22
  from collections.abc import Callable, Iterable, Iterator
23
- from typing import cast, Never
23
+ from typing import cast
24
+
24
25
  from pythonic_fp.fptools.function import negate, swap
25
26
  from pythonic_fp.fptools.maybe import MayBe
27
+ from pythonic_fp.fptools.recoverable import RECOVERABLE
26
28
  from pythonic_fp.gadgets.sentinels.novalue import NoValue
29
+
27
30
  from .drop_take import drop_while, take_while_split
28
31
 
29
32
  __all__ = [
@@ -34,19 +37,20 @@ __all__ = [
34
37
  'sc_reduce_left',
35
38
  'sc_reduce_right',
36
39
  ]
40
+ novalue = NoValue()
37
41
 
38
42
 
39
43
  def accumulate[D, L](
40
- iterable: Iterable[D], f: Callable[[L, D], L], initial: L | NoValue = NoValue()
44
+ iterable: Iterable[D], f: Callable[[L, D], L], initial: L | NoValue = novalue
41
45
  ) -> Iterator[L]:
42
46
  """
43
47
  .. admonition:: accumulate
44
48
 
45
- Returns an iterator of partial fold items. A pure Python
46
- version of
49
+ Returns an iterator of partially folded items.
47
50
 
48
51
  :param iterable: Iterable to be folded.
49
- :param f: Two parameter function, first parameter for accumulated items.
52
+ :param f: Two parameter function, first parameter is for
53
+ the accumulator.
50
54
  :param initial: Optional ``initial`` item to start fold.
51
55
  :yields: The intermediate folded items.
52
56
 
@@ -83,14 +87,15 @@ def accumulate[D, L](
83
87
  yield acc
84
88
 
85
89
 
86
- def reduce_left[D](iterable: Iterable[D], f: Callable[[D, D], D]) -> D | Never:
90
+ def reduce_left[D](iterable: Iterable[D], f: Callable[[D, D], D]) -> D:
87
91
  """
88
92
  .. admonition:: reduce left
89
93
 
90
94
  Fold an iterable left with a function.
91
95
 
92
96
  :param iterable: Iterable to be reduced (folded).
93
- :param f: Two parameter function, first parameter for accumulated items.
97
+ :param f: Two parameter function, first parameter is for
98
+ the accumulator.
94
99
  :return: Reduced item from the iterable.
95
100
  :raises StopIteration: When called on an empty iterable.
96
101
  :raises Exception: Does not catch any exceptions from ``f``.
@@ -98,7 +103,7 @@ def reduce_left[D](iterable: Iterable[D], f: Callable[[D, D], D]) -> D | Never:
98
103
  .. warning::
99
104
 
100
105
  - never returns if given an infinite iterable
101
- - does not catch or re-raises exceptions raised by ``f``
106
+ - does not catch or re-raise exceptions raised by ``f``
102
107
 
103
108
  """
104
109
  it = iter(iterable)
@@ -116,7 +121,7 @@ def reduce_left[D](iterable: Iterable[D], f: Callable[[D, D], D]) -> D | Never:
116
121
 
117
122
  def fold_left[D, L](
118
123
  iterable: Iterable[D], f: Callable[[L, D], L], initial: L
119
- ) -> L | Never:
124
+ ) -> L:
120
125
  """
121
126
  .. admonition:: fold left
122
127
 
@@ -126,10 +131,11 @@ def fold_left[D, L](
126
131
  - initial item is required, does not default to ``0``
127
132
  - handles non-numeric data just find
128
133
 
129
- :param iterable: iterable to be folded
130
- :param f: two parameter function, first parameter for accumulated item
131
- :param initial: mandatory initial item to start fold
132
- :return: the folded item
134
+ :param iterable: Iterable to be folded.
135
+ :param f: Two parameter function, first parameter is for
136
+ the accumulator.
137
+ :param initial: Mandatory initial item to start fold
138
+ :return: The folded item.
133
139
 
134
140
  .. warning::
135
141
 
@@ -144,8 +150,8 @@ def fold_left[D, L](
144
150
 
145
151
 
146
152
  def maybe_fold_left[D, L](
147
- iterable: Iterable[D], f: Callable[[L, D], L], initial: L | NoValue = NoValue()
148
- ) -> MayBe[L] | Never:
153
+ iterable: Iterable[D], f: Callable[[L, D], L], initial: L | NoValue = novalue
154
+ ) -> MayBe[L]:
149
155
  """
150
156
  .. admonition:: maybe fold left
151
157
 
@@ -155,7 +161,7 @@ def maybe_fold_left[D, L](
155
161
  - if iterable empty and no ``initial`` item given, return ``MayBe()``
156
162
 
157
163
  :param iterable: The iterable to be folded.
158
- :param f: First argument is for the accumulated items.
164
+ :param f: First argument is for the accumulator.
159
165
  :param initial: Mandatory initial item to start fold.
160
166
  :return: ``MayBe`` of a successfully folded item,
161
167
  otherwise returns ``MayBe()``.
@@ -179,7 +185,7 @@ def maybe_fold_left[D, L](
179
185
  for v in it:
180
186
  try:
181
187
  acc = f(acc, v)
182
- except Exception:
188
+ except RECOVERABLE:
183
189
  return MayBe()
184
190
 
185
191
  return MayBe(acc)
@@ -199,7 +205,7 @@ def sc_reduce_left[D](
199
205
  Short circuit version of a left fold.
200
206
 
201
207
  :param iterable: Iterable to be reduced from the left.
202
- :param f: Two parameter function, first parameter for
208
+ :param f: Two parameter function, first parameter is for
203
209
  the accumulator.
204
210
  :param start: Delay starting the fold until it returns true.
205
211
  :param stop: Prematurely stop the fold when it returns true.
@@ -261,7 +267,7 @@ def sc_reduce_right[D](
261
267
  Short circuit version of a right fold.
262
268
 
263
269
  :param iterable: Iterable to be reduced from the right.
264
- :param f: Two parameter function, second parameter for
270
+ :param f: Two parameter function, second parameter is for
265
271
  the accumulator.
266
272
  :param start: Delay starting the fold until it returns true.
267
273
  :param stop: Prematurely stop the fold when it returns true.
@@ -20,7 +20,7 @@
20
20
  """
21
21
 
22
22
  from collections.abc import Iterable, Iterator
23
- from enum import auto, Enum
23
+ from enum import Enum, auto
24
24
 
25
25
  __all__ = [
26
26
  'MergeEnum',
@@ -35,9 +35,9 @@ class MergeEnum(Enum):
35
35
  """
36
36
  .. admonition:: Iterable Blending Enums.
37
37
 
38
- - **MergeEnum.Concat:** Concatenate first to last
39
- - **MergeEnum.Merge:** Merge until one is exhausted
40
- - **MergeEnum.Exhaust:** Merge until all are exhausted
38
+ - **Concat:** Concatenate first to last
39
+ - **Merge:** Merge until one is exhausted
40
+ - **Exhaust:** Merge until all are exhausted
41
41
 
42
42
  """
43
43
  Concat = auto()
@@ -63,7 +63,7 @@ def concat[D](*iterables: Iterable[D]) -> Iterator[D]:
63
63
  Performant to the standard library's ``itertools.chain``.
64
64
 
65
65
  """
66
- for iterator in map(lambda x: iter(x), iterables):
66
+ for iterator in (iter(x) for x in iterables):
67
67
  while True:
68
68
  try:
69
69
  item = next(iterator)
@@ -76,7 +76,7 @@ def merge[D](*iterables: Iterable[D], yield_partials: bool = False) -> Iterator[
76
76
  """
77
77
  .. admonition:: merge iterables
78
78
 
79
- Merge multiple iterables until one is exhausted.
79
+ Merge multiple iterables until one of them is exhausted.
80
80
 
81
81
  :param iterables: Iterables to merge until one gets exhausted.
82
82
  :param yield_partials: Yield any unpaired yielded items from other iterables.
@@ -93,7 +93,7 @@ def merge[D](*iterables: Iterable[D], yield_partials: bool = False) -> Iterator[
93
93
  iterators with external references.
94
94
 
95
95
  """
96
- iter_list = list(map(lambda x: iter(x), iterables))
96
+ iter_list = [iter(x) for x in iterables]
97
97
  items = []
98
98
  if (num_iters := len(iter_list)) > 0:
99
99
  while True:
@@ -112,14 +112,14 @@ def exhaust[D](*iterables: Iterable[D]) -> Iterator[D]:
112
112
  """
113
113
  .. admonition:: exhaustively merge iterables
114
114
 
115
- Merge multiple iterables until all are exhausted.
115
+ Merge multiple iterables until all of them are exhausted.
116
116
 
117
117
  :param iterables: Iterables to exhaustively merge.
118
118
  :yields: Merged items from the iterables until all of the
119
119
  iterables are exhausted.
120
120
 
121
121
  """
122
- iter_list = list(map(lambda x: iter(x), iterables))
122
+ iter_list = [iter(x) for x in iterables]
123
123
  if (num_iters := len(iter_list)) > 0:
124
124
  ii = 0
125
125
  items = []
@@ -150,6 +150,10 @@ def blend[D](
150
150
 
151
151
  Merge behavior based on value of merge_enum parameter.
152
152
 
153
+ - Concat: Concatenate first to last
154
+ - Merge: Merge until one is exhausted
155
+ - Exhaust: Merge until all are exhausted
156
+
153
157
  :param iterables: Iterables to blend together.
154
158
  :param merge_enum: ``MergeEnum`` to determine merging behavior.
155
159
  :param yield_partials: Yield unpaired items from other iterables.
@@ -1,62 +1,52 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-iterables
3
- Version: 5.1.4
4
- Summary: .. admonition:: Composing and iterating iterables
3
+ Version: 6.0.0
4
+ Summary: Composing and iterating iterables.
5
5
  Keywords: iterables,iterators
6
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
7
+ Requires-Python: >=3.14
8
+ Description-Content-Type: text/markdown
9
+ Classifier: Development Status :: 4 - Beta
10
10
  Classifier: Framework :: Pytest
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
13
  Classifier: Operating System :: OS Independent
14
14
  Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Programming Language :: Python :: 3.15
15
16
  Classifier: Typing :: Typed
16
17
  License-File: LICENSE
17
- Requires-Dist: pythonic-fp-fptools>=5.2.0
18
- Requires-Dist: pythonic-fp-gadgets>=4.0.2
19
- Requires-Dist: pytest>=8.4.1 ; extra == "test"
20
- Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-iterables/blob/main/CHANGELOG.rst
21
- Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/projects/iterables.html
22
- Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/
18
+ Requires-Dist: pythonic-fp-fptools>=6.2,<7
19
+ Requires-Dist: pythonic-fp-gadgets>=6,<7
20
+ Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-iterables/blob/main/CHANGELOG.md
21
+ Project-URL: Documentation, https://grscheller.github.io/pythonic-fp-iterables
22
+ Project-URL: Homepage, https://grscheller.github.io/pythonic-fp
23
23
  Project-URL: Source, https://github.com/grscheller/pythonic-fp-iterables
24
- Provides-Extra: test
25
24
 
26
- Pythonic FP - Tools for iterables
27
- =================================
25
+ # Pythonic FP - Tools for iterables
26
+
27
+ Library of functions for iterating iterables.
28
28
 
29
29
  PyPI project
30
- `pythonic-fp-iterators
31
- <https://pypi.org/project/pythonic-fp-iterables>`_.
30
+ [pythonic-fp-iterators](https://pypi.org/project/pythonic-fp-iterables).
31
+ Part of the
32
+ [pythonic-fp](https://grscheller.github.io/pythonic-fp)
33
+ PyPI projects.
32
34
 
33
- Library of functions for iterating iterables.
35
+ ## Documentation
36
+
37
+ Documentation and other links for this project are hosted on
38
+ [GitHub Pages](https://grscheller.github.io/pythonic-fp-iterables).
34
39
 
35
40
  - Concatenating and merging iterables
36
41
  - Dropping and taking values from iterables
37
42
  - Reducing and accumulating iterables
38
43
  - Assumptions
39
-
40
44
  - iterables are not necessarily iterators
41
45
  - at all times iterator protocol is assumed to be followed
42
-
43
46
  - all iterators are assumed to be iterable
44
- - for all iterators ``foo`` we assume ``iter(foo) is foo``
45
-
46
- Part of the
47
- `pythonic-fp
48
- <https://grscheller.github.io/pythonic-fp/>`_
49
- PyPI projects.
50
-
51
- Documentation
52
- -------------
53
-
54
- Documentation and other links for this project are hosted on
55
- `GitHub Pages
56
- <https://grscheller.github.io/pythonic-fp/projects/iterables.html>`_.
47
+ - for all iterators `foo` we assume `iter(foo)` is `foo`
57
48
 
58
- Copyright and License
59
- ---------------------
49
+ ## Copyright and License
60
50
 
61
51
  Copyright (c) 2023-2026 Geoffrey R. Scheller. Licensed under the Apache
62
52
  License, Version 2.0. See the LICENSE file for details.
@@ -0,0 +1,9 @@
1
+ pythonic_fp/iterables/__init__.py,sha256=lL6SETAAn9sn2dGRBxvbJlswZwweym4OumCKbJfokQI,1246
2
+ pythonic_fp/iterables/drop_take.py,sha256=OXvDpzxDWvCwUeaZaDY0-fgOKO8bGMczkzT2q1IRD7g,5529
3
+ pythonic_fp/iterables/folding.py,sha256=f1_2mLlTnUYl5xDtrn-xd6xeVyHare2lql7-rE8UakM,9422
4
+ pythonic_fp/iterables/merging.py,sha256=_tAfQM4_tq_wg5RdWxtFjeQ6uii0DC74NQjpDQq0Qgw,5011
5
+ pythonic_fp/iterables/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ pythonic_fp_iterables-6.0.0.dist-info/licenses/LICENSE,sha256=IJMkVWQUVy-SonK6SMaMotDQ6Zb-lVi2bUTiGp1GUO8,10774
7
+ pythonic_fp_iterables-6.0.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
8
+ pythonic_fp_iterables-6.0.0.dist-info/METADATA,sha256=9mOfNJcoVa0PePBSUh3158X-tJzrELq-WSgTz5VW5NM,1950
9
+ pythonic_fp_iterables-6.0.0.dist-info/RECORD,,
File without changes
@@ -1,10 +0,0 @@
1
- from collections.abc import Callable, Iterable, Iterator
2
-
3
- __all__ = ['drop', 'drop_while', 'take', 'take_while', 'take_split', 'take_while_split']
4
-
5
- def drop[D](iterable: Iterable[D], n: int) -> Iterator[D]: ...
6
- def drop_while[D](iterable: Iterable[D], pred: Callable[[D], bool]) -> Iterator[D]: ...
7
- def take[D](iterable: Iterable[D], n: int) -> Iterator[D]: ...
8
- def take_while[D](iterable: Iterable[D], pred: Callable[[D], bool]) -> Iterator[D]: ...
9
- def take_split[D](iterable: Iterable[D], n: int) -> tuple[Iterator[D], Iterator[D]]: ...
10
- def take_while_split[D](iterable: Iterable[D], pred: Callable[[D], bool]) -> tuple[Iterator[D], Iterator[D]]: ...
@@ -1,13 +0,0 @@
1
- from collections.abc import Callable, Iterable, Iterator
2
- from pythonic_fp.fptools.maybe import MayBe
3
- from pythonic_fp.gadgets.sentinels.novalue import NoValue
4
- from typing import Never
5
-
6
- __all__ = ['accumulate', 'reduce_left', 'fold_left', 'maybe_fold_left', 'sc_reduce_left', 'sc_reduce_right']
7
-
8
- def accumulate[D, L](iterable: Iterable[D], f: Callable[[L, D], L], initial: L | NoValue = ...) -> Iterator[L]: ...
9
- def reduce_left[D](iterable: Iterable[D], f: Callable[[D, D], D]) -> D | Never: ...
10
- def fold_left[D, L](iterable: Iterable[D], f: Callable[[L, D], L], initial: L) -> L | Never: ...
11
- def maybe_fold_left[D, L](iterable: Iterable[D], f: Callable[[L, D], L], initial: L | NoValue = ...) -> MayBe[L] | Never: ...
12
- def sc_reduce_left[D](iterable: Iterable[D], f: Callable[[D, D], D], start: Callable[[D], bool] = ..., stop: Callable[[D], bool] = ..., include_start: bool = True, include_stop: bool = True) -> tuple[MayBe[D], Iterator[D]]: ...
13
- def sc_reduce_right[D](iterable: Iterable[D], f: Callable[[D, D], D], start: Callable[[D], bool] = ..., stop: Callable[[D], bool] = ..., include_start: bool = True, include_stop: bool = True) -> tuple[MayBe[D], Iterator[D]]: ...
@@ -1,14 +0,0 @@
1
- from collections.abc import Iterable, Iterator
2
- from enum import Enum
3
-
4
- __all__ = ['MergeEnum', 'concat', 'merge', 'exhaust', 'blend']
5
-
6
- class MergeEnum(Enum):
7
- Concat = ...
8
- Merge = ...
9
- Exhaust = ...
10
-
11
- def concat[D](*iterables: Iterable[D]) -> Iterator[D]: ...
12
- def merge[D](*iterables: Iterable[D], yield_partials: bool = False) -> Iterator[D]: ...
13
- def exhaust[D](*iterables: Iterable[D]) -> Iterator[D]: ...
14
- def blend[D](*iterables: Iterable[D], merge_enum: MergeEnum = ..., yield_partials: bool = False) -> Iterator[D]: ...
@@ -1,13 +0,0 @@
1
- pythonic_fp/iterables/__init__.py,sha256=j-Z9XV73LehhLwYvi_Wzhml7hPaEbHiRjRJt-BI6RKs,1255
2
- pythonic_fp/iterables/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- pythonic_fp/iterables/drop_take.py,sha256=0ydMGx-aj_-aK5PIx7Rowh_9h0niC6bRKMSotHjvy1g,5558
4
- pythonic_fp/iterables/drop_take.pyi,sha256=vPyByY4PxCGEuL6trI0aTK8fBr4xCuOgqhaKALwJ5Ys,653
5
- pythonic_fp/iterables/folding.py,sha256=tqFzxzWLpK6qIS9ff8tTwv58q2h4gjBAyuHrNeEWi20,9347
6
- pythonic_fp/iterables/folding.pyi,sha256=ZVrpB-D4kWoVwpCsQ2rc3GJ8iTzavAOQ5YK9LteAukU,1175
7
- pythonic_fp/iterables/merging.py,sha256=acQ8_Iw07CVvOnB_D8dbLvmkjv7P48CysareWlfAbRc,4912
8
- pythonic_fp/iterables/merging.pyi,sha256=KnuSFREXEpnbtTvMWsvn-KfeSjZ3ybP-6n9hCxjNKVs,533
9
- pythonic_fp/iterables/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- pythonic_fp_iterables-5.1.4.dist-info/licenses/LICENSE,sha256=IJMkVWQUVy-SonK6SMaMotDQ6Zb-lVi2bUTiGp1GUO8,10774
11
- pythonic_fp_iterables-5.1.4.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
12
- pythonic_fp_iterables-5.1.4.dist-info/METADATA,sha256=zOdoxJujuqsKpXHZqKfI-0wJRmnKEDdy5T_KjMXMJGQ,2096
13
- pythonic_fp_iterables-5.1.4.dist-info/RECORD,,