pythonic-fp.containers 3.0.0__tar.gz → 3.0.1__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 (24) hide show
  1. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/.gitignore +1 -0
  2. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/PKG-INFO +8 -9
  3. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/README.rst +1 -1
  4. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/pyproject.toml +28 -23
  5. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/src/pythonic_fp/containers/__init__.py +0 -4
  6. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/src/pythonic_fp/containers/functional_tuple.py +20 -26
  7. pythonic_fp_containers-3.0.1/src/pythonic_fp/containers/functional_tuple.pyi +58 -0
  8. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/src/pythonic_fp/containers/immutable_list.py +16 -20
  9. pythonic_fp_containers-3.0.1/src/pythonic_fp/containers/immutable_list.pyi +72 -0
  10. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/src/pythonic_fp/containers/queues/de.py +2 -4
  11. pythonic_fp_containers-3.0.1/src/pythonic_fp/containers/queues/de.pyi +45 -0
  12. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/src/pythonic_fp/containers/queues/fifo.py +2 -4
  13. pythonic_fp_containers-3.0.1/src/pythonic_fp/containers/queues/fifo.pyi +44 -0
  14. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/src/pythonic_fp/containers/queues/lifo.py +2 -4
  15. pythonic_fp_containers-3.0.1/src/pythonic_fp/containers/queues/lifo.pyi +40 -0
  16. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/tests/queues/test_queues.py +1 -1
  17. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/tests/test_functional_tuple.py +1 -1
  18. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/tests/test_immutable_list.py +0 -2
  19. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/tests/test_immutable_list_fp.py +0 -1
  20. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/CHANGELOG.rst +0 -0
  21. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/LICENSE +0 -0
  22. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/src/pythonic_fp/containers/py.typed +0 -0
  23. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/src/pythonic_fp/containers/queues/__init__.py +0 -0
  24. {pythonic_fp_containers-3.0.0 → pythonic_fp_containers-3.0.1}/src/pythonic_fp/containers/queues/py.typed +0 -0
@@ -1,6 +1,7 @@
1
1
  # Minimal version - only add to when necessary
2
2
  **/__pycache__/
3
3
  dist/
4
+ **/.dmypy.json
4
5
  **/.mypy_cache/
5
6
  **/.pytest_cache/
6
7
  **/.ruff_cache
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-containers
3
- Version: 3.0.0
3
+ Version: 3.0.1
4
4
  Summary: Package of container like data structures.
5
- Keywords: boxes,functional_tuple,immutable_list,queue,fifo,lifo,dqueue,dequeue
5
+ Keywords: boxes,dequeue,dqueue,fifo,functional_tuple,immutable_list,lifo,queue
6
6
  Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
7
7
  Requires-Python: >=3.12
8
8
  Description-Content-Type: text/x-rst
9
- Classifier: Development Status :: 5 - Production/Stable
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
@@ -14,12 +14,11 @@ 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.3.0
18
- Requires-Dist: pythonic-fp-fptools>=5.0.0
19
- Requires-Dist: pythonic-fp-iterables>=5.0.0
20
- Requires-Dist: pythonic-fp-singletons>=1.0.0
17
+ Requires-Dist: pythonic-fp-circulararray>=5.3.2
18
+ Requires-Dist: pythonic-fp-fptools>=5.1.0
19
+ Requires-Dist: pythonic-fp-iterables>=5.1.0
21
20
  Requires-Dist: pytest>=8.4.1 ; extra == "test"
22
- Requires-Dist: pythonic-fp-splitends>=1.0.0 ; extra == "test"
21
+ Requires-Dist: pythonic-fp-splitends>=1.0.1 ; extra == "test"
23
22
  Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-containers/blob/main/CHANGELOG.rst
24
23
  Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/containers/development/build/html/releases.html
25
24
  Project-URL: Homepage, https://github.com/grscheller/pythonic-fp/blob/main/README.md
@@ -37,8 +36,8 @@ Python package of container like data structures.
37
36
  +------------------+------------------------------------------------------+
38
37
  | Description | Module |
39
38
  +==================+======================================================+
40
- | Single item box | *module* ``pythonic_fp.containers.box`` |
41
39
  | Functional tuple | *module* ``pythonic_fp.containers.functional_tuple`` |
40
+ +------------------+------------------------------------------------------+
42
41
  | Immutable list | *module* ``pythonic_fp.containers.immutable_list`` |
43
42
  +------------------+------------------------------------------------------+
44
43
 
@@ -9,8 +9,8 @@ Python package of container like data structures.
9
9
  +------------------+------------------------------------------------------+
10
10
  | Description | Module |
11
11
  +==================+======================================================+
12
- | Single item box | *module* ``pythonic_fp.containers.box`` |
13
12
  | Functional tuple | *module* ``pythonic_fp.containers.functional_tuple`` |
13
+ +------------------+------------------------------------------------------+
14
14
  | Immutable list | *module* ``pythonic_fp.containers.immutable_list`` |
15
15
  +------------------+------------------------------------------------------+
16
16
 
@@ -1,26 +1,22 @@
1
- [build-system]
2
- requires = ["flit_core>=3.12,<4"]
3
- build-backend = "flit_core.buildapi"
4
-
5
1
  [project]
6
2
  name = "pythonic-fp-containers"
7
- version = "3.0.0"
3
+ version = "3.0.1"
8
4
  readme = "README.rst"
9
5
  requires-python = ">=3.12"
10
6
  license = { file = "LICENSE" }
11
7
  authors = [{ name = "Geoffrey R. Scheller", email = "geoffrey@scheller.com" }]
12
8
  keywords = [
13
9
  "boxes",
10
+ "dequeue",
11
+ "dqueue",
12
+ "fifo",
14
13
  "functional_tuple",
15
14
  "immutable_list",
16
- "queue",
17
- "fifo",
18
15
  "lifo",
19
- "dqueue",
20
- "dequeue",
16
+ "queue",
21
17
  ]
22
18
  classifiers = [
23
- "Development Status :: 5 - Production/Stable",
19
+ "Development Status :: 4 - Beta",
24
20
  "Framework :: Pytest",
25
21
  "Intended Audience :: Developers",
26
22
  "License :: OSI Approved :: Apache Software License",
@@ -29,32 +25,37 @@ classifiers = [
29
25
  "Typing :: Typed",
30
26
  ]
31
27
  dependencies = [
32
- "pythonic-fp-circulararray>= 5.3.0",
33
- "pythonic-fp-fptools>=5.0.0",
34
- "pythonic-fp-iterables>=5.0.0",
35
- "pythonic-fp-singletons>=1.0.0",
28
+ "pythonic-fp-circulararray>=5.3.2",
29
+ "pythonic-fp-fptools>=5.1.0",
30
+ "pythonic-fp-iterables>=5.1.0",
36
31
  ]
37
32
  dynamic = ["description"]
38
33
 
39
- [project.optional-dependencies]
40
- test = [
41
- "pytest>=8.4.1",
42
- "pythonic-fp-splitends>=1.0.0",
43
- ]
44
-
45
34
  [project.urls]
46
35
  Changelog = "https://github.com/grscheller/pythonic-fp-containers/blob/main/CHANGELOG.rst"
47
36
  Documentation = "https://grscheller.github.io/pythonic-fp/containers/development/build/html/releases.html"
48
37
  Homepage = "https://github.com/grscheller/pythonic-fp/blob/main/README.md"
49
38
  Source = "https://github.com/grscheller/pythonic-fp-containers"
50
39
 
40
+ [project.optional-dependencies]
41
+ test = [
42
+ "pytest>=8.4.1",
43
+ "pythonic-fp-splitends>=1.0.1",
44
+ ]
45
+
46
+ [build-system]
47
+ requires = ["flit_core>=3.12,<4"]
48
+ build-backend = "flit_core.buildapi"
49
+
51
50
  [tool.flit.module]
52
51
  name = "pythonic_fp.containers"
53
52
 
54
53
  [tool.mypy]
55
- enable_incomplete_feature = ["NewGenericSyntax"]
54
+ enable_incomplete_feature = "NewGenericSyntax"
55
+ explicit_package_bases = true
56
56
  implicit_reexport = false
57
57
  local_partial_types = true
58
+ namespace_packages = true
58
59
  warn_redundant_casts = true
59
60
  warn_return_any = true
60
61
  warn_unused_configs = true
@@ -62,21 +63,25 @@ warn_unused_configs = true
62
63
  [tool.pylsp-mypy]
63
64
  enabled = true
64
65
  live-mode = true
66
+ dmypy = false
65
67
  strict = true
66
68
  report_progress = true
67
69
 
68
70
  [tool.pytest.ini_options]
71
+ addopts = "-ra"
69
72
  consider_namespace_packages = true
70
73
  testpaths = ["tests/"]
71
- addopts = "-ra"
72
74
 
73
75
  [tool.ruff]
74
76
  target-version = "py313"
75
- ignore = ["E741"]
76
77
 
77
78
  [tool.ruff.lint.flake8-quotes]
78
79
  docstring-quotes = "double"
79
80
 
81
+ [tool.ruff.lint.per-file-ignores]
82
+ "tests/*" = ["C901"]
83
+ "**/*.py" = ["E741"]
84
+
80
85
  [tool.ruff.format]
81
86
  quote-style = "single"
82
87
  docstring-code-line-length = 72
@@ -24,10 +24,6 @@
24
24
  | Queues | | package ``pythonic_fp.containers.queues`` |
25
25
  +------------------+--------+----------------------------------------------------+
26
26
 
27
- .. note::
28
-
29
- Module ``box`` has been moved to ``pythonic_fp.gadgets.box``.
30
-
31
27
  """
32
28
 
33
29
  __author__ = 'Geoffrey R. Scheller'
@@ -14,10 +14,8 @@
14
14
 
15
15
  """Pythonic FP - Functional Tuple"""
16
16
 
17
- from __future__ import annotations
18
-
19
17
  from collections.abc import Callable, Iterator
20
- from typing import cast, Never, overload, TypeVar
18
+ from typing import cast, Never, overload, TypeVar, SupportsIndex
21
19
  from pythonic_fp.iterables.folding import accumulate
22
20
  from pythonic_fp.iterables.merging import blend, concat, MergeEnum
23
21
 
@@ -25,6 +23,7 @@ __all__ = ['FTuple']
25
23
 
26
24
  D = TypeVar('D', covariant=True)
27
25
 
26
+
28
27
  class FTuple[D](tuple[D, ...]):
29
28
  """Functional Tuple suitable for inheritance
30
29
 
@@ -40,6 +39,7 @@ class FTuple[D](tuple[D, ...]):
40
39
  - Since these tuples are homogeneous, their covariance may be quirky
41
40
 
42
41
  """
42
+
43
43
  def __reversed__(self) -> Iterator[D]:
44
44
  for ii in range(len(self) - 1, -1, -1):
45
45
  yield (self[ii])
@@ -59,17 +59,14 @@ class FTuple[D](tuple[D, ...]):
59
59
  return False
60
60
  return True
61
61
 
62
- @overload # type:ignore
63
- def __getitem__(self, x: int) -> D: ...
64
62
  @overload
65
- def __getitem__(self, x: slice) -> tuple[D, ...]: ...
66
-
67
- def __getitem__(self, idx: int | slice, /) -> tuple[D, ...] | D:
68
- def newtup(tup: tuple[D, ...]) -> tuple[D, ...]:
69
- return tup[0:-1] + tup[-1:]
63
+ def __getitem__(self, idx: SupportsIndex) -> D: ...
64
+ @overload
65
+ def __getitem__(self, idx: slice) -> tuple[D, ...]: ...
70
66
 
67
+ def __getitem__(self, idx: SupportsIndex | slice) -> tuple[D, ...] | D:
71
68
  if isinstance(idx, slice):
72
- return self.__class__(newtup(super().__getitem__(idx)))
69
+ return self.__class__(super().__getitem__(idx))
73
70
  else:
74
71
  return super().__getitem__(idx)
75
72
 
@@ -131,25 +128,25 @@ class FTuple[D](tuple[D, ...]):
131
128
  acc = f(v, acc)
132
129
  return acc
133
130
 
134
- def copy(self) -> FTuple[D]:
131
+ def copy(self) -> 'FTuple[D]':
135
132
  """Return a shallow copy of ``FTuple`` in O(1) time & space complexity."""
136
133
  return self.__class__(self)
137
134
 
138
135
  def __add__(self, other: object, /) -> tuple[D, ...]:
139
- if not isinstance(other, FTuple):
136
+ if not isinstance(other, tuple):
140
137
  msg = 'FTuple being added to something not an FTuple'
141
138
  raise ValueError(msg)
142
139
  return self.__class__(concat(self, other))
143
140
 
144
- def __mul__(self, num: int, /) -> tuple[D, ...]:
141
+ def __mul__(self, num: SupportsIndex) -> tuple[D, ...]:
145
142
  return self.__class__(super().__mul__(num))
146
143
 
147
- def __rmul__(self, num: int, /) -> tuple[D]:
144
+ def __rmul__(self, num: SupportsIndex) -> tuple[D, ...]:
148
145
  return self.__class__(super().__rmul__(num))
149
146
 
150
147
  def accummulate[L](
151
148
  self, f: Callable[[L, D], L], s: L | None = None, /
152
- ) -> FTuple[L]:
149
+ ) -> 'FTuple[L]':
153
150
  """Accumulate partial folds
154
151
 
155
152
  Accumulate partial fold results in an ``FTuple`` with an optional
@@ -160,14 +157,15 @@ class FTuple[D](tuple[D, ...]):
160
157
  return FTuple(accumulate(self, f))
161
158
  return FTuple(accumulate(self, f, s))
162
159
 
163
- def map[U](self, f: Callable[[D], U], /) -> FTuple[U]:
160
+ def map[U](self, f: Callable[[D], U], /) -> 'FTuple[U]':
164
161
  return FTuple(map(f, self))
165
162
 
166
163
  def bind[U](
167
- self, f: Callable[[D], FTuple[U]],
168
- merge_enum: MergeEnum = MergeEnum.Concat,
169
- yield_partials: bool = False,
170
- ) -> FTuple[U] | Never:
164
+ self,
165
+ f: 'Callable[[D], FTuple[U]]',
166
+ merge_enum: MergeEnum = MergeEnum.Concat,
167
+ yield_partials: bool = False,
168
+ ) -> 'FTuple[U] | Never':
171
169
  """Bind function ``f`` to the ``FTuple``.
172
170
 
173
171
  :param ds: values to instantiate FTuple
@@ -176,9 +174,5 @@ class FTuple[D](tuple[D, ...]):
176
174
 
177
175
  """
178
176
  return FTuple(
179
- blend(
180
- *map(f, self),
181
- merge_enum=merge_enum,
182
- yield_partials=yield_partials
183
- )
177
+ blend(*map(f, self), merge_enum=merge_enum, yield_partials=yield_partials)
184
178
  )
@@ -0,0 +1,58 @@
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
+ from collections.abc import Callable, Iterator
16
+ from typing import Never, overload, TypeVar, SupportsIndex
17
+ from pythonic_fp.iterables.merging import MergeEnum
18
+
19
+ __all__ = ['FTuple']
20
+
21
+ D = TypeVar('D', covariant=True)
22
+
23
+ class FTuple[D](tuple[D, ...]):
24
+ def __reversed__(self) -> Iterator[D]: ...
25
+ def __repr__(self) -> str: ...
26
+ def __eq__(self, other: object, /) -> bool: ...
27
+ @overload
28
+ def __getitem__(self, idx: SupportsIndex) -> D: ...
29
+ @overload
30
+ def __getitem__(self, idx: slice) -> tuple[D, ...]: ...
31
+ def foldl[L](
32
+ self,
33
+ f: Callable[[L, D], L],
34
+ /,
35
+ start: L | None = None,
36
+ default: L | None = None,
37
+ ) -> L | None: ...
38
+ def foldr[R](
39
+ self,
40
+ f: Callable[[D, R], R],
41
+ /,
42
+ start: R | None = None,
43
+ default: R | None = None,
44
+ ) -> R | None: ...
45
+ def copy(self) -> FTuple[D]: ...
46
+ def __add__(self, other: object, /) -> tuple[D, ...]: ...
47
+ def __mul__(self, num: SupportsIndex) -> tuple[D, ...]: ...
48
+ def __rmul__(self, num: SupportsIndex) -> tuple[D, ...]: ...
49
+ def accummulate[L](
50
+ self, f: Callable[[L, D], L], s: L | None = None, /
51
+ ) -> FTuple[L]: ...
52
+ def map[U](self, f: Callable[[D], U], /) -> FTuple[U]: ...
53
+ def bind[U](
54
+ self,
55
+ f: Callable[[D], FTuple[U]],
56
+ merge_enum: MergeEnum = MergeEnum.Concat,
57
+ yield_partials: bool = False,
58
+ ) -> FTuple[U] | Never: ...
@@ -23,8 +23,6 @@
23
23
 
24
24
  """
25
25
 
26
- from __future__ import annotations
27
-
28
26
  from collections.abc import Callable, Iterable, Iterator, Hashable
29
27
  from typing import cast, Never, overload, TypeVar
30
28
  from pythonic_fp.iterables.folding import accumulate
@@ -35,6 +33,7 @@ __all__ = ['IList']
35
33
  D = TypeVar('D', covariant=True)
36
34
  T = TypeVar('T')
37
35
 
36
+
38
37
  class IList[D](Hashable):
39
38
  """Immutable List like data structure.
40
39
 
@@ -45,6 +44,7 @@ class IList[D](Hashable):
45
44
  - both left and right int multiplication supported
46
45
 
47
46
  """
47
+
48
48
  __slots__ = ('_ds', '_len', '_hash')
49
49
  __match_args__ = ('_ds', '_len')
50
50
 
@@ -98,9 +98,9 @@ class IList[D](Hashable):
98
98
  @overload
99
99
  def __getitem__(self, idx: int, /) -> D: ...
100
100
  @overload
101
- def __getitem__(self, idx: slice, /) -> IList[D]: ...
101
+ def __getitem__(self, idx: slice, /) -> 'IList[D]': ...
102
102
 
103
- def __getitem__(self, idx: slice | int, /) -> IList[D] | D:
103
+ def __getitem__(self, idx: slice | int, /) -> 'IList[D] | D':
104
104
  if isinstance(idx, slice):
105
105
  return IList(self._ds[idx])
106
106
  return self._ds[idx]
@@ -116,7 +116,7 @@ class IList[D](Hashable):
116
116
 
117
117
  - fold left with an optional starting value
118
118
  - first argument of function ``f`` is for the accumulated value
119
-
119
+
120
120
  "raises ValueError: when empty and a start value not given
121
121
 
122
122
  """
@@ -167,22 +167,22 @@ class IList[D](Hashable):
167
167
  acc = f(v, acc)
168
168
  return acc
169
169
 
170
- def __add__(self, other: IList[D], /) -> IList[D]:
170
+ def __add__(self, other: 'IList[D]', /) -> 'IList[D]':
171
171
  if not isinstance(other, IList):
172
172
  msg = 'IList being added to something not a IList'
173
173
  raise ValueError(msg)
174
174
 
175
175
  return IList(concat(self, other))
176
176
 
177
- def __mul__(self, num: int, /) -> IList[D]:
177
+ def __mul__(self, num: int, /) -> 'IList[D]':
178
178
  return IList(self._ds.__mul__(num if num > 0 else 0))
179
179
 
180
- def __rmul__(self, num: int, /) -> IList[D]:
180
+ def __rmul__(self, num: int, /) -> 'IList[D]':
181
181
  return IList(self._ds.__mul__(num if num > 0 else 0))
182
182
 
183
183
  def accummulate[L](
184
184
  self, f: Callable[[L, D], L], s: L | None = None, /
185
- ) -> IList[L]:
185
+ ) -> 'IList[L]':
186
186
  """Accumulate partial folds
187
187
 
188
188
  Accumulate partial fold results in an IList with
@@ -193,15 +193,15 @@ class IList[D](Hashable):
193
193
  return IList(accumulate(self, f))
194
194
  return IList(accumulate(self, f, s))
195
195
 
196
- def map[U](self, f: Callable[[D], U], /) -> IList[U]:
196
+ def map[U](self, f: Callable[[D], U], /) -> 'IList[U]':
197
197
  return IList(map(f, self))
198
198
 
199
199
  def bind[U](
200
- self,
201
- f: Callable[[D], IList[U]],
202
- merge_enum: MergeEnum = MergeEnum.Concat,
203
- yield_partials: bool = False,
204
- ) -> IList[U] | Never:
200
+ self,
201
+ f: 'Callable[[D], IList[U]]',
202
+ merge_enum: MergeEnum = MergeEnum.Concat,
203
+ yield_partials: bool = False,
204
+ ) -> 'IList[U] | Never':
205
205
  """Bind function `f` to the `IList`.
206
206
 
207
207
  :param ds: values to instantiate IList
@@ -210,9 +210,5 @@ class IList[D](Hashable):
210
210
 
211
211
  """
212
212
  return IList(
213
- blend(
214
- *map(f, self),
215
- merge_enum=merge_enum,
216
- yield_partials=yield_partials
217
- )
213
+ blend(*map(f, self), merge_enum=merge_enum, yield_partials=yield_partials)
218
214
  )
@@ -0,0 +1,72 @@
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
+ from collections.abc import Callable, Iterable, Iterator, Hashable
16
+ from typing import Never, overload, TypeVar
17
+ from pythonic_fp.iterables.merging import MergeEnum
18
+
19
+ __all__ = ['IList']
20
+
21
+ D = TypeVar('D', covariant=True)
22
+ T = TypeVar('T')
23
+
24
+
25
+ class IList[D](Hashable):
26
+ __slots__ = ('_ds', '_len', '_hash')
27
+ __match_args__ = ('_ds', '_len')
28
+
29
+ L = TypeVar('L')
30
+ R = TypeVar('R')
31
+ U = TypeVar('U')
32
+
33
+ def __init__(self, *dss: Iterable[D]) -> None: ...
34
+ def __hash__(self) -> int: ...
35
+ def __iter__(self) -> Iterator[D]: ...
36
+ def __reversed__(self) -> Iterator[D]: ...
37
+ def __bool__(self) -> bool: ...
38
+ def __len__(self) -> int: ...
39
+ def __repr__(self) -> str: ...
40
+ def __str__(self) -> str: ...
41
+ def __eq__(self, other: object, /) -> bool: ...
42
+ @overload
43
+ def __getitem__(self, idx: int, /) -> D: ...
44
+ @overload
45
+ def __getitem__(self, idx: slice, /) -> IList[D]: ...
46
+ def foldl[L](
47
+ self,
48
+ f: Callable[[L, D], L],
49
+ /,
50
+ start: L | None = None,
51
+ default: L | None = None,
52
+ ) -> L | None: ...
53
+ def foldr[R](
54
+ self,
55
+ f: Callable[[D, R], R],
56
+ /,
57
+ start: R | None = None,
58
+ default: R | None = None,
59
+ ) -> R | None: ...
60
+ def __add__(self, other: IList[D], /) -> IList[D]: ...
61
+ def __mul__(self, num: int, /) -> IList[D]: ...
62
+ def __rmul__(self, num: int, /) -> IList[D]: ...
63
+ def accummulate[L](
64
+ self, f: Callable[[L, D], L], s: L | None = None, /
65
+ ) -> IList[L]: ...
66
+ def map[U](self, f: Callable[[D], U], /) -> IList[U]: ...
67
+ def bind[U](
68
+ self,
69
+ f: Callable[[D], IList[U]],
70
+ merge_enum: MergeEnum = MergeEnum.Concat,
71
+ yield_partials: bool = False,
72
+ ) -> IList[U] | Never: ...
@@ -22,8 +22,6 @@
22
22
  - neither indexable nor sliceable by design
23
23
 
24
24
  """
25
- from __future__ import annotations
26
-
27
25
  from collections.abc import Callable, Iterable, Iterator
28
26
  from typing import TypeVar
29
27
  from pythonic_fp.circulararray.auto import CA
@@ -76,7 +74,7 @@ class DEQueue[D]:
76
74
  def __str__(self) -> str:
77
75
  return '>< ' + ' | '.join(map(str, self)) + ' ><'
78
76
 
79
- def copy(self) -> DEQueue[D]:
77
+ def copy(self) -> 'DEQueue[D]':
80
78
  """Shallow copy.
81
79
 
82
80
  :return: shallow copy of the DEQueue
@@ -166,7 +164,7 @@ class DEQueue[D]:
166
164
  return MayBe()
167
165
  return MayBe(self._ca.foldr(f, start))
168
166
 
169
- def map[U](self, f: Callable[[D], U]) -> DEQueue[U]:
167
+ def map[U](self, f: Callable[[D], U]) -> 'DEQueue[U]':
170
168
  """Map f over the DEQueue left to right, retain original order.
171
169
 
172
170
  :return: new DEQueue instance
@@ -0,0 +1,45 @@
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
+ from collections.abc import Callable, Iterable, Iterator
16
+ from typing import TypeVar
17
+ from pythonic_fp.fptools.maybe import MayBe
18
+
19
+ __all__ = ['DEQueue', 'de_queue']
20
+
21
+ D = TypeVar('D')
22
+
23
+ class DEQueue[D]:
24
+ __slots__ = ('_ca',)
25
+
26
+ def __init__(self, *dss: Iterable[D]) -> None: ...
27
+ def __bool__(self) -> bool: ...
28
+ def __len__(self) -> int: ...
29
+ def __eq__(self, other: object) -> bool: ...
30
+ def __iter__(self) -> Iterator[D]: ...
31
+ def __reversed__(self) -> Iterator[D]: ...
32
+ def __repr__(self) -> str: ...
33
+ def __str__(self) -> str: ...
34
+ def copy(self) -> DEQueue[D]: ...
35
+ def pushl(self, *ds: D) -> None: ...
36
+ def pushr(self, *ds: D) -> None: ...
37
+ def popl(self) -> MayBe[D]: ...
38
+ def popr(self) -> MayBe[D]: ...
39
+ def peakl(self) -> MayBe[D]: ...
40
+ def peakr(self) -> MayBe[D]: ...
41
+ def foldl[L](self, f: Callable[[L, D], L], start: L | None = None) -> MayBe[L]: ...
42
+ def foldr[R](self, f: Callable[[D, R], R], start: R | None = None) -> MayBe[R]: ...
43
+ def map[U](self, f: Callable[[D], U]) -> DEQueue[U]: ...
44
+
45
+ def de_queue[D](*ds: D) -> DEQueue[D]: ...
@@ -22,8 +22,6 @@
22
22
  - O(1) length determination
23
23
 
24
24
  """
25
- from __future__ import annotations
26
-
27
25
  from collections.abc import Callable, Iterable, Iterator
28
26
  from typing import TypeVar
29
27
  from pythonic_fp.circulararray.auto import CA
@@ -72,7 +70,7 @@ class FIFOQueue[D]:
72
70
  def __str__(self) -> str:
73
71
  return '<< ' + ' < '.join(map(str, self)) + ' <<'
74
72
 
75
- def copy(self) -> FIFOQueue[D]:
73
+ def copy(self) -> 'FIFOQueue[D]':
76
74
  """Shallow copy.
77
75
 
78
76
  :return: shallow copy of the FIFOQueue
@@ -131,7 +129,7 @@ class FIFOQueue[D]:
131
129
  return MayBe()
132
130
  return MayBe(self._ca.foldl(f, start))
133
131
 
134
- def map[U](self, f: Callable[[D], U]) -> FIFOQueue[U]:
132
+ def map[U](self, f: Callable[[D], U]) -> 'FIFOQueue[U]':
135
133
  """Map f over the FIFOQueue, retain original order.
136
134
 
137
135
  :return: new FIFOQueue instance
@@ -0,0 +1,44 @@
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
+ from collections.abc import Callable, Iterable, Iterator
16
+ from typing import TypeVar
17
+ from pythonic_fp.circulararray.auto import CA
18
+ from pythonic_fp.fptools.maybe import MayBe
19
+
20
+ __all__ = ['FIFOQueue', 'fifo_queue']
21
+
22
+ D = TypeVar('D')
23
+
24
+
25
+ class FIFOQueue[D]:
26
+
27
+ __slots__ = ('_ca',)
28
+
29
+ def __init__(self, *dss: Iterable[D]) -> None: ...
30
+ def __bool__(self) -> bool: ...
31
+ def __len__(self) -> int: ...
32
+ def __eq__(self, other: object) -> bool: ...
33
+ def __iter__(self) -> Iterator[D]: ...
34
+ def __repr__(self) -> str: ...
35
+ def __str__(self) -> str: ...
36
+ def copy(self) -> FIFOQueue[D]: ...
37
+ def push(self, *ds: D) -> None: ...
38
+ def pop(self) -> MayBe[D]: ...
39
+ def peak_last_in(self) -> MayBe[D]: ...
40
+ def peak_next_out(self) -> MayBe[D]: ...
41
+ def fold[T](self, f: Callable[[T, D], T], start: T | None = None) -> MayBe[T]: ...
42
+ def map[U](self, f: Callable[[D], U]) -> FIFOQueue[U]: ...
43
+
44
+ def fifo_queue[D](*ds: D) -> FIFOQueue[D]: ...
@@ -22,8 +22,6 @@
22
22
  - O(1) length determination
23
23
 
24
24
  """
25
- from __future__ import annotations
26
-
27
25
  from collections.abc import Callable, Iterable, Iterator
28
26
  from typing import TypeVar
29
27
  from pythonic_fp.circulararray.auto import CA
@@ -73,7 +71,7 @@ class LIFOQueue[D]:
73
71
  def __str__(self) -> str:
74
72
  return '|| ' + ' > '.join(map(str, self)) + ' ><'
75
73
 
76
- def copy(self) -> LIFOQueue[D]:
74
+ def copy(self) -> 'LIFOQueue[D]':
77
75
  """Shallow copy.
78
76
 
79
77
  :return: shallow copy of the LIFOQueue
@@ -122,7 +120,7 @@ class LIFOQueue[D]:
122
120
  return MayBe()
123
121
  return MayBe(self._ca.foldr(swap(f), start))
124
122
 
125
- def map[U](self, f: Callable[[D], U]) -> LIFOQueue[U]:
123
+ def map[U](self, f: Callable[[D], U]) -> 'LIFOQueue[U]':
126
124
  """Map f over the LIFOQueue, retain original order.
127
125
 
128
126
  :return: new LIFOQueue instance
@@ -0,0 +1,40 @@
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
+ from collections.abc import Callable, Iterable, Iterator
16
+ from typing import TypeVar
17
+ from pythonic_fp.fptools.maybe import MayBe
18
+
19
+ __all__ = ['LIFOQueue', 'lifo_queue']
20
+
21
+ D = TypeVar('D')
22
+
23
+ class LIFOQueue[D]:
24
+ __slots__ = ('_ca',)
25
+
26
+ def __init__(self, *dss: Iterable[D]) -> None: ...
27
+ def __bool__(self) -> bool: ...
28
+ def __len__(self) -> int: ...
29
+ def __eq__(self, other: object) -> bool: ...
30
+ def __iter__(self) -> Iterator[D]: ...
31
+ def __repr__(self) -> str: ...
32
+ def __str__(self) -> str: ...
33
+ def copy(self) -> LIFOQueue[D]: ...
34
+ def push(self, *ds: D) -> None: ...
35
+ def pop(self) -> MayBe[D]: ...
36
+ def peak(self) -> MayBe[D]: ...
37
+ def fold[T](self, f: Callable[[T, D], T], start: T | None = None) -> MayBe[T]: ...
38
+ def map[U](self, f: Callable[[D], U]) -> LIFOQueue[U]: ...
39
+
40
+ def lifo_queue[D](*ds: D) -> LIFOQueue[D]: ...
@@ -12,7 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from __future__ import annotations
16
15
  from typing import Optional
17
16
  from pythonic_fp.circulararray.auto import ca
18
17
  from pythonic_fp.circulararray.fixed import caf
@@ -24,6 +23,7 @@ from pythonic_fp.containers.queues.lifo import LIFOQueue as LQ
24
23
  from pythonic_fp.containers.queues.lifo import lifo_queue as lq
25
24
  from pythonic_fp.fptools.maybe import MayBe
26
25
 
26
+
27
27
  class TestQueueTypes:
28
28
  def test_mutate_map(self) -> None:
29
29
  de1: DE[int] = DE()
@@ -12,10 +12,10 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from __future__ import annotations
16
15
  from pythonic_fp.containers.functional_tuple import FTuple as FT
17
16
  from pythonic_fp.iterables.merging import MergeEnum
18
17
 
18
+
19
19
  class TestFunctionalTuple:
20
20
  """FunctionalTuple test suite"""
21
21
  def test_method_returns_copy(self) -> None:
@@ -12,7 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from __future__ import annotations
16
15
  from pythonic_fp.containers.immutable_list import IList
17
16
  from pythonic_fp.iterables.merging import MergeEnum
18
17
 
@@ -27,7 +26,6 @@ class TestImmutableList:
27
26
  assert il2[2] == il2[5] == 0
28
27
  assert il1[2] is not None and il1[2] * 2 == il1[5] == 6
29
28
 
30
-
31
29
  def test_empty(self) -> None:
32
30
  """Test functionality"""
33
31
  il1: IList[int] = IList()
@@ -14,7 +14,6 @@
14
14
 
15
15
  """Test FP use cases"""
16
16
 
17
- from __future__ import annotations
18
17
  from pythonic_fp.containers.immutable_list import IList
19
18
  from pythonic_fp.splitends.splitend import SplitEnd as SE
20
19
  from pythonic_fp.iterables.merging import MergeEnum