pythonic-fp.iterables 4.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
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
- Name: pythonic-fp.iterables
3
- Version: 4.0.0
2
+ Name: pythonic-fp-iterables
3
+ Version: 5.0.0
4
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,43 +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
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"
20
21
  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/API/development/build/html/releases.html
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 library of functions 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
38
+ - Assumptions
34
39
 
35
- #### Info:
36
-
37
- This library assumes that at all times iterator protocol
38
- is followed. This means that all iterators are iterable and
39
- that ``iter(some_iterator) is some_iterator``.
40
-
41
- #### Note:
40
+ - iterables are not necessarily iterators
41
+ - at all times iterator protocol is assumed to be followed
42
42
 
43
- Iterables are not necessarily iterators.
43
+ - all iterators are assumed to be iterable
44
+ - for all iterators ``foo`` we assume ``iter(foo) is foo``
44
45
 
45
- This PyPI project is part of of the grscheller
46
- [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>`_
47
48
 
48
- ## Documentation
49
+ Documentation
50
+ -------------
49
51
 
50
- Documentation for this PyPI projects is hosted on
51
- [GitHub Pages](https://grscheller.github.io/pythonic-fp/iterators/API/development/build/html/releases.html).
52
+ Documentation for this project is hosted on
53
+ `GitHub Pages
54
+ <https://grscheller.github.io/pythonic-fp/iterables/development/build/html>`_.
52
55
 
53
- ## Copyright and License
56
+ Copyright and License
57
+ ---------------------
54
58
 
55
59
  Copyright (c) 2023-2025 Geoffrey R. Scheller. Licensed under the Apache
56
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 = "4.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
35
  Changelog = "https://github.com/grscheller/pythonic-fp-iterables/blob/main/CHANGELOG.rst"
27
- Documentation = "https://grscheller.github.io/pythonic-fp/iterables/API/development/build/html/releases.html"
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", "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"]
@@ -48,18 +53,15 @@ enabled = true
48
53
  live-mode = true
49
54
  strict = true
50
55
  report_progress = true
51
- exclude = ["tests/.*"]
52
56
 
53
57
  [tool.pytest.ini_options]
54
58
  consider_namespace_packages = true
55
- testpaths = ["tests"]
59
+ testpaths = ["tests/"]
56
60
  addopts = "-ra"
57
61
 
58
62
  [tool.ruff]
59
63
  target-version = "py313"
60
-
61
- [tool.ruff.lint.per-file-ignores]
62
- "__init__.py" = ["F401"]
64
+ ignore = ["E741"]
63
65
 
64
66
  [tool.ruff.lint.flake8-quotes]
65
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))