pythonic-fp.iterables 3.0.0__tar.gz → 5.0.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.
@@ -0,0 +1,6 @@
1
+ # Minimal version - only add to when necessary
2
+ **/__pycache__/
3
+ dist/
4
+ **/.mypy_cache/
5
+ **/.pytest_cache/
6
+ **/.ruff_cache
@@ -0,0 +1,190 @@
1
+ CHANGELOG
2
+ =========
3
+
4
+ PyPI pythonic-fp.iterables project.
5
+
6
+ Semantic Versioning
7
+ -------------------
8
+
9
+ Strict 3 digit semantic versioning adopted 2025-05-19.
10
+
11
+ - **MAJOR** version incremented for incompatible API changes
12
+ - **MINOR** version incremented for backward compatible added functionality
13
+ - **PATCH** version incremented for backward compatible bug fixes
14
+
15
+ See `Semantic Versioning 2.0.0 <https://semver.org>`_.
16
+
17
+ Releases and Important Milestones
18
+ ---------------------------------
19
+
20
+ 4.0.0 - 2025-07-16
21
+ ~~~~~~~~~~~~~~~~~~
22
+
23
+ Primary purpose was to bring Sphinx documentation in alignment
24
+ with other pythonic-fp projects. Ended up making substantial
25
+ Sphinx documentation improvements. Will use this documentation
26
+ for the other pythonic-fp projects.
27
+
28
+ - API change
29
+
30
+ - renamed pythonic_fp.iterables.foldl to pythonic_fp.iterables.fold_left
31
+
32
+ 3.0.0 - 2025-07-06
33
+ ~~~~~~~~~~~~~~~~~~
34
+
35
+ First PyPI release as ``pythonic-fp.iterables``
36
+
37
+ - dropping dtools namespace name because there is a repo by that name.
38
+
39
+ 2.0.0 - 2025-05-22
40
+ ~~~~~~~~~~~~~~~~~~
41
+
42
+ - Moved dtools.fp.iterables to its own PyPI project
43
+
44
+ - dtools.iterables
45
+
46
+ - Moved dtools.fp.err_handling to the dtools.containers PyPI project
47
+
48
+ - Moved class MayBe -> module dtools.containers.maybe
49
+ - Moved class Xor -> module dtools.containers.xor
50
+ - dropped lazy methods
51
+
52
+ - will import dtools.fp.lazy directly for this functionality
53
+
54
+ 1.7.0 - 2025-04-22
55
+ ~~~~~~~~~~~~~~~~~~
56
+
57
+ Last PyPI release as dtools.fp
58
+
59
+ - API changes along the lines of dtools.ca 3.12
60
+ - typing improvements
61
+ - docstring changes
62
+ - pyproject.toml standardization
63
+
64
+ 1.6.0 - 2025-04-07
65
+ ~~~~~~~~~~~~~~~~~~
66
+
67
+ - typing improvements
68
+
69
+ 1.4.0 - 2025-03-16
70
+ ~~~~~~~~~~~~~~~~~~
71
+
72
+ - much work dtools.iterables
73
+
74
+ - finally implemented scReduceL and scReduceR functions
75
+ - tweaked API across iterables module
76
+
77
+ 1.3.0 - 2025-01-17
78
+ ~~~~~~~~~~~~~~~~~~
79
+
80
+ First release as dtools.fp
81
+
82
+ Repo name changes.
83
+
84
+ - GitHub: fp -> dtools-fp
85
+ - PyPI: grscheller.fp -> dtools.fp
86
+
87
+ 1.0.1 - 2024-10-20
88
+ ~~~~~~~~~~~~~~~~~~
89
+
90
+ - removed docs from repo
91
+ - docs for all grscheller namespace projects maintained here
92
+
93
+ - https://grscheller.github.io/grscheller-pypi-namespace-docs/
94
+
95
+ 1.0.0 - 2024-10-18
96
+ ~~~~~~~~~~~~~~~~~~
97
+
98
+ Decided to make this release first stable release.
99
+
100
+ - renamed module fp.woException to fp.err_handling
101
+ - pytest improvements based on pytest documentation
102
+
103
+ 0.4.0 - 2024-10-03
104
+ ~~~~~~~~~~~~~~~~~~
105
+
106
+ Long overdue PyPI release.
107
+
108
+ 0.3.4.0 - 2024-09-30
109
+ ~~~~~~~~~~~~~~~~~~~~
110
+
111
+ Development environment only.
112
+
113
+ - API change for fp.iterables
114
+
115
+ - function name changes
116
+
117
+ - ``foldL``, ``foldR``, ``foldLsc``, ``foldRsc``
118
+ - ``sc`` stands for "short circuit"
119
+
120
+ - all now return class woException.MB
121
+
122
+ 0.3.3.7 - 2024-09-22
123
+ ~~~~~~~~~~~~~~~~~~~~
124
+
125
+ Development environment only.
126
+
127
+ - added more functions to fp.iterables module
128
+
129
+ - take(it: Iterable[D], n: int) -> Iterator[D]
130
+ - takeWhile(it: Iterable[D], pred: Callable\[[D], bool\]) -> Iterator[D]
131
+ - drop(it: Iterable[D], n: int) -> Iterator[D]
132
+ - dropWhile(it: Iterable[D], pred: Callable\[[D], bool\]) -> Iterator[D]
133
+
134
+ 0.3.3.4 - 2024-09-16
135
+ ~~~~~~~~~~~~~~~~~~~~
136
+
137
+ Development environment only.
138
+
139
+ - fp.iterables ``foldL_sc`` & ``foldR_sc`` now have
140
+
141
+ - common paradigm
142
+ - similar signatures
143
+
144
+ 0.3.3.3 - 2024-09-15
145
+ ~~~~~~~~~~~~~~~~~~~~
146
+
147
+ Development environment only.
148
+
149
+ - added fp.iterables function ``foldR_sc``
150
+
151
+ - shortcut version of ``foldR``
152
+ - not fully tested
153
+ - docstring not updated
154
+
155
+ 0.3.3.2 - 2024-09-14
156
+ ~~~~~~~~~~~~~~~~~~~~
157
+
158
+ Development environment only.
159
+
160
+ - added fp.iterables function ``foldL_sc``
161
+
162
+ - shortcut version of foldL
163
+
164
+ 0.3.1 - 2024-08-20
165
+ ~~~~~~~~~~~~~~~~~~
166
+
167
+ Now fp.iterables no longer exports ``CONCAT``, ``MERGE``, ``EXHAUST``.
168
+
169
+ - for grscheller.datastructures
170
+
171
+ - grscheller.datastructures.ftuple
172
+ - grscheller.datastructures.split_ends
173
+
174
+ 0.2.0 - 2024-07-26
175
+ ~~~~~~~~~~~~~~~~~~
176
+
177
+ - from last PyPI release
178
+
179
+ - added accumulate function to fp.iterators
180
+
181
+ - overall much better docstrings
182
+
183
+ 0.1.0 - 2024-07-11
184
+ ~~~~~~~~~~~~~~~~~~
185
+
186
+ Initial PyPI release as grscheller.fp
187
+
188
+ Replicated functionality from grscheller.datastructures.
189
+
190
+ - ``grscheller.core.iterlib -> grscheller.fp.iterators``
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
- Name: pythonic-fp.iterables
3
- Version: 3.0.0
4
- Summary: Module fp.iterables - Iterator related tools
2
+ Name: pythonic-fp-iterables
3
+ Version: 5.0.0
4
+ Summary: Library of functions for iterating iterables.
5
5
  Keywords: iterables,iterators
6
6
  Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
7
7
  Requires-Python: >=3.12
8
- Description-Content-Type: text/markdown
8
+ Description-Content-Type: text/x-rst
9
9
  Classifier: Development Status :: 5 - Production/Stable
10
10
  Classifier: Framework :: Pytest
11
11
  Classifier: Intended Audience :: Developers
@@ -14,38 +14,47 @@ Classifier: Operating System :: OS Independent
14
14
  Classifier: Programming Language :: Python :: 3.13
15
15
  Classifier: Typing :: Typed
16
16
  License-File: LICENSE
17
- Requires-Dist: pythonic-fp.circulararray>=5.0.0
18
- Requires-Dist: pythonic-fp.containers >=2.0.0
19
- Requires-Dist: pythonic-fp.fptools >=3.0.0
20
- Project-URL: Changelog, https://grscheller.github.io/pythonic-fp-iterables/html/changelog.html
21
- Project-URL: Documentation, https://grscheller.github.io/pythonic-fp-iterables/html/
17
+ Requires-Dist: pythonic-fp-fptools>=5.0.0
18
+ Requires-Dist: pythonic-fp>=1.1.0
19
+ Requires-Dist: pythonic-fp-singletons>=1.0.0
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
22
23
  Project-URL: Homepage, https://github.com/grscheller/pythonic-fp/blob/main/README.md
23
24
  Project-URL: Source, https://github.com/grscheller/pythonic-fp-iterables
25
+ Provides-Extra: test
24
26
 
25
- # Pythonic FP - Tools for iterables
27
+ Pythonic FP - Tools for iterables
28
+ =================================
26
29
 
27
30
  PyPI project
28
- [pythonic-fp.iterators](https://pypi.org/project/pythonic-fp.iterables/)
29
- implementing a Python package of tools for iterables and iterators.
31
+ `pythonic-fp.iterators <https://pypi.org/project/pythonic-fp.iterables>`_.
32
+
33
+ Library of functions for iterating iterables.
30
34
 
31
35
  - Concatenating and merging iterables
32
36
  - Dropping and taking values from iterables
33
37
  - Reducing and accumulating iterables
34
38
  - Assumptions
39
+
35
40
  - iterables are not necessarily iterators
36
41
  - at all times iterator protocol is assumed to be followed
42
+
37
43
  - all iterators are assumed to be iterable
38
- - for all iterators `my_iter` we assume `iter(my_iter) is my_iter`
44
+ - for all iterators ``foo`` we assume ``iter(foo) is foo``
39
45
 
40
- This PyPI project is part of of the grscheller
41
- [pythonic-fp namespace projects](https://github.com/grscheller/pythonic-fp/blob/main/README.md).
46
+ This PyPI project is part of of the
47
+ `pythonic-fp namespace projects <https://github.com/grscheller/pythonic-fp/blob/main/README.md>`_
42
48
 
43
- ## Documentation
49
+ Documentation
50
+ -------------
44
51
 
45
- Documentation hosted on
46
- [GitHub Pages](https://grscheller.github.io/pythonic-fp-iterables/html).
52
+ Documentation for this project is hosted on
53
+ `GitHub Pages
54
+ <https://grscheller.github.io/pythonic-fp/iterables/development/build/html>`_.
47
55
 
48
- ## Copyright and License
56
+ Copyright and License
57
+ ---------------------
49
58
 
50
59
  Copyright (c) 2023-2025 Geoffrey R. Scheller. Licensed under the Apache
51
60
  License, Version 2.0. See the LICENSE file for details.
@@ -0,0 +1,34 @@
1
+ Pythonic FP - Tools for iterables
2
+ =================================
3
+
4
+ PyPI project
5
+ `pythonic-fp.iterators <https://pypi.org/project/pythonic-fp.iterables>`_.
6
+
7
+ Library of functions for iterating iterables.
8
+
9
+ - Concatenating and merging iterables
10
+ - Dropping and taking values from iterables
11
+ - Reducing and accumulating iterables
12
+ - Assumptions
13
+
14
+ - iterables are not necessarily iterators
15
+ - at all times iterator protocol is assumed to be followed
16
+
17
+ - all iterators are assumed to be iterable
18
+ - for all iterators ``foo`` we assume ``iter(foo) is foo``
19
+
20
+ This PyPI project is part of of the
21
+ `pythonic-fp namespace projects <https://github.com/grscheller/pythonic-fp/blob/main/README.md>`_
22
+
23
+ Documentation
24
+ -------------
25
+
26
+ Documentation for this project is hosted on
27
+ `GitHub Pages
28
+ <https://grscheller.github.io/pythonic-fp/iterables/development/build/html>`_.
29
+
30
+ Copyright and License
31
+ ---------------------
32
+
33
+ Copyright (c) 2023-2025 Geoffrey R. Scheller. Licensed under the Apache
34
+ License, Version 2.0. See the LICENSE file for details.
@@ -1,7 +1,11 @@
1
+ [build-system]
2
+ requires = ["flit_core>=3.12,<4"]
3
+ build-backend = "flit_core.buildapi"
4
+
1
5
  [project]
2
- name = "pythonic-fp.iterables"
3
- version = "3.0.0"
4
- readme = "README.md"
6
+ name = "pythonic-fp-iterables"
7
+ version = "5.0.0"
8
+ readme = "README.rst"
5
9
  requires-python = ">=3.12"
6
10
  license = { file = "LICENSE" }
7
11
  authors = [{ name = "Geoffrey R. Scheller", email = "geoffrey@scheller.com" }]
@@ -16,24 +20,25 @@ classifiers = [
16
20
  "Typing :: Typed",
17
21
  ]
18
22
  dependencies = [
19
- "pythonic-fp.circulararray>=5.0.0",
20
- "pythonic-fp.containers >=2.0.0",
21
- "pythonic-fp.fptools >=3.0.0",
23
+ "pythonic-fp-fptools>=5.0.0",
24
+ "pythonic-fp>=1.1.0",
25
+ "pythonic-fp-singletons>=1.0.0",
22
26
  ]
23
27
  dynamic = ["description"]
24
28
 
29
+ [project.optional-dependencies]
30
+ test = [
31
+ "pytest>=8.4.1",
32
+ ]
33
+
25
34
  [project.urls]
26
- Changelog = "https://grscheller.github.io/pythonic-fp-iterables/html/changelog.html"
27
- Documentation = "https://grscheller.github.io/pythonic-fp-iterables/html/"
35
+ Changelog = "https://github.com/grscheller/pythonic-fp-iterables/blob/main/CHANGELOG.rst"
36
+ Documentation = "https://grscheller.github.io/pythonic-fp/iterables/development/build/html/releases.html"
28
37
  Homepage = "https://github.com/grscheller/pythonic-fp/blob/main/README.md"
29
38
  Source = "https://github.com/grscheller/pythonic-fp-iterables"
30
39
 
31
- [build-system]
32
- requires = ["flit_core>=3.12,<4"]
33
- build-backend = "flit_core.buildapi"
34
-
35
- [tool.flit.sdist]
36
- exclude = ["dist", "docs", "tests", ".gitignore", ".mypy_cache", ".pytest_cache"]
40
+ [tool.flit.module]
41
+ name = "pythonic_fp.iterables"
37
42
 
38
43
  [tool.mypy]
39
44
  enable_incomplete_feature = ["NewGenericSyntax"]
@@ -43,31 +48,20 @@ warn_redundant_casts = true
43
48
  warn_return_any = true
44
49
  warn_unused_configs = true
45
50
 
46
- [tool.pylsp]
47
- python_path = [
48
- "/home/grs/devel/pypi/fptools/pythonic-fp-iterables/src",
49
- "/home/grs/devel/pypi/fptools/pythonic-fp-circulararray/src",
50
- "/home/grs/devel/pypi/fptools/pythonic-fp-containers/src",
51
- "/home/grs/devel/pypi/fptools/pythonic-fp-fptools/src",
52
- ]
53
-
54
51
  [tool.pylsp-mypy]
55
52
  enabled = true
56
53
  live-mode = true
57
54
  strict = true
58
55
  report_progress = true
59
- exclude = ["tests/.*"]
60
56
 
61
57
  [tool.pytest.ini_options]
62
58
  consider_namespace_packages = true
63
- testpaths = ["tests"]
59
+ testpaths = ["tests/"]
64
60
  addopts = "-ra"
65
61
 
66
62
  [tool.ruff]
67
63
  target-version = "py313"
68
-
69
- [tool.ruff.lint.per-file-ignores]
70
- "__init__.py" = ["F401"]
64
+ ignore = ["E741"]
71
65
 
72
66
  [tool.ruff.lint.flake8-quotes]
73
67
  docstring-quotes = "double"
@@ -0,0 +1,39 @@
1
+ # Copyright 2023-2024 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
+ """Library of functions for iterating iterables.
16
+
17
+ +-----------+-------------------------------------------+
18
+ | Module | Description |
19
+ +===========+===========================================+
20
+ | merging | Concatenating and merging iterables |
21
+ +-----------+-------------------------------------------+
22
+ | drop_take | Dropping and taking values from iterables |
23
+ +-----------+-------------------------------------------+
24
+ | folding | Reducing and accumulating iterables |
25
+ +-----------+-------------------------------------------+
26
+
27
+ Assumptions:
28
+
29
+ - iterables are not necessarily iterators
30
+ - at all times iterator protocol is assumed to be followed
31
+
32
+ - all iterators are assumed to be iterable
33
+ - for all iterators ``foobar`` we assume ``iter(foobar) is foobar``
34
+
35
+ """
36
+
37
+ __author__ = 'Geoffrey R. Scheller'
38
+ __copyright__ = 'Copyright (c) 2023-2025 Geoffrey R. Scheller'
39
+ __license__ = 'Apache License 2.0'
@@ -0,0 +1,177 @@
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.drop_take"""
16
+
17
+ from __future__ import annotations
18
+
19
+ __author__ = 'Geoffrey R. Scheller'
20
+ __copyright__ = 'Copyright (c) 2023-2025 Geoffrey R. Scheller'
21
+ __license__ = 'Apache License 2.0'
22
+
23
+ from collections.abc import Callable, Iterable, Iterator
24
+ from pythonic_fp.gadgets.box import Box
25
+ from .merging import concat
26
+
27
+ __all__ = [
28
+ 'drop',
29
+ 'drop_while',
30
+ 'take',
31
+ 'take_while',
32
+ 'take_split',
33
+ 'take_while_split',
34
+ ]
35
+
36
+
37
+ ## dropping and taking
38
+
39
+
40
+ def drop[D](iterable: Iterable[D], n: int) -> Iterator[D]:
41
+ """Drop the next n values from iterable.
42
+
43
+ :param iterable: iterable whose values are to be dropped
44
+ :param n: number of values to be dropped
45
+ :return: an iterator of the remaining values
46
+
47
+ """
48
+ iterator = iter(iterable)
49
+ for _ in range(n):
50
+ try:
51
+ next(iterator)
52
+ except StopIteration:
53
+ break
54
+ return iterator
55
+
56
+
57
+ def drop_while[D](
58
+ iterable: Iterable[D],
59
+ pred: Callable[[D], bool]
60
+ ) -> Iterator[D]:
61
+ """Drop initial values from iterable while predicate is true.
62
+
63
+ :param iterable: iterable whose values are to be dropped
64
+ :param pred: Boolean valued function, the "predicate"
65
+ :return: an iterator beginning where pred returned false
66
+
67
+ """
68
+ iterator = iter(iterable)
69
+ while True:
70
+ try:
71
+ value = next(iterator)
72
+ if not pred(value):
73
+ iterator = concat((value,), iterator)
74
+ break
75
+ except StopIteration:
76
+ break
77
+ return iterator
78
+
79
+
80
+ def take[D](iterable: Iterable[D], n: int) -> Iterator[D]:
81
+ """Return an iterator of up to n initial values of an iterable.
82
+
83
+ :param iterable: iterable providing the values to be taken
84
+ :param n: number of values to be dropped
85
+ :return: an iterator of up to n initial values from iterable
86
+
87
+ """
88
+ iterator = iter(iterable)
89
+ for _ in range(n):
90
+ try:
91
+ value = next(iterator)
92
+ yield value
93
+ except StopIteration:
94
+ break
95
+
96
+
97
+ def take_while[D](
98
+ iterable: Iterable[D],
99
+ pred: Callable[[D], bool]
100
+ ) -> Iterator[D]:
101
+ """Yield values from iterable while predicate is true.
102
+
103
+ .. warning::
104
+ Risk of value loss if iterable is multiple referenced iterator.
105
+
106
+ :param iterable: iterable providing the values to be taken
107
+ :param pred: Boolean valued function, the "predicate"
108
+ :return: an Iterator of of values from iterable until predicate false
109
+
110
+ """
111
+ iterator = iter(iterable)
112
+ while True:
113
+ try:
114
+ value = next(iterator)
115
+ if pred(value):
116
+ yield value
117
+ else:
118
+ break
119
+ except StopIteration:
120
+ break
121
+
122
+
123
+ def take_split[D](
124
+ iterable: Iterable[D],
125
+ n: int
126
+ ) -> tuple[Iterator[D], Iterator[D]]:
127
+ """Same as take except also return iterator of remaining values.
128
+
129
+ .. Warning::
130
+
131
+ **CONTRACT:** Do not access the second returned iterator until the
132
+ first one is exhausted.
133
+
134
+ :param iterable: iterable providing the values to be taken
135
+ :param n: maximum number of values to be taken
136
+ :return: an iterator of values taken and an iterator of remaining values
137
+
138
+ """
139
+ iterator = iter(iterable)
140
+ itn = take(iterator, n)
141
+
142
+ return itn, iterator
143
+
144
+
145
+ def take_while_split[D](
146
+ iterable: Iterable[D], pred: Callable[[D], bool]
147
+ ) -> tuple[Iterator[D], Iterator[D]]:
148
+ """Yield values from iterable while predicate is true.
149
+
150
+ .. Warning::
151
+
152
+ **CONTRACT:** Do not access the second returned iterator until
153
+ the first one is exhausted.
154
+
155
+ :param iterable: iterable providing the values to be taken
156
+ :param pred: Boolean valued function
157
+ :return: tuple containing an iterator of values taken and an iterator of remaining values
158
+
159
+ """
160
+ def _take_while(
161
+ iterator: Iterator[D], pred: Callable[[D], bool], val: Box[D]
162
+ ) -> Iterator[D]:
163
+ while True:
164
+ try:
165
+ val.put(next(iterator))
166
+ if pred(val.get()):
167
+ yield val.pop()
168
+ else:
169
+ break
170
+ except StopIteration:
171
+ break
172
+
173
+ iterator = iter(iterable)
174
+ value: Box[D] = Box()
175
+ it_pred = _take_while(iterator, pred, value)
176
+
177
+ return (it_pred, concat(value, iterator))