pythonic-fp.iterables 5.1.3__tar.gz → 5.2.0__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,62 +1,53 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-iterables
3
- Version: 5.1.3
4
- Summary: Tools for iterables
3
+ Version: 5.2.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
7
+ Requires-Python: >=3.14
8
+ Description-Content-Type: text/markdown
9
9
  Classifier: Development Status :: 5 - Production/Stable
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
- Classifier: Programming Language :: Python :: 3.13
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/iterables/development/build/html/
22
- Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/homepage/build/html/
18
+ Requires-Dist: pythonic-fp-fptools>=6,<6.2
19
+ Requires-Dist: pythonic-fp-gadgets>=4.5,<6
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/release/html/
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 <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.
31
34
 
32
- 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/projects/iterables.html).
33
39
 
34
40
  - Concatenating and merging iterables
35
41
  - Dropping and taking values from iterables
36
42
  - Reducing and accumulating iterables
37
43
  - Assumptions
38
-
39
44
  - iterables are not necessarily iterators
40
45
  - at all times iterator protocol is assumed to be followed
41
-
42
46
  - all iterators are assumed to be iterable
43
47
  - for all iterators ``foo`` we assume ``iter(foo) is foo``
44
48
 
45
- Part of the
46
- `pythonic-fp
47
- <https://grscheller.github.io/pythonic-fp>`_
48
- PyPI projects.
49
-
50
- Documentation
51
- -------------
52
-
53
- Documentation for this project is hosted on
54
- `GitHub Pages
55
- <https://grscheller.github.io/pythonic-fp/iterables>`_.
56
-
57
- Copyright and License
58
- ---------------------
49
+ ## Copyright and License
59
50
 
60
- Copyright (c) 2023-2025 Geoffrey R. Scheller. Licensed under the Apache
51
+ Copyright (c) 2023-2026 Geoffrey R. Scheller. Licensed under the Apache
61
52
  License, Version 2.0. See the LICENSE file for details.
62
53
 
@@ -1,36 +1,28 @@
1
- Pythonic FP - Tools for iterables
2
- =================================
1
+ # Pythonic FP - Tools for iterables
2
+
3
+ Library of functions for iterating iterables.
3
4
 
4
5
  PyPI project
5
- `pythonic-fp.iterators <https://pypi.org/project/pythonic-fp.iterables>`_.
6
+ [pythonic-fp-iterators](https://pypi.org/project/pythonic-fp-iterables).
7
+ Part of the
8
+ [pythonic-fp](https://grscheller.github.io/pythonic-fp/)
9
+ PyPI projects.
6
10
 
7
- Library of functions for iterating iterables.
11
+ ## Documentation
12
+
13
+ Documentation and other links for this project are hosted on
14
+ [GitHub Pages](https://grscheller.github.io/pythonic-fp/projects/iterables.html).
8
15
 
9
16
  - Concatenating and merging iterables
10
17
  - Dropping and taking values from iterables
11
18
  - Reducing and accumulating iterables
12
19
  - Assumptions
13
-
14
20
  - iterables are not necessarily iterators
15
21
  - at all times iterator protocol is assumed to be followed
16
-
17
22
  - all iterators are assumed to be iterable
18
23
  - for all iterators ``foo`` we assume ``iter(foo) is foo``
19
24
 
20
- Part of the
21
- `pythonic-fp
22
- <https://grscheller.github.io/pythonic-fp>`_
23
- PyPI projects.
24
-
25
- Documentation
26
- -------------
27
-
28
- Documentation for this project is hosted on
29
- `GitHub Pages
30
- <https://grscheller.github.io/pythonic-fp/iterables>`_.
31
-
32
- Copyright and License
33
- ---------------------
25
+ ## Copyright and License
34
26
 
35
- Copyright (c) 2023-2025 Geoffrey R. Scheller. Licensed under the Apache
27
+ Copyright (c) 2023-2026 Geoffrey R. Scheller. Licensed under the Apache
36
28
  License, Version 2.0. See the LICENSE file for details.
@@ -1,75 +1,86 @@
1
+ [build-system]
2
+ requires = ["flit_core>=3.12,<4"]
3
+ build-backend = "flit_core.buildapi"
4
+
1
5
  [project]
2
6
  name = "pythonic-fp-iterables"
3
- version = "5.1.3"
4
- readme = "README.rst"
5
- requires-python = ">=3.13"
6
- license = { file = "LICENSE" }
7
- authors = [{ name = "Geoffrey R. Scheller", email = "geoffrey@scheller.com" }]
8
- keywords = ["iterables", "iterators"]
7
+ version = "5.2.0"
8
+ description = "Composing and iterating iterables."
9
+ readme = "README.md"
10
+ requires-python = ">=3.14" # floor: PEP 649/749 deferred annotations — class-level self-reference
11
+ authors = [
12
+ { name = "Geoffrey R. Scheller", email = "geoffrey@scheller.com" },
13
+ ]
14
+ keywords = [
15
+ "iterables",
16
+ "iterators",
17
+ ]
9
18
  classifiers = [
10
19
  "Development Status :: 5 - Production/Stable",
11
20
  "Framework :: Pytest",
12
21
  "Intended Audience :: Developers",
13
22
  "License :: OSI Approved :: Apache Software License",
14
23
  "Operating System :: OS Independent",
15
- "Programming Language :: Python :: 3.13",
24
+ "Programming Language :: Python :: 3.14",
25
+ "Programming Language :: Python :: 3.15",
16
26
  "Typing :: Typed",
17
27
  ]
18
28
  dependencies = [
19
- "pythonic-fp-fptools>=5.2.0",
20
- "pythonic-fp-gadgets>=4.0.2",
29
+ "pythonic-fp-fptools>=6,<6.2",
30
+ "pythonic-fp-gadgets>=4.5,<6",
21
31
  ]
22
- dynamic = ["description"]
23
32
 
24
33
  [project.urls]
25
- Changelog = "https://github.com/grscheller/pythonic-fp-iterables/blob/main/CHANGELOG.rst"
26
- Documentation = "https://grscheller.github.io/pythonic-fp/iterables/development/build/html/"
27
- Homepage = "https://grscheller.github.io/pythonic-fp/homepage/build/html/"
34
+ Changelog = "https://github.com/grscheller/pythonic-fp-iterables/blob/main/CHANGELOG.md"
35
+ Documentation ="https://grscheller.github.io/pythonic-fp-iterables/release/html/"
36
+ Homepage = "https://grscheller.github.io/pythonic-fp/"
28
37
  Source = "https://github.com/grscheller/pythonic-fp-iterables"
29
38
 
30
- [project.optional-dependencies]
39
+ [dependency-groups]
40
+ docs = [
41
+ "furo>=2025.12.19",
42
+ "sphinx>=9.1",
43
+ ]
31
44
  test = [
32
45
  "pytest>=8.4.1",
33
46
  ]
34
47
 
35
- [build-system]
36
- requires = ["flit_core>=3.12,<4"]
37
- build-backend = "flit_core.buildapi"
38
-
39
48
  [tool.flit.module]
40
49
  name = "pythonic_fp.iterables"
41
50
 
51
+ [tool.flit.sdist]
52
+ exclude = [
53
+ "docs/",
54
+ "tests/",
55
+ ]
56
+
57
+ [tool.pytest]
58
+ addopts = ["-ra"]
59
+ consider_namespace_packages = true
60
+ testpaths = ["tests/"]
61
+
42
62
  [tool.mypy]
43
- enable_incomplete_feature = "NewGenericSyntax"
44
63
  explicit_package_bases = true
45
- implicit_reexport = false
46
64
  local_partial_types = true
47
65
  namespace_packages = true
48
66
  warn_redundant_casts = true
49
67
  warn_return_any = true
50
68
  warn_unused_configs = true
51
69
 
52
- [tool.pylsp-mypy]
53
- enabled = true
54
- live-mode = true
55
- dmypy = false
56
- strict = true
57
- report_progress = true
58
-
59
- [tool.pytest.ini_options]
60
- addopts = "-ra"
61
- consider_namespace_packages = true
62
- testpaths = ["tests/"]
63
-
64
70
  [tool.ruff]
65
- target-version = "py313"
71
+ target-version = "py314"
72
+
73
+ [tool.ruff.lint]
74
+ ignore = ["RUF022", "E741"]
66
75
 
67
76
  [tool.ruff.lint.flake8-quotes]
68
77
  docstring-quotes = "double"
69
78
 
70
79
  [tool.ruff.lint.per-file-ignores]
71
- "tests/*" = ["C901"]
72
- "**/*.py" = ["E741"]
80
+ "tests/**/*.py" = [
81
+ "E731",
82
+ "C901",
83
+ ]
73
84
 
74
85
  [tool.ruff.format]
75
86
  quote-style = "single"
@@ -13,20 +13,11 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """
16
- Tools for iterables
17
- -------------------
16
+ .. admonition:: Composing and iterating iterables
18
17
 
19
- .. admonition:: Library of functions for iterating iterables
20
-
21
- +-----------+-------------------------------------------+
22
- | Module | Description |
23
- +===========+===========================================+
24
- | merging | Concatenating and merging iterables |
25
- +-----------+-------------------------------------------+
26
- | drop_take | Dropping and taking values from iterables |
27
- +-----------+-------------------------------------------+
28
- | folding | Reducing and accumulating iterables |
29
- +-----------+-------------------------------------------+
18
+ - module **merging:** Concatenating and merging iterables.
19
+ - module **drop_take:** Dropping and taking values from iterables.
20
+ - module **folding:** Reducing and accumulating iterables.
30
21
 
31
22
  .. important::
32
23
 
@@ -35,8 +26,8 @@ Tools for iterables
35
26
  - iterables are not necessarily iterators
36
27
  - at all times iterator protocol is assumed to be followed
37
28
 
38
- - all iterators are assumed to be iterable
39
- - for all iterators ``foobar`` we assume ``iter(foobar) is foobar``
29
+ - all iterators are assumed to be iterable
30
+ - for all iterators ``foo`` we assume ``iter(foo) is foo``
40
31
 
41
32
  """
42
33
 
@@ -0,0 +1,202 @@
1
+ # Copyright 2023-2026 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
+ """
16
+ .. admonition:: Drop and Take
17
+
18
+ Functions which drop or take items from an iterable.
19
+
20
+ .. important::
21
+
22
+ If iterable is a multiply referenced iterator, items
23
+ dropped or taken need not be the next consecutive items.
24
+
25
+ .. important::
26
+
27
+ If iterable is mutable, iterator may be affected by the
28
+ current state of the original iterable.
29
+
30
+ .. tip::
31
+
32
+ Prefer immutable iterables over mutable ones.
33
+
34
+ """
35
+
36
+ from collections.abc import Callable, Iterable, Iterator
37
+ from pythonic_fp.gadgets.box import Box
38
+ from .merging import concat
39
+
40
+ __all__ = [
41
+ 'drop',
42
+ 'drop_while',
43
+ 'take',
44
+ 'take_while',
45
+ 'take_split',
46
+ 'take_while_split',
47
+ ]
48
+
49
+
50
+ def drop[D](iterable: Iterable[D], n: int) -> Iterator[D]:
51
+ """
52
+ .. admonition:: drop
53
+
54
+ Drop the next n items from iterable.
55
+
56
+ :param iterable: Iterable whose items are to be dropped.
57
+ :param n: Number of items to be dropped.
58
+ :yields: The remaining items.
59
+
60
+ """
61
+ iterator = iter(iterable)
62
+ for _ in range(n):
63
+ try:
64
+ next(iterator)
65
+ except StopIteration:
66
+ break
67
+ return iterator
68
+
69
+
70
+ def drop_while[D](iterable: Iterable[D], pred: Callable[[D], bool]) -> Iterator[D]:
71
+ """
72
+ .. admonition:: drop while
73
+
74
+ Drop initial items from iterable while predicate is true.
75
+
76
+ :param iterable: Iterable whose items are to be dropped.
77
+ :param pred: Single argument Boolean valued function.
78
+ :yields: items starting when ``pred`` returns ``False``.
79
+
80
+ """
81
+ iterator = iter(iterable)
82
+ while True:
83
+ try:
84
+ item = next(iterator)
85
+ if not pred(item):
86
+ iterator = concat((item,), iterator)
87
+ break
88
+ except StopIteration:
89
+ break
90
+ return iterator
91
+
92
+
93
+ def take[D](iterable: Iterable[D], n: int) -> Iterator[D]:
94
+ """
95
+ .. admonition:: take
96
+
97
+ Return an iterator yielding up to n items from an iterable.
98
+
99
+ :param Iterable: Iterable providing the items to be taken.
100
+ :param n: Number of items to be taken.
101
+ :yields: Up to n items from iterable.
102
+
103
+ """
104
+ iterator = iter(iterable)
105
+ for _ in range(n):
106
+ try:
107
+ item = next(iterator)
108
+ yield item
109
+ except StopIteration:
110
+ break
111
+
112
+
113
+ def take_while[D](iterable: Iterable[D], pred: Callable[[D], bool]) -> Iterator[D]:
114
+ """
115
+ .. admonition:: take while
116
+
117
+ Return an iterator of items until predicate false.
118
+
119
+ :param iterable: Iterable providing the items to be taken.
120
+ :param pred: Single argument Boolean valued function.
121
+ :yields: Items from iterable while predicate is true.
122
+
123
+ .. warning::
124
+
125
+ Risk of data loss if iterable is multiple referenced iterator.
126
+
127
+ """
128
+ iterator = iter(iterable)
129
+ while True:
130
+ try:
131
+ item = next(iterator)
132
+ if pred(item):
133
+ yield item
134
+ else:
135
+ break
136
+ except StopIteration:
137
+ break
138
+
139
+
140
+ def take_split[D](iterable: Iterable[D], n: int) -> tuple[Iterator[D], Iterator[D]]:
141
+ """
142
+ .. admonition:: take split
143
+
144
+ Same as take except also return an iterator of
145
+ the remaining items.
146
+
147
+ .. admonition:: CONTRACT
148
+
149
+ **IMPORTANT:** Do not access the second iterator until
150
+ the first one is completely exhausted.
151
+
152
+ :param iterable: Iterable providing the items to be taken.
153
+ :param n: maximum Number of items to be taken.
154
+ :returns: A tuple containing an iterator of items taken
155
+ and an iterator of remaining items.
156
+
157
+ """
158
+ iterator = iter(iterable)
159
+ itn = take(iterator, n)
160
+
161
+ return itn, iterator
162
+
163
+
164
+ def take_while_split[D](
165
+ iterable: Iterable[D], pred: Callable[[D], bool]
166
+ ) -> tuple[Iterator[D], Iterator[D]]:
167
+ """
168
+ .. admonition:: take while
169
+
170
+ Same as take_while except also return an iterator of
171
+ the remaining items.
172
+
173
+ .. admonition:: CONTRACT
174
+
175
+ **IMPORTANT:** Do not access the second iterator until
176
+ the first one is completely exhausted.
177
+
178
+ :param iterable: Iterable providing the items to be taken.
179
+ :param pred: Single argument Boolean valued function.
180
+ :returns: A tuple containing an iterator of items taken while
181
+ ``pred`` truthy and an iterator of remaining items.
182
+
183
+ """
184
+
185
+ def _take_while(
186
+ iterator: Iterator[D], pred: Callable[[D], bool], val: Box[D]
187
+ ) -> Iterator[D]:
188
+ while True:
189
+ try:
190
+ val.put(next(iterator))
191
+ if pred(val.get()):
192
+ yield val.pop()
193
+ else:
194
+ break
195
+ except StopIteration:
196
+ break
197
+
198
+ iterator = iter(iterable)
199
+ item: Box[D] = Box()
200
+ it_pred = _take_while(iterator, pred, item)
201
+
202
+ return it_pred, concat(item, iterator)