pythonic-fp-circulararray 6.1.0__py3-none-any.whl → 6.2.0__py3-none-any.whl

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 (143) hide show
  1. pythonic_fp/circulararray/.mypy_cache/.gitignore +2 -0
  2. pythonic_fp/circulararray/.mypy_cache/3.13/@plugins_snapshot.json +1 -0
  3. pythonic_fp/circulararray/.mypy_cache/3.13/__future__.data.json +1 -0
  4. pythonic_fp/circulararray/.mypy_cache/3.13/__future__.meta.json +1 -0
  5. pythonic_fp/circulararray/.mypy_cache/3.13/_ast.data.json +1 -0
  6. pythonic_fp/circulararray/.mypy_cache/3.13/_ast.meta.json +1 -0
  7. pythonic_fp/circulararray/.mypy_cache/3.13/_codecs.data.json +1 -0
  8. pythonic_fp/circulararray/.mypy_cache/3.13/_codecs.meta.json +1 -0
  9. pythonic_fp/circulararray/.mypy_cache/3.13/_collections_abc.data.json +1 -0
  10. pythonic_fp/circulararray/.mypy_cache/3.13/_collections_abc.meta.json +1 -0
  11. pythonic_fp/circulararray/.mypy_cache/3.13/_frozen_importlib.data.json +1 -0
  12. pythonic_fp/circulararray/.mypy_cache/3.13/_frozen_importlib.meta.json +1 -0
  13. pythonic_fp/circulararray/.mypy_cache/3.13/_frozen_importlib_external.data.json +1 -0
  14. pythonic_fp/circulararray/.mypy_cache/3.13/_frozen_importlib_external.meta.json +1 -0
  15. pythonic_fp/circulararray/.mypy_cache/3.13/_io.data.json +1 -0
  16. pythonic_fp/circulararray/.mypy_cache/3.13/_io.meta.json +1 -0
  17. pythonic_fp/circulararray/.mypy_cache/3.13/_sitebuiltins.data.json +1 -0
  18. pythonic_fp/circulararray/.mypy_cache/3.13/_sitebuiltins.meta.json +1 -0
  19. pythonic_fp/circulararray/.mypy_cache/3.13/_typeshed/__init__.data.json +1 -0
  20. pythonic_fp/circulararray/.mypy_cache/3.13/_typeshed/__init__.meta.json +1 -0
  21. pythonic_fp/circulararray/.mypy_cache/3.13/_typeshed/importlib.data.json +1 -0
  22. pythonic_fp/circulararray/.mypy_cache/3.13/_typeshed/importlib.meta.json +1 -0
  23. pythonic_fp/circulararray/.mypy_cache/3.13/_warnings.data.json +1 -0
  24. pythonic_fp/circulararray/.mypy_cache/3.13/_warnings.meta.json +1 -0
  25. pythonic_fp/circulararray/.mypy_cache/3.13/abc.data.json +1 -0
  26. pythonic_fp/circulararray/.mypy_cache/3.13/abc.meta.json +1 -0
  27. pythonic_fp/circulararray/.mypy_cache/3.13/ast.data.json +1 -0
  28. pythonic_fp/circulararray/.mypy_cache/3.13/ast.meta.json +1 -0
  29. pythonic_fp/circulararray/.mypy_cache/3.13/builtins.data.json +1 -0
  30. pythonic_fp/circulararray/.mypy_cache/3.13/builtins.meta.json +1 -0
  31. pythonic_fp/circulararray/.mypy_cache/3.13/circulararray/__init__.data.json +1 -0
  32. pythonic_fp/circulararray/.mypy_cache/3.13/circulararray/__init__.meta.json +1 -0
  33. pythonic_fp/circulararray/.mypy_cache/3.13/circulararray/auto.data.json +1 -0
  34. pythonic_fp/circulararray/.mypy_cache/3.13/circulararray/auto.meta.json +1 -0
  35. pythonic_fp/circulararray/.mypy_cache/3.13/circulararray/fixed.data.json +1 -0
  36. pythonic_fp/circulararray/.mypy_cache/3.13/circulararray/fixed.meta.json +1 -0
  37. pythonic_fp/circulararray/.mypy_cache/3.13/codecs.data.json +1 -0
  38. pythonic_fp/circulararray/.mypy_cache/3.13/codecs.meta.json +1 -0
  39. pythonic_fp/circulararray/.mypy_cache/3.13/collections/__init__.data.json +1 -0
  40. pythonic_fp/circulararray/.mypy_cache/3.13/collections/__init__.meta.json +1 -0
  41. pythonic_fp/circulararray/.mypy_cache/3.13/collections/abc.data.json +1 -0
  42. pythonic_fp/circulararray/.mypy_cache/3.13/collections/abc.meta.json +1 -0
  43. pythonic_fp/circulararray/.mypy_cache/3.13/contextlib.data.json +1 -0
  44. pythonic_fp/circulararray/.mypy_cache/3.13/contextlib.meta.json +1 -0
  45. pythonic_fp/circulararray/.mypy_cache/3.13/dataclasses.data.json +1 -0
  46. pythonic_fp/circulararray/.mypy_cache/3.13/dataclasses.meta.json +1 -0
  47. pythonic_fp/circulararray/.mypy_cache/3.13/email/__init__.data.json +1 -0
  48. pythonic_fp/circulararray/.mypy_cache/3.13/email/__init__.meta.json +1 -0
  49. pythonic_fp/circulararray/.mypy_cache/3.13/email/_policybase.data.json +1 -0
  50. pythonic_fp/circulararray/.mypy_cache/3.13/email/_policybase.meta.json +1 -0
  51. pythonic_fp/circulararray/.mypy_cache/3.13/email/charset.data.json +1 -0
  52. pythonic_fp/circulararray/.mypy_cache/3.13/email/charset.meta.json +1 -0
  53. pythonic_fp/circulararray/.mypy_cache/3.13/email/contentmanager.data.json +1 -0
  54. pythonic_fp/circulararray/.mypy_cache/3.13/email/contentmanager.meta.json +1 -0
  55. pythonic_fp/circulararray/.mypy_cache/3.13/email/errors.data.json +1 -0
  56. pythonic_fp/circulararray/.mypy_cache/3.13/email/errors.meta.json +1 -0
  57. pythonic_fp/circulararray/.mypy_cache/3.13/email/header.data.json +1 -0
  58. pythonic_fp/circulararray/.mypy_cache/3.13/email/header.meta.json +1 -0
  59. pythonic_fp/circulararray/.mypy_cache/3.13/email/message.data.json +1 -0
  60. pythonic_fp/circulararray/.mypy_cache/3.13/email/message.meta.json +1 -0
  61. pythonic_fp/circulararray/.mypy_cache/3.13/email/policy.data.json +1 -0
  62. pythonic_fp/circulararray/.mypy_cache/3.13/email/policy.meta.json +1 -0
  63. pythonic_fp/circulararray/.mypy_cache/3.13/enum.data.json +1 -0
  64. pythonic_fp/circulararray/.mypy_cache/3.13/enum.meta.json +1 -0
  65. pythonic_fp/circulararray/.mypy_cache/3.13/genericpath.data.json +1 -0
  66. pythonic_fp/circulararray/.mypy_cache/3.13/genericpath.meta.json +1 -0
  67. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/__init__.data.json +1 -0
  68. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/__init__.meta.json +1 -0
  69. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/_abc.data.json +1 -0
  70. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/_abc.meta.json +1 -0
  71. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/_bootstrap.data.json +1 -0
  72. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/_bootstrap.meta.json +1 -0
  73. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/_bootstrap_external.data.json +1 -0
  74. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/_bootstrap_external.meta.json +1 -0
  75. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/abc.data.json +1 -0
  76. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/abc.meta.json +1 -0
  77. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/machinery.data.json +1 -0
  78. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/machinery.meta.json +1 -0
  79. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/metadata/__init__.data.json +1 -0
  80. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/metadata/__init__.meta.json +1 -0
  81. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/metadata/_meta.data.json +1 -0
  82. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/metadata/_meta.meta.json +1 -0
  83. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/readers.data.json +1 -0
  84. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/readers.meta.json +1 -0
  85. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/__init__.data.json +1 -0
  86. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/__init__.meta.json +1 -0
  87. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/_common.data.json +1 -0
  88. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/_common.meta.json +1 -0
  89. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/_functional.data.json +1 -0
  90. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/_functional.meta.json +1 -0
  91. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/abc.data.json +1 -0
  92. pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/abc.meta.json +1 -0
  93. pythonic_fp/circulararray/.mypy_cache/3.13/io.data.json +1 -0
  94. pythonic_fp/circulararray/.mypy_cache/3.13/io.meta.json +1 -0
  95. pythonic_fp/circulararray/.mypy_cache/3.13/os/__init__.data.json +1 -0
  96. pythonic_fp/circulararray/.mypy_cache/3.13/os/__init__.meta.json +1 -0
  97. pythonic_fp/circulararray/.mypy_cache/3.13/os/path.data.json +1 -0
  98. pythonic_fp/circulararray/.mypy_cache/3.13/os/path.meta.json +1 -0
  99. pythonic_fp/circulararray/.mypy_cache/3.13/pathlib/__init__.data.json +1 -0
  100. pythonic_fp/circulararray/.mypy_cache/3.13/pathlib/__init__.meta.json +1 -0
  101. pythonic_fp/circulararray/.mypy_cache/3.13/posixpath.data.json +1 -0
  102. pythonic_fp/circulararray/.mypy_cache/3.13/posixpath.meta.json +1 -0
  103. pythonic_fp/circulararray/.mypy_cache/3.13/re.data.json +1 -0
  104. pythonic_fp/circulararray/.mypy_cache/3.13/re.meta.json +1 -0
  105. pythonic_fp/circulararray/.mypy_cache/3.13/resource.data.json +1 -0
  106. pythonic_fp/circulararray/.mypy_cache/3.13/resource.meta.json +1 -0
  107. pythonic_fp/circulararray/.mypy_cache/3.13/sre_compile.data.json +1 -0
  108. pythonic_fp/circulararray/.mypy_cache/3.13/sre_compile.meta.json +1 -0
  109. pythonic_fp/circulararray/.mypy_cache/3.13/sre_constants.data.json +1 -0
  110. pythonic_fp/circulararray/.mypy_cache/3.13/sre_constants.meta.json +1 -0
  111. pythonic_fp/circulararray/.mypy_cache/3.13/sre_parse.data.json +1 -0
  112. pythonic_fp/circulararray/.mypy_cache/3.13/sre_parse.meta.json +1 -0
  113. pythonic_fp/circulararray/.mypy_cache/3.13/subprocess.data.json +1 -0
  114. pythonic_fp/circulararray/.mypy_cache/3.13/subprocess.meta.json +1 -0
  115. pythonic_fp/circulararray/.mypy_cache/3.13/sys/__init__.data.json +1 -0
  116. pythonic_fp/circulararray/.mypy_cache/3.13/sys/__init__.meta.json +1 -0
  117. pythonic_fp/circulararray/.mypy_cache/3.13/sys/_monitoring.data.json +1 -0
  118. pythonic_fp/circulararray/.mypy_cache/3.13/sys/_monitoring.meta.json +1 -0
  119. pythonic_fp/circulararray/.mypy_cache/3.13/types.data.json +1 -0
  120. pythonic_fp/circulararray/.mypy_cache/3.13/types.meta.json +1 -0
  121. pythonic_fp/circulararray/.mypy_cache/3.13/typing.data.json +1 -0
  122. pythonic_fp/circulararray/.mypy_cache/3.13/typing.meta.json +1 -0
  123. pythonic_fp/circulararray/.mypy_cache/3.13/typing_extensions.data.json +1 -0
  124. pythonic_fp/circulararray/.mypy_cache/3.13/typing_extensions.meta.json +1 -0
  125. pythonic_fp/circulararray/.mypy_cache/3.13/warnings.data.json +1 -0
  126. pythonic_fp/circulararray/.mypy_cache/3.13/warnings.meta.json +1 -0
  127. pythonic_fp/circulararray/.mypy_cache/3.13/zipfile/__init__.data.json +1 -0
  128. pythonic_fp/circulararray/.mypy_cache/3.13/zipfile/__init__.meta.json +1 -0
  129. pythonic_fp/circulararray/.mypy_cache/3.13/zipfile/_path/__init__.data.json +1 -0
  130. pythonic_fp/circulararray/.mypy_cache/3.13/zipfile/_path/__init__.meta.json +1 -0
  131. pythonic_fp/circulararray/.mypy_cache/3.13/zipimport.data.json +1 -0
  132. pythonic_fp/circulararray/.mypy_cache/3.13/zipimport.meta.json +1 -0
  133. pythonic_fp/circulararray/.mypy_cache/3.14/cache.db +0 -0
  134. pythonic_fp/circulararray/.mypy_cache/CACHEDIR.TAG +3 -0
  135. pythonic_fp/circulararray/auto.py +197 -106
  136. pythonic_fp/circulararray/auto.pyi +3 -3
  137. pythonic_fp/circulararray/fixed.py +194 -110
  138. pythonic_fp/circulararray/fixed.pyi +5 -5
  139. {pythonic_fp_circulararray-6.1.0.dist-info → pythonic_fp_circulararray-6.2.0.dist-info}/METADATA +16 -30
  140. pythonic_fp_circulararray-6.2.0.dist-info/RECORD +145 -0
  141. pythonic_fp_circulararray-6.1.0.dist-info/RECORD +0 -11
  142. {pythonic_fp_circulararray-6.1.0.dist-info → pythonic_fp_circulararray-6.2.0.dist-info}/WHEEL +0 -0
  143. {pythonic_fp_circulararray-6.1.0.dist-info → pythonic_fp_circulararray-6.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -13,7 +13,8 @@
13
13
  # limitations under the License.
14
14
 
15
15
  from collections.abc import Callable, Iterable, Iterator
16
- from typing import cast, Final, overload
16
+ from typing import Final, cast, overload
17
+
17
18
  from pythonic_fp.gadgets.sentinels.novalue import NoValue
18
19
 
19
20
  __all__ = ['CAF', 'caf']
@@ -22,28 +23,33 @@ nada: Final[NoValue] = NoValue()
22
23
 
23
24
 
24
25
  class CAF[X]:
25
-
26
26
  """
27
27
  .. admonition:: Fixed storage capacity circular array CAF
28
28
 
29
29
  - O(1) pops and pushes either end
30
30
  - O(1) indexing, does not support slicing
31
31
  - fixed total storage capacity
32
- - iterable but not threadsafe
32
+ - iterable (see __iter__ method below)
33
33
  - comparisons compare identity before equality, like builtins
34
- - in boolean context, falsy when either empty or full, otherwise truthy
35
- - function ``caf`` produces fixed capacity circular array from arguments
34
+ - in boolean context, falsy when either empty or full,
35
+ otherwise truthy
36
+ - function ``caf`` produces fixed capacity circular array
37
+ from arguments
36
38
 
37
39
  """
40
+
38
41
  __slots__ = '_xs', '_cnt', '_cap', '_front', '_rear'
39
42
 
40
43
  def __init__(self, *xs: Iterable[X], cap: int = 2) -> None:
41
44
  """
42
- :param xs: Takes 0 or 1 iterable parameters to initially
43
- populate the ``CAF`` left (front) to right (back).
44
- :param cap: Minimum fixed storage capacity of circular array.
45
- :raises ValueError: When more than one iterable is provided.
46
- :raises TypeError: When passed a non-iterable positional parameter.
45
+ .. admonition:: initializer
46
+
47
+ Populate ``CAF`` with an optional iterable
48
+ from front (left) to rear (right).
49
+
50
+ :param xs: Takes an optional iterable parameter.
51
+ :raises ValueError: When more than one parameter is provided.
52
+ :raises TypeError: When passed a non-iterable parameter.
47
53
 
48
54
  """
49
55
  cap = max(2, cap)
@@ -68,61 +74,48 @@ class CAF[X]:
68
74
  self._rear = cnt - 1
69
75
 
70
76
  def __bool__(self) -> bool:
77
+ """
78
+ .. admonition:: bool
79
+
80
+ - falsy if either empty or full
81
+ - truthy otherwise
82
+
83
+ :returns: ``True`` when partially filled,
84
+ ``False`` otherwise.
85
+
86
+ """
71
87
  return 0 < self._cnt < self._cap
72
88
 
73
89
  def __len__(self) -> int:
90
+ """
91
+ .. admonition:: length
92
+
93
+ Number of items in the ``CAF``.
94
+
95
+ :returns: The number of items in the ``CAF``.
96
+
97
+ """
74
98
  return self._cnt
75
99
 
76
- def __eq__(self, other: object) -> bool:
100
+ def __iter__(self) -> Iterator[X]:
77
101
  """
78
- .. admonition:: Equality comparison
102
+ .. admonition:: iterate
79
103
 
80
- Efficiently compare ``CAF`` to another object.
104
+ Iterates circular array, left (front) to right (rear).
81
105
 
82
- :param other: The object to be compared.
83
- :returns: ``True`` if ``other`` is another ``CAF`` whose
84
- contents compare as equal to the corresponding
85
- contents of the ``CAF``, otherwise ``False``.
106
+ :yields: The ``CA`` contents front to rear.
86
107
 
87
- """
88
- if self is other:
89
- return True
90
- if not isinstance(other, type(self)):
91
- return False
108
+ .. warning::
92
109
 
93
- (
94
- front1,
95
- cnt1,
96
- cap1,
97
- front2,
98
- cnt2,
99
- cap2,
100
- ) = (
101
- self._front,
102
- self._cnt,
103
- self._cap,
104
- other._front,
105
- other._cnt,
106
- other._cap,
107
- )
110
+ Not threadsafe, especially for long living iterators.
108
111
 
109
- if cnt1 != cnt2:
110
- return False
112
+ .. tip::
111
113
 
112
- for nn in range(cnt1):
113
- if (
114
- self._xs[(front1 + nn) % cap1]
115
- is other._xs[(front2 + nn) % cap2]
116
- ):
117
- continue
118
- if (
119
- self._xs[(front1 + nn) % cap1]
120
- != other._xs[(front2 + nn) % cap2]
121
- ):
122
- return False
123
- return True
114
+ Cache contents to make more thread tolerant. Put
115
+ a lock around circular array during caching process
116
+ to make threadsafe.
124
117
 
125
- def __iter__(self) -> Iterator[X]:
118
+ """
126
119
  if self._cnt > 0:
127
120
  (
128
121
  cap,
@@ -142,6 +135,24 @@ class CAF[X]:
142
135
  yield cast(X, current_state[position])
143
136
 
144
137
  def __reversed__(self) -> Iterator[X]:
138
+ """
139
+ .. admonition:: reverse iterate
140
+
141
+ Iterates circular array, right (rear) to left (front).
142
+
143
+ :yields: The ``CAF`` contents rear to front.
144
+
145
+ .. warning
146
+
147
+ Not thread safe, especially for long living iterators.
148
+
149
+ .. tip::
150
+
151
+ Cache contents to make more thread tolerant. Put
152
+ a lock around circular array during caching process
153
+ to make threadsafe.
154
+
155
+ """
145
156
  if self._cnt > 0:
146
157
  (
147
158
  cap,
@@ -160,7 +171,57 @@ class CAF[X]:
160
171
  position = (position - 1) % cap
161
172
  yield cast(X, current_state[position])
162
173
 
174
+ def __eq__(self, other: object) -> bool:
175
+ """
176
+ .. admonition:: equality comparison
177
+
178
+ Efficiently compare ``CAF`` to another object.
179
+
180
+ :param other: The object to be compared.
181
+ :returns: ``True`` if ``other`` is another ``CAF`` whose
182
+ contents compare as equal to the corresponding
183
+ contents of the ``CAF``, otherwise ``False``.
184
+
185
+ """
186
+ if self is other:
187
+ return True
188
+ if not isinstance(other, type(self)):
189
+ return False
190
+
191
+ (
192
+ front1,
193
+ cnt1,
194
+ cap1,
195
+ front2,
196
+ cnt2,
197
+ cap2,
198
+ ) = (
199
+ self._front,
200
+ self._cnt,
201
+ self._cap,
202
+ other._front,
203
+ other._cnt,
204
+ other._cap,
205
+ )
206
+
207
+ if cnt1 != cnt2:
208
+ return False
209
+
210
+ for nn in range(cnt1):
211
+ if self._xs[(front1 + nn) % cap1] is other._xs[(front2 + nn) % cap2]:
212
+ continue
213
+ if self._xs[(front1 + nn) % cap1] != other._xs[(front2 + nn) % cap2]:
214
+ return False
215
+ return True
216
+
163
217
  def __getitem__(self, idx: int) -> X:
218
+ """
219
+ .. admonition:: getitem
220
+
221
+ Fixed capacity circular arrays are indexable but
222
+ not sliceable.
223
+
224
+ """
164
225
  cnt = self._cnt
165
226
  if 0 <= idx < cnt:
166
227
  return cast(X, self._xs[(self._front + idx) % self._cap])
@@ -178,6 +239,13 @@ class CAF[X]:
178
239
  raise IndexError(msg1 + msg2 + msg3)
179
240
 
180
241
  def __setitem__(self, idx: int, val: X) -> None:
242
+ """
243
+ .. admonition:: setitem
244
+
245
+ Fixed capacity circular arrays are indexable but
246
+ not sliceable.
247
+
248
+ """
181
249
  cnt = self._cnt
182
250
  if 0 <= idx < cnt:
183
251
  self._xs[(self._front + idx) % self._cap] = val
@@ -193,9 +261,16 @@ class CAF[X]:
193
261
  raise IndexError(msg1 + msg2 + msg3)
194
262
 
195
263
  def __delitem__(self, idx: int) -> None:
264
+ """
265
+ .. admonition:: delitem
266
+
267
+ Fixed capacity circular arrays are indexable but
268
+ not sliceable.
269
+
270
+ """
196
271
  item_list = list(self)
197
272
  del item_list[idx]
198
- _ca = CAF(item_list, cap = self._cap)
273
+ _ca = CAF(item_list, cap=self._cap)
199
274
  (
200
275
  self._xs,
201
276
  self._cnt,
@@ -211,38 +286,37 @@ class CAF[X]:
211
286
 
212
287
  def __repr__(self) -> str:
213
288
  """
214
- .. admonition:: String representation
289
+ .. admonition:: repr string
215
290
 
216
- Return 'CAF("repr(x1)", "repr(x2)", ..., "repr(xn)")'
217
- where x1, x2, ..., xn are the circular array's
218
- contents and "repr(xi)" is the repr-string for xi.
291
+ Construct string 'CAF(x₁, x₂, … xₙ)' where
292
+ x₁, x₂, … xₙ are the contents displayed with ``repr()``.
219
293
 
220
- :returns: A string to reproduce the ``CAF``.
294
+ :returns: A string to reproduce the ``CAF``.
221
295
 
222
296
  """
223
297
  return 'caf(' + ', '.join(map(repr, self)) + ')'
224
298
 
225
299
  def __str__(self) -> str:
226
300
  r"""
227
- .. admonition:: User string
228
-
229
- Return '(\|x1, x2, ..., xn\|)'
230
- where x1, x2, ..., xn are the circular array's
231
- contents displayed as strings.
301
+ .. admonition:: user string
302
+ Construct string '(\|x₁, x₂, … xₙ\|)' where
303
+ x₁, x₂, ..., xₙ are the contents displayed with ``str()``.
232
304
 
233
- :returns: A string meaningful to an end user.
305
+ :returns: A string meaningful to an end user.
234
306
 
235
307
  """
236
308
  return '(|' + ', '.join(map(str, self)) + '|)'
237
309
 
238
310
  def pushl(self, x: X) -> None:
239
311
  """
240
- .. admonition:: Push left
312
+ .. admonition:: push left
241
313
 
242
314
  Push single item from the left onto the ``CAF``.
243
315
 
244
- :param x: Single item to be pushed onto the front of the circular array from the left.
245
- :raises ValueError: When called on a full fixed storage capacity circular array.
316
+ :param x: Single item to be pushed onto the front of
317
+ the ``CAF`` from the left.
318
+ :raises ValueError: When called on a full fixed storage
319
+ capacity circular array.
246
320
 
247
321
  """
248
322
  if self._cnt == self._cap:
@@ -261,12 +335,14 @@ class CAF[X]:
261
335
 
262
336
  def pushr(self, x: X) -> None:
263
337
  """
264
- .. admonition:: Push right
338
+ .. admonition:: push right
265
339
 
266
340
  Push single item from the right onto the ``CAF``.
267
341
 
268
- :param x: Single item to be pushed onto the rear of the circular array from the right.
269
- :raises ValueError: When called on a full fixed storage capacity circular array.
342
+ :param x: Single item to be pushed onto the rear of
343
+ the ``CAF`` from the right.
344
+ :raises ValueError: When called on a full fixed
345
+ storage capacity circular array.
270
346
 
271
347
  """
272
348
  if self._cnt == self._cap:
@@ -285,12 +361,12 @@ class CAF[X]:
285
361
 
286
362
  def popl(self) -> X:
287
363
  """
288
- .. admonition:: Pop left
364
+ .. admonition:: pop left
289
365
 
290
366
  Pop a single items off the left side of the ``CAF``.
291
367
 
292
- :returns: Item popped from left side (front) of circular array.
293
- :raises ValueError: When called on an empty circular array.
368
+ :returns: Item popped from left side (front) of the ``CAF``.
369
+ :raises ValueError: When called on an empty ``CAF``.
294
370
 
295
371
  """
296
372
  if self._cnt > 1:
@@ -326,12 +402,12 @@ class CAF[X]:
326
402
 
327
403
  def popr(self) -> X:
328
404
  """
329
- .. admonition:: Pop right
405
+ .. admonition:: pop right
330
406
 
331
407
  Pop a single items off the right side of the ``CAF``.
332
408
 
333
- :returns: Item popped from right side (rear) of circular array.
334
- :raises ValueError: When called on an empty circular array.
409
+ :returns: Item popped from right side (rear) of the ``CAF``.
410
+ :raises ValueError: When called on an empty ``CAF``.
335
411
 
336
412
  """
337
413
  if self._cnt > 1:
@@ -367,14 +443,14 @@ class CAF[X]:
367
443
 
368
444
  def popld(self, default: X) -> X:
369
445
  """
370
- .. admonition:: Pop Left with default
446
+ .. admonition:: pop Left with default
371
447
 
372
448
  Pop a single items off the left side of the ``CAF``.
373
449
 
374
- :param default: Default value to return if ``CAF`` is empty.
375
- :returns: Item popped from left side (front) of circular array
376
- if not empty, otherwise return the provided default
377
- value.
450
+ :param default: Default value to return if ``CAF`` is empty.
451
+ :returns: Item popped from left side (front) of the ``CAF``
452
+ if not empty, otherwise return the provided
453
+ default value.
378
454
 
379
455
  """
380
456
  try:
@@ -384,14 +460,14 @@ class CAF[X]:
384
460
 
385
461
  def poprd(self, default: X) -> X:
386
462
  """
387
- .. admonition:: Pop Right with default
463
+ .. admonition:: pop Right with default
388
464
 
389
465
  Pop a single items off the right side of the ``CAF``.
390
466
 
391
- :param default: Default value to return if ``CAF`` is empty.
392
- :returns: Item popped from right side (rear) of circular array
393
- if not empty, otherwise return the provided default
394
- value.
467
+ :param default: Default value to return if ``CAF`` is empty.
468
+ :returns: Item popped from right side (rear) of the ``CAF``
469
+ if not empty, otherwise return the provided
470
+ default value.
395
471
 
396
472
  """
397
473
  try:
@@ -405,8 +481,9 @@ class CAF[X]:
405
481
 
406
482
  Pop items off the left side of the ``CAF``.
407
483
 
408
- :param maximum: Maximum number of items to pop, may pop less if not enough items in ``CAF``.
409
- :returns: A ``tuple`` of the items popped, left to right.
484
+ :param maximum: Maximum number of items to pop,
485
+ may pop less if not enough items in ``CAF``.
486
+ :returns: A ``tuple`` of the items popped, left to right.
410
487
 
411
488
  """
412
489
  xs: list[X] = []
@@ -427,8 +504,9 @@ class CAF[X]:
427
504
 
428
505
  Pop items off the right side of the ``CAF``.
429
506
 
430
- :param maximum: Maximum number of items to pop, may pop less if not enough items in ``CAF``.
431
- :returns: A ``tuple`` of the items popped, right to left.
507
+ :param maximum: Maximum number of items to pop,
508
+ may pop less if not enough items in ``CAF``.
509
+ :returns: A ``tuple`` of the items popped, right to left.
432
510
 
433
511
  """
434
512
  xs: list[X] = []
@@ -448,7 +526,8 @@ class CAF[X]:
448
526
  Rotate contents of ``CAF`` to the left putting first
449
527
  item onto rear.
450
528
 
451
- :param n: Number of times to shift items left. Default 1 time.
529
+ :param n: Number of times to shift items left.
530
+ Default 1 time.
452
531
 
453
532
  """
454
533
  if self._cnt < 2:
@@ -463,7 +542,8 @@ class CAF[X]:
463
542
  Rotate contents of ``CAF`` to the right putting last
464
543
  item onto front.
465
544
 
466
- :param n: Number of times to shift items right. Default 1 time.
545
+ :param n: Number of times to shift items right.
546
+ Default 1 time.
467
547
 
468
548
  """
469
549
  if self._cnt < 2:
@@ -477,11 +557,11 @@ class CAF[X]:
477
557
 
478
558
  Apply function ``f`` over the circular array's contents.
479
559
 
480
- :param f: Callable from type ``X`` to type ``Y``.
481
- :returns: New fixed capacity circular array instance.
560
+ :param f: Callable from type ``X`` to type ``Y``.
561
+ :returns: New fixed capacity circular array instance.
482
562
 
483
563
  """
484
- return CAF(map(f, self), cap = self._cap)
564
+ return CAF(map(f, self), cap=self._cap)
485
565
 
486
566
  @overload
487
567
  def foldl[L](self, f: Callable[[X, X], X]) -> X: ...
@@ -494,10 +574,12 @@ class CAF[X]:
494
574
 
495
575
  Fold ``CAF`` left with a function and optional starting item.
496
576
 
497
- :param f: Folding function, first argument to ``f`` is for the accumulator.
498
- :param start: Optional starting item.
499
- :returns: Reduced value produced by the left fold.
500
- :raises ValueError: When circular array empty and ``start`` not given.
577
+ :param f: Folding function, first argument to ``f`` is for
578
+ the accumulator.
579
+ :param start: Optional starting item.
580
+ :returns: Reduced value produced by the left fold.
581
+ :raises ValueError: When circular array empty and ``start``
582
+ not given.
501
583
 
502
584
  """
503
585
  if self._cnt == 0:
@@ -528,10 +610,12 @@ class CAF[X]:
528
610
 
529
611
  Fold ``CAF`` right left with a function and optional starting item.
530
612
 
531
- :param f: Folding function, second argument to ``f`` is for the accumulator.
532
- :param start: Optional starting item.
533
- :returns: Reduced value produced by the right fold.
534
- :raises ValueError: When circular array empty and ``start`` not given.
613
+ :param f: Folding function, second argument to ``f`` is for
614
+ the accumulator.
615
+ :param start: Optional starting item.
616
+ :returns: Reduced value produced by the right fold.
617
+ :raises ValueError: When circular array empty and ``start``
618
+ not given.
535
619
 
536
620
  """
537
621
  if self._cnt == 0:
@@ -557,8 +641,7 @@ class CAF[X]:
557
641
 
558
642
  Get the fixed storage capacity of the circular array.
559
643
 
560
-
561
- :returns: Fixed storage capacity.
644
+ :returns: Fixed storage capacity.
562
645
 
563
646
  """
564
647
  return self._cap
@@ -588,7 +671,7 @@ class CAF[X]:
588
671
 
589
672
  Find fraction of the storage capacity which is filled.
590
673
 
591
- :returns: The ratio count/capacity.
674
+ :returns: The ratio count/capacity.
592
675
 
593
676
  """
594
677
  return self._cnt / self._cap
@@ -598,11 +681,12 @@ def caf[T](*ts: T, cap: int = 2) -> CAF[T]:
598
681
  """
599
682
  .. admonition:: Circular array factory function
600
683
 
601
- Produce a circular array from a variable number of arguments.
684
+ Produce a fixed capacity circular array from
685
+ a variable number of arguments.
602
686
 
603
- :param ts: Initial items for a new fixed capacity circular array.
604
- :param cap: The minimum storage capacity to set.
605
- :returns: New fixed storage capacity circular array.
687
+ :param ts: Initial items for a new fixed capacity circular array.
688
+ :param cap: The minimum storage capacity to set.
689
+ :returns: New fixed storage capacity circular array.
606
690
 
607
691
  """
608
692
  return CAF(ts, cap=cap)
@@ -5,16 +5,16 @@ __all__ = ['CAF', 'caf']
5
5
 
6
6
  class CAF[X]:
7
7
  def __init__(self, *xs: Iterable[X], cap: int = 2) -> None: ...
8
- def __iter__(self) -> Iterator[X]: ...
9
- def __reversed__(self) -> Iterator[X]: ...
10
8
  def __bool__(self) -> bool: ...
11
9
  def __len__(self) -> int: ...
10
+ def __iter__(self) -> Iterator[X]: ...
11
+ def __reversed__(self) -> Iterator[X]: ...
12
+ def __eq__(self, other: object) -> bool: ...
12
13
  def __getitem__(self, idx: int) -> X: ...
13
14
  def __setitem__(self, idx: int, val: X) -> None: ...
14
15
  def __delitem__(self, idx: int) -> None: ...
15
- def __eq__(self, other: object) -> bool: ...
16
- def pushl(self, item: X) -> None: ...
17
- def pushr(self, item: X) -> None: ...
16
+ def pushl(self, x: X) -> None: ...
17
+ def pushr(self, x: X) -> None: ...
18
18
  def popl(self) -> X: ...
19
19
  def popr(self) -> X: ...
20
20
  def popld(self, default: X) -> X: ...
@@ -1,38 +1,39 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-circulararray
3
- Version: 6.1.0
4
- Summary: Circular Array
3
+ Version: 6.2.0
4
+ Summary: Circular array datastructures.
5
5
  Keywords: auto resizing,circular array,circulararray,dequeue,indexable,pop,push
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
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
18
  Requires-Dist: pythonic-fp-gadgets>=4.0.2
18
- Requires-Dist: pytest>=8.4.1 ; extra == "test"
19
- Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-circulararray/blob/main/CHANGELOG.rst
20
- Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/projects/circulararray.html
19
+ Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-circulararray/blob/main/CHANGELOG.md
20
+ Project-URL: Documentation, https://grscheller.github.io/pythonic-fp-circulararray/release/html/
21
21
  Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/
22
22
  Project-URL: Source, https://github.com/grscheller/pythonic-fp-circulararray
23
- Provides-Extra: test
24
23
 
25
- Pythonic FP - Circular Array
26
- ============================
24
+ # Pythonic FP - Circular Array
25
+
26
+ Stateful circular array data structures.
27
27
 
28
28
  PyPI project
29
- `pythonic-fp-circulararray
30
- <https://pypi.org/project/pythonic-fp-circulararray>`_.
29
+ [pythonic-fp-circulararray](https://pypi.org/project/pythonic-fp-circulararray).
30
+ Part of the
31
+ [pythonic-fp](https://grscheller.github.io/pythonic-fp/)
32
+ PyPI projects.
31
33
 
32
- Python module implementing stateful circular array data structures.
34
+ ## Description
33
35
 
34
36
  - variable storage capacity circular array
35
-
36
37
  - O(1) pops either end
37
38
  - O(1) amortized pushes either end
38
39
  - O(1) indexing, fully supports slicing
@@ -41,9 +42,7 @@ Python module implementing stateful circular array data structures.
41
42
  - comparisons compare identity before equality, like builtins
42
43
  - in boolean context, falsy when empty, otherwise truthy
43
44
  - function ``ca`` produces auto-resizing circular array from arguments
44
-
45
45
  - fixed storage capacity circular array
46
-
47
46
  - O(1) pops and pushes either end
48
47
  - O(1) indexing, does not support slicing
49
48
  - fixed total storage capacity
@@ -52,20 +51,7 @@ Python module implementing stateful circular array data structures.
52
51
  - in boolean context, falsy when either empty or full, otherwise truthy
53
52
  - function ``caf`` produces fixed capacity circular array from arguments
54
53
 
55
- Part of the
56
- `pythonic-fp
57
- <https://grscheller.github.io/pythonic-fp/>`_
58
- PyPI projects.
59
-
60
- Documentation
61
- -------------
62
-
63
- Documentation and other links for this project are hosted on
64
- `GitHub Pages
65
- <https://grscheller.github.io/pythonic-fp/projects/circulararray.html>`_.
66
-
67
- Copyright and License
68
- ---------------------
54
+ ## Copyright and License
69
55
 
70
56
  Copyright (c) 2023-2026 Geoffrey R. Scheller. Licensed under the Apache
71
57
  License, Version 2.0. See the LICENSE file for details.