pythonic-fp.containers 4.1.0__tar.gz → 6.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.
Files changed (33) hide show
  1. pythonic_fp_containers-6.0.0/PKG-INFO +51 -0
  2. pythonic_fp_containers-6.0.0/README.md +25 -0
  3. {pythonic_fp_containers-4.1.0 → pythonic_fp_containers-6.0.0}/pyproject.toml +43 -25
  4. {pythonic_fp_containers-4.1.0 → pythonic_fp_containers-6.0.0}/src/pythonic_fp/containers/functional_tuple.py +15 -8
  5. {pythonic_fp_containers-4.1.0 → pythonic_fp_containers-6.0.0}/src/pythonic_fp/containers/immutable_list.py +18 -17
  6. pythonic_fp_containers-4.1.0/.github/workflows/static.yml +0 -64
  7. pythonic_fp_containers-4.1.0/.gitignore +0 -9
  8. pythonic_fp_containers-4.1.0/CHANGELOG.rst +0 -676
  9. pythonic_fp_containers-4.1.0/PKG-INFO +0 -62
  10. pythonic_fp_containers-4.1.0/README.rst +0 -35
  11. pythonic_fp_containers-4.1.0/docs/Makefile +0 -78
  12. pythonic_fp_containers-4.1.0/docs/gen_conf.py +0 -110
  13. pythonic_fp_containers-4.1.0/docs/requirements.txt +0 -2
  14. pythonic_fp_containers-4.1.0/docs/source/_static/.gitkeep +0 -0
  15. pythonic_fp_containers-4.1.0/docs/source/_static/custom.css +0 -3
  16. pythonic_fp_containers-4.1.0/docs/source/_templates/.gitkeep +0 -0
  17. pythonic_fp_containers-4.1.0/docs/source/api/functional_tuple.rst +0 -6
  18. pythonic_fp_containers-4.1.0/docs/source/api/immutable_list.rst +0 -6
  19. pythonic_fp_containers-4.1.0/docs/source/api/index.rst +0 -19
  20. pythonic_fp_containers-4.1.0/docs/source/changelog.rst +0 -7
  21. pythonic_fp_containers-4.1.0/docs/source/description.rst +0 -7
  22. pythonic_fp_containers-4.1.0/docs/source/index.rst +0 -30
  23. pythonic_fp_containers-4.1.0/docs/source/releases.rst +0 -22
  24. pythonic_fp_containers-4.1.0/docs/source/usage.rst +0 -21
  25. pythonic_fp_containers-4.1.0/src/pythonic_fp/containers/__init__.pyi +0 -0
  26. pythonic_fp_containers-4.1.0/src/pythonic_fp/containers/functional_tuple.pyi +0 -22
  27. pythonic_fp_containers-4.1.0/src/pythonic_fp/containers/immutable_list.pyi +0 -28
  28. pythonic_fp_containers-4.1.0/tests/test_functional_tuple.py +0 -174
  29. pythonic_fp_containers-4.1.0/tests/test_immutable_list.py +0 -152
  30. pythonic_fp_containers-4.1.0/tests/test_immutable_list_fp.py +0 -86
  31. {pythonic_fp_containers-4.1.0 → pythonic_fp_containers-6.0.0}/LICENSE +0 -0
  32. {pythonic_fp_containers-4.1.0 → pythonic_fp_containers-6.0.0}/src/pythonic_fp/containers/__init__.py +0 -0
  33. {pythonic_fp_containers-4.1.0 → pythonic_fp_containers-6.0.0}/src/pythonic_fp/containers/py.typed +0 -0
@@ -0,0 +1,51 @@
1
+ Metadata-Version: 2.4
2
+ Name: pythonic-fp-containers
3
+ Version: 6.0.0
4
+ Summary: Containers with FP interfaces.
5
+ Keywords: functional_containers,functional_tuple,immutable_list
6
+ Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
7
+ Requires-Python: >=3.14
8
+ Description-Content-Type: text/markdown
9
+ Classifier: Development Status :: 3 - Alpha
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.14
15
+ Classifier: Programming Language :: Python :: 3.15
16
+ Classifier: Typing :: Typed
17
+ License-File: LICENSE
18
+ Requires-Dist: pythonic-fp-circulararray>=6.4,<7
19
+ Requires-Dist: pythonic-fp-fptools>=6.2,<7
20
+ Requires-Dist: pythonic-fp-iterables>=6,<7
21
+ Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-containers/blob/main/CHANGELOG.md
22
+ Project-URL: Documentation, https://grscheller.github.io/pythonic-fp-containers
23
+ Project-URL: Homepage, https://grscheller.github.io/pythonic-fp
24
+ Project-URL: Source, https://github.com/grscheller/pythonic-fp-containers
25
+
26
+ # Pythonic FP - Containers
27
+
28
+ Python package for containers of like data structures with functional
29
+ programming inspired tweaks.
30
+
31
+ PyPI project
32
+ [pythonic-fp-containers](https://pypi.org/project/pythonic-fp-containers).
33
+ Part of the
34
+ [pythonic-fp](https://grscheller.github.io/pythonic-fp)
35
+ PyPI projects.
36
+
37
+ ## Documentation
38
+
39
+ Documentation and other links for this project are hosted on
40
+ [GitHub Pages](https://grscheller.github.io/pythonic-fp-containers).
41
+
42
+ | module | class | name |
43
+ |:------ |:-----:|:---- |
44
+ | pythonic_fp.containers.functional_tuple | FTuple | Functional Tuple |
45
+ | pythonic_fp.containers.immutable_list | IList | Immutable List |
46
+
47
+ ## Copyright and License
48
+
49
+ Copyright (c) 2023-2026 Geoffrey R. Scheller. Licensed under the Apache
50
+ License, Version 2.0. See the LICENSE file for details.
51
+
@@ -0,0 +1,25 @@
1
+ # Pythonic FP - Containers
2
+
3
+ Python package for containers of like data structures with functional
4
+ programming inspired tweaks.
5
+
6
+ PyPI project
7
+ [pythonic-fp-containers](https://pypi.org/project/pythonic-fp-containers).
8
+ Part of the
9
+ [pythonic-fp](https://grscheller.github.io/pythonic-fp)
10
+ PyPI projects.
11
+
12
+ ## Documentation
13
+
14
+ Documentation and other links for this project are hosted on
15
+ [GitHub Pages](https://grscheller.github.io/pythonic-fp-containers).
16
+
17
+ | module | class | name |
18
+ |:------ |:-----:|:---- |
19
+ | pythonic_fp.containers.functional_tuple | FTuple | Functional Tuple |
20
+ | pythonic_fp.containers.immutable_list | IList | Immutable List |
21
+
22
+ ## Copyright and License
23
+
24
+ Copyright (c) 2023-2026 Geoffrey R. Scheller. Licensed under the Apache
25
+ License, Version 2.0. See the LICENSE file for details.
@@ -4,9 +4,10 @@ build-backend = "flit_core.buildapi"
4
4
 
5
5
  [project]
6
6
  name = "pythonic-fp-containers"
7
- version = "4.1.0"
8
- readme = "README.rst"
9
- requires-python = ">=3.13"
7
+ version = "6.0.0"
8
+ description = "Containers with FP interfaces."
9
+ readme = "README.md"
10
+ requires-python = ">=3.14" # floor: PEP 649/749 deferred annotations — class-level self-reference NameErrors on <3.14
10
11
  authors = [
11
12
  { name = "Geoffrey R. Scheller", email = "geoffrey@scheller.com" },
12
13
  ]
@@ -22,22 +23,26 @@ classifiers = [
22
23
  "License :: OSI Approved :: Apache Software License",
23
24
  "Operating System :: OS Independent",
24
25
  "Programming Language :: Python :: 3.14",
26
+ "Programming Language :: Python :: 3.15",
25
27
  "Typing :: Typed",
26
28
  ]
27
29
  dependencies = [
28
- "pythonic-fp-circulararray>=6.0.4",
29
- "pythonic-fp-fptools>=5.2.0",
30
- "pythonic-fp-iterables>=5.1.3",
30
+ "pythonic-fp-circulararray>=6.4,<7",
31
+ "pythonic-fp-fptools>=6.2,<7",
32
+ "pythonic-fp-iterables>=6,<7",
31
33
  ]
32
- dynamic = ["description"]
33
34
 
34
35
  [project.urls]
35
- Changelog = "https://github.com/grscheller/pythonic-fp-containers/blob/main/CHANGELOG.rst"
36
- Documentation = "https://grscheller.github.io/pythonic-fp/projects/containers.html"
37
- Homepage = "https://grscheller.github.io/pythonic-fp/"
36
+ Changelog = "https://github.com/grscheller/pythonic-fp-containers/blob/main/CHANGELOG.md"
37
+ Documentation ="https://grscheller.github.io/pythonic-fp-containers"
38
+ Homepage = "https://grscheller.github.io/pythonic-fp"
38
39
  Source = "https://github.com/grscheller/pythonic-fp-containers"
39
40
 
40
- [project.optional-dependencies]
41
+ [dependency-groups]
42
+ docs = [
43
+ "furo>=2025.12.19",
44
+ "sphinx>=9.1",
45
+ ]
41
46
  test = [
42
47
  "pytest>=8.4.1",
43
48
  ]
@@ -45,6 +50,22 @@ test = [
45
50
  [tool.flit.module]
46
51
  name = "pythonic_fp.containers"
47
52
 
53
+ [tool.flit.sdist]
54
+ exclude = [
55
+ "docs/",
56
+ "tests/",
57
+ "**/.mypy_cache/",
58
+ "**/.ruff_cache/",
59
+ "**/.pytest_cache/",
60
+ "**/__pycache__/",
61
+ "**/.dmypy.json",
62
+ ]
63
+
64
+ [tool.pytest]
65
+ addopts = ["-ra"]
66
+ consider_namespace_packages = true
67
+ testpaths = ["tests/"]
68
+
48
69
  [tool.mypy]
49
70
  explicit_package_bases = true
50
71
  local_partial_types = true
@@ -53,23 +74,16 @@ warn_redundant_casts = true
53
74
  warn_return_any = true
54
75
  warn_unused_configs = true
55
76
 
56
- [tool.pylsp-mypy]
57
- enabled = true
58
- live-mode = true
59
- dmypy = false
60
- strict = true
61
- report_progress = true
62
-
63
- [tool.pytest]
64
- addopts = [
65
- "-ra",
66
- ]
67
- consider_namespace_packages = true
68
- testpaths = ["tests/"]
77
+ [[tool.mypy.overrides]]
78
+ module = ["tests.*"]
79
+ strict_equality = false
69
80
 
70
81
  [tool.ruff]
71
82
  target-version = "py314"
72
83
 
84
+ [tool.ruff.lint]
85
+ ignore = ["RUF022", "E741"]
86
+
73
87
  [tool.ruff.lint.flake8-quotes]
74
88
  docstring-quotes = "double"
75
89
 
@@ -78,8 +92,12 @@ docstring-quotes = "double"
78
92
  "E731",
79
93
  "C901",
80
94
  ]
81
- "**/*.py" = ["E741"]
82
95
 
83
96
  [tool.ruff.format]
84
97
  quote-style = "single"
85
98
  docstring-code-line-length = 72
99
+
100
+ [tool.uv.sources]
101
+ pythonic-fp-circulararray = { path = "../pythonic-fp-circulararray", editable = true }
102
+ pythonic-fp-fptools = { path = "../pythonic-fp-fptools", editable = true }
103
+ pythonic-fp-iterables = { path = "../pythonic-fp-iterables", editable = true }
@@ -14,9 +14,10 @@
14
14
  # limitations under the License.
15
15
 
16
16
  from collections.abc import Callable, Iterator
17
- from typing import cast, Never, overload, SupportsIndex
17
+ from typing import SupportsIndex, cast, overload
18
+
18
19
  from pythonic_fp.iterables.folding import accumulate
19
- from pythonic_fp.iterables.merging import blend, concat, MergeEnum
20
+ from pythonic_fp.iterables.merging import MergeEnum, blend, concat
20
21
 
21
22
  __all__ = ['FTuple']
22
23
 
@@ -158,7 +159,7 @@ class FTuple[D](tuple[D, ...]):
158
159
  acc = f(v, acc)
159
160
  return acc
160
161
 
161
- def copy(self) -> 'FTuple[D]':
162
+ def copy(self) -> FTuple[D]:
162
163
  """
163
164
  .. admonition:: copy
164
165
 
@@ -173,7 +174,13 @@ class FTuple[D](tuple[D, ...]):
173
174
  def __add__(self, other: object, /) -> tuple[D, ...]:
174
175
  if not isinstance(other, tuple):
175
176
  msg = 'FTuple being added to something not an FTuple'
176
- raise ValueError(msg)
177
+ raise TypeError(msg)
178
+ return self.__class__(concat(self, other))
179
+
180
+ def __radd__(self, other: object, /) -> tuple[D, ...]:
181
+ if not isinstance(other, tuple):
182
+ msg = 'FTuple being added to something not an FTuple'
183
+ raise TypeError(msg)
177
184
  return self.__class__(concat(self, other))
178
185
 
179
186
  def __mul__(self, num: SupportsIndex) -> tuple[D, ...]:
@@ -184,7 +191,7 @@ class FTuple[D](tuple[D, ...]):
184
191
 
185
192
  def accummulate[L](
186
193
  self, f: Callable[[L, D], L], s: L | None = None, /
187
- ) -> 'FTuple[L]':
194
+ ) -> FTuple[L]:
188
195
  """
189
196
  .. admonition:: accumulate partial folds
190
197
 
@@ -197,7 +204,7 @@ class FTuple[D](tuple[D, ...]):
197
204
  return FTuple(accumulate(self, f))
198
205
  return FTuple(accumulate(self, f, s))
199
206
 
200
- def map[U](self, f: Callable[[D], U], /) -> 'FTuple[U]':
207
+ def map[U](self, f: Callable[[D], U], /) -> FTuple[U]:
201
208
  """
202
209
  .. admonition:: map
203
210
 
@@ -209,10 +216,10 @@ class FTuple[D](tuple[D, ...]):
209
216
 
210
217
  def bind[U](
211
218
  self,
212
- f: 'Callable[[D], FTuple[U]]',
219
+ f: Callable[[D], FTuple[U]],
213
220
  merge_type: MergeEnum = MergeEnum.Concat,
214
221
  yield_partials: bool = False,
215
- ) -> 'FTuple[U] | Never':
222
+ ) -> FTuple[U]:
216
223
  """
217
224
  .. admonition:: bind
218
225
 
@@ -12,10 +12,11 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from collections.abc import Callable, Iterable, Iterator, Hashable
16
- from typing import cast, Never, overload
15
+ from collections.abc import Callable, Hashable, Iterable, Iterator
16
+ from typing import cast, overload
17
+
17
18
  from pythonic_fp.iterables.folding import accumulate
18
- from pythonic_fp.iterables.merging import blend, concat, MergeEnum
19
+ from pythonic_fp.iterables.merging import MergeEnum, blend, concat
19
20
 
20
21
  __all__ = ['IList']
21
22
 
@@ -34,7 +35,7 @@ class IList[D](Hashable):
34
35
 
35
36
  """
36
37
 
37
- __slots__ = ('_ds', '_len', '_hash')
38
+ __slots__ = ('_ds', '_hash', '_len')
38
39
  __match_args__ = ('_ds', '_len')
39
40
 
40
41
  def __init__(self, *ds: Iterable[D]) -> None:
@@ -48,7 +49,7 @@ class IList[D](Hashable):
48
49
  msg = f'IList expects at most 1 iterable argument, got {size}'
49
50
  raise ValueError(msg)
50
51
  else:
51
- self._ds: tuple[D, ...] = tuple(ds[0]) if size == 1 else tuple()
52
+ self._ds: tuple[D, ...] = tuple(ds[0]) if size == 1 else ()
52
53
  self._len = len(self._ds)
53
54
  try:
54
55
  self._hash = hash((self._len, 42) + self._ds)
@@ -118,9 +119,9 @@ class IList[D](Hashable):
118
119
  @overload
119
120
  def __getitem__(self, idx: int, /) -> D: ...
120
121
  @overload
121
- def __getitem__(self, idx: slice, /) -> 'IList[D]': ...
122
+ def __getitem__(self, idx: slice, /) -> IList[D]: ...
122
123
 
123
- def __getitem__(self, idx: slice | int, /) -> 'IList[D] | D':
124
+ def __getitem__(self, idx: slice | int, /) -> IList[D] | D:
124
125
  """
125
126
  .. admonition:: getitem
126
127
 
@@ -222,7 +223,7 @@ class IList[D](Hashable):
222
223
  acc = f(v, acc)
223
224
  return acc
224
225
 
225
- def __add__(self, other: 'IList[D]', /) -> 'IList[D]':
226
+ def __add__(self, other: IList[D], /) -> IList[D]:
226
227
  """
227
228
  .. admonition:: add by concatenation
228
229
 
@@ -237,11 +238,11 @@ class IList[D](Hashable):
237
238
  """
238
239
  if not isinstance(other, IList):
239
240
  msg = 'IList being added to something not an IList'
240
- raise ValueError(msg)
241
+ raise TypeError(msg)
241
242
 
242
243
  return IList(concat(self, other))
243
244
 
244
- def __mul__(self, num: int, /) -> 'IList[D]':
245
+ def __mul__(self, num: int, /) -> IList[D]:
245
246
  """
246
247
  .. admonition:: add by concatenation
247
248
 
@@ -255,9 +256,9 @@ class IList[D](Hashable):
255
256
  Maybe define a "column vector" version?
256
257
 
257
258
  """
258
- return IList(self._ds.__mul__(num if num > 0 else 0))
259
+ return IList(self._ds.__mul__(max(0, num)))
259
260
 
260
- def __rmul__(self, num: int, /) -> 'IList[D]':
261
+ def __rmul__(self, num: int, /) -> IList[D]:
261
262
  """
262
263
  .. admonition:: concatenation with itself
263
264
 
@@ -267,11 +268,11 @@ class IList[D](Hashable):
267
268
  :raises ValueError: When ``other`` is not an ``IList``.
268
269
 
269
270
  """
270
- return IList(self._ds.__mul__(num if num > 0 else 0))
271
+ return IList(self._ds.__mul__(max(0, num)))
271
272
 
272
273
  def accummulate[L](
273
274
  self, f: Callable[[L, D], L], s: L | None = None, /
274
- ) -> 'IList[L]':
275
+ ) -> IList[L]:
275
276
  """
276
277
  .. admonition:: accumulate partial folds
277
278
 
@@ -287,7 +288,7 @@ class IList[D](Hashable):
287
288
  return IList(accumulate(self, f))
288
289
  return IList(accumulate(self, f, s))
289
290
 
290
- def map[U](self, f: Callable[[D], U], /) -> 'IList[U]':
291
+ def map[U](self, f: Callable[[D], U], /) -> IList[U]:
291
292
  """
292
293
  .. admonition:: map
293
294
 
@@ -299,10 +300,10 @@ class IList[D](Hashable):
299
300
 
300
301
  def bind[U](
301
302
  self,
302
- f: 'Callable[[D], IList[U]]',
303
+ f: Callable[[D], IList[U]],
303
304
  merge_enum: MergeEnum = MergeEnum.Concat,
304
305
  yield_partials: bool = False,
305
- ) -> 'IList[U] | Never':
306
+ ) -> IList[U]:
306
307
  """
307
308
  .. admonition:: bind
308
309
 
@@ -1,64 +0,0 @@
1
- name: Build and Deploy Furo Themed Sphinx Documentation
2
-
3
- on:
4
- push:
5
- branches: ["main"]
6
- workflow_dispatch:
7
-
8
- env:
9
- RELEASE: '4.1.0'
10
- DEVEL: '5.0.0'
11
- PYTHON: '3.14'
12
-
13
- permissions:
14
- contents: read
15
- pages: write
16
- id-token: write
17
-
18
- concurrency:
19
- group: "pages"
20
- cancel-in-progress: false
21
-
22
- jobs:
23
- deploy:
24
- runs-on: ubuntu-latest
25
- environment:
26
- name: github-pages
27
- url: ${{ steps.deployment.outputs.page_url }}
28
- steps:
29
- - name: Checkout
30
- uses: actions/checkout@v6
31
-
32
- - name: Select Python
33
- uses: actions/setup-python@v6
34
- with:
35
- python-version: ${{ env.PYTHON }}
36
-
37
- - name: Install Sphinx Dependencies
38
- run: |
39
- pip install -r docs/requirements.txt
40
- sudo apt-get install -y graphviz
41
-
42
- - name: Build Release Docs
43
- run: |
44
- pip install pythonic-fp-circulararray
45
- docs/gen_conf.py release ${{ env.RELEASE }} Containers containers > docs/source/conf.py
46
- sphinx-build -M html docs/source docs/build/release
47
-
48
- - name: Build Development Docs
49
- run: |
50
- pip install -e .
51
- docs/gen_conf.py devel ${{ env.DEVEL }} Containers containers > docs/source/conf.py
52
- sphinx-build -M html docs/source docs/build/development
53
-
54
- - name: Setup Pages
55
- uses: actions/configure-pages@v6
56
-
57
- - name: Upload Artifact
58
- uses: actions/upload-pages-artifact@v5
59
- with:
60
- path: docs/build
61
-
62
- - name: Deploy to GitHub Pages
63
- uses: actions/deploy-pages@v5
64
- id: deployment
@@ -1,9 +0,0 @@
1
- # Minimal version - only add to when necessary
2
- **/__pycache__/
3
- dist/
4
- docs/build/
5
- docs/source/conf.py
6
- **/.dmypy.json
7
- **/.mypy_cache/
8
- **/.pytest_cache/
9
- **/.ruff_cache