dtools.circular-array 3.12.1__py3-none-any.whl → 3.13.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.
@@ -19,15 +19,14 @@ data structure with amortized O(1) pushes and pops either end.
19
19
 
20
20
  Circular array data structure.
21
21
 
22
- - *module* dtools.circular_array
22
+ - *module* dtools.circular_array.ca
23
23
  - *class* dtools.circular_array.ca.CA
24
24
  - initializer takes up to 1 iterable
25
25
  - *function* dtools.circular_array.ca.ca
26
- - factory function taking a variable number of arguments
26
+ - constructs a `CA` from a variable number of arguments
27
27
 
28
28
  """
29
29
 
30
- __version__ = '3.12.1'
31
30
  __author__ = 'Geoffrey R. Scheller'
32
31
  __copyright__ = 'Copyright (c) 2023-2025 Geoffrey R. Scheller'
33
32
  __license__ = 'Apache License 2.0'
@@ -12,41 +12,42 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- """### Module for an indexable circular array data structure."""
15
+ """### An indexable circular array data structure."""
16
16
 
17
17
  from __future__ import annotations
18
+
18
19
  from collections.abc import Callable, Iterable, Iterator
19
20
  from typing import cast, Never, overload, TypeVar
20
21
 
21
22
  __all__ = ['CA', 'ca']
22
23
 
23
- D = TypeVar('D') # Needed only for pdoc documentation generation. Otherwise,
24
- L = TypeVar('L') # ignored by both MyPy and Python. Makes linters unhappy
25
- R = TypeVar('R') # when these are used on function and method signatures due
26
- U = TypeVar('U') # to "redefined-outer-name" warnings. Function and method
27
- T = TypeVar('T') # signatures do not support variance and bounds constraints.
24
+ D = TypeVar('D')
28
25
 
29
26
 
30
- class CA[D]():
27
+ class CA[D]:
31
28
  """Indexable circular array data structure
32
29
 
33
30
  - generic, stateful data structure
34
- - lowercase class name chosen to match nomenclature for builtins
35
- - like `list` and `tuple`
36
31
  - amortized O(1) pushing and popping from either end
37
32
  - O(1) random access any element
38
33
  - will resize itself as needed
39
34
  - sliceable
40
35
  - makes defensive copies of contents for the purposes of iteration
41
- - in boolean context returns true if not empty, false if empty
42
- - in comparisons compare identity before equality (like builtins)
36
+ - in boolean context returns
37
+ - `True` when not empty
38
+ - `False` when empty
39
+ - in comparisons compare identity before equality, like builtins do
43
40
  - raises `IndexError` for out-of-bounds indexing
44
- - raises `ValueError` for popping from or folding an empty `ca`
41
+ - raises `ValueError` for popping from or folding an empty `CA`
45
42
 
46
43
  """
47
44
 
48
45
  __slots__ = '_data', '_cnt', '_cap', '_front', '_rear'
49
46
 
47
+ L = TypeVar('L')
48
+ R = TypeVar('R')
49
+ U = TypeVar('U')
50
+
50
51
  def __init__(self, *dss: Iterable[D]) -> None:
51
52
  if len(dss) < 2:
52
53
  self._data: list[D | None] = (
@@ -77,7 +78,6 @@ class CA[D]():
77
78
  self._front, self._cap = self._front + self._cap, 2 * self._cap
78
79
 
79
80
  def _compact_storage_capacity(self) -> None:
80
- """Compact the CA."""
81
81
  match self._cnt:
82
82
  case 0:
83
83
  self._cap, self._front, self._rear, self._data = 2, 0, 1, [None, None]
@@ -211,11 +211,11 @@ class CA[D]():
211
211
  raise IndexError(msg1 + msg2 + msg3)
212
212
 
213
213
  @overload
214
- def __delitem__(self, idx: int) -> None: ...
214
+ def __delitem__(self, idx: int, /) -> None: ...
215
215
  @overload
216
- def __delitem__(self, idx: slice) -> None: ...
216
+ def __delitem__(self, idx: slice, /) -> None: ...
217
217
 
218
- def __delitem__(self, idx: int | slice) -> None:
218
+ def __delitem__(self, idx: int | slice, /) -> None:
219
219
  data = list(self)
220
220
  del data[idx]
221
221
  _ca = CA(data)
@@ -259,7 +259,11 @@ class CA[D]():
259
259
  return True
260
260
 
261
261
  def pushl(self, *ds: D) -> None:
262
- """Push data from the left onto the CA."""
262
+ """Push left.
263
+
264
+ - push data from the left onto the CA
265
+
266
+ """
263
267
  for d in ds:
264
268
  if self._cnt == self._cap:
265
269
  self._double_storage_capacity()
@@ -267,7 +271,11 @@ class CA[D]():
267
271
  self._data[self._front], self._cnt = d, self._cnt + 1
268
272
 
269
273
  def pushr(self, *ds: D) -> None:
270
- """Push data from the right onto the CA."""
274
+ """Push right.
275
+
276
+ - push data from the right onto the CA
277
+
278
+ """
271
279
  for d in ds:
272
280
  if self._cnt == self._cap:
273
281
  self._double_storage_capacity()
@@ -275,9 +283,10 @@ class CA[D]():
275
283
  self._data[self._rear], self._cnt = d, self._cnt + 1
276
284
 
277
285
  def popl(self) -> D | Never:
278
- """Pop one value off the left side of the CA.
286
+ """Pop left.
279
287
 
280
- Raises `ValueError` when called on an empty CA.
288
+ - pop one value off the left side of the `CA`
289
+ - raises `ValueError` when called on an empty `CA`
281
290
 
282
291
  """
283
292
  if self._cnt > 1:
@@ -301,9 +310,10 @@ class CA[D]():
301
310
  return cast(D, d)
302
311
 
303
312
  def popr(self) -> D | Never:
304
- """Pop one value off the right side of the CA.
313
+ """Pop right
305
314
 
306
- Raises `ValueError` when called on an empty CA.
315
+ - pop one value off the right side of the `CA`
316
+ - raises `ValueError` when called on an empty `CA`
307
317
 
308
318
  """
309
319
  if self._cnt > 1:
@@ -330,7 +340,7 @@ class CA[D]():
330
340
  """Pop one value from left, provide a mandatory default value.
331
341
 
332
342
  - safe version of popl
333
- - returns a default value in the event the `CA` is empty
343
+ - returns the default value if `CA` is empty
334
344
 
335
345
  """
336
346
  try:
@@ -342,7 +352,7 @@ class CA[D]():
342
352
  """Pop one value from right, provide a mandatory default value.
343
353
 
344
354
  - safe version of popr
345
- - returns a default value in the event the `CA` is empty
355
+ - returns the default value if `CA` is empty
346
356
 
347
357
  """
348
358
  try:
@@ -353,9 +363,8 @@ class CA[D]():
353
363
  def poplt(self, maximum: int, /) -> tuple[D, ...]:
354
364
  """Pop multiple values from left side of `CA`.
355
365
 
356
- - returns the results in a tuple of type `tuple[~D, ...]`
357
- - returns an empty tuple if `CA` is empty
358
- - pop no more that `max` values
366
+ - returns the results in a tuple of type
367
+ - pop no more that `maximum` values
359
368
  - will pop less if `CA` becomes empty
360
369
 
361
370
  """
@@ -374,9 +383,8 @@ class CA[D]():
374
383
  def poprt(self, maximum: int, /) -> tuple[D, ...]:
375
384
  """Pop multiple values from right side of `CA`.
376
385
 
377
- - returns the results in a tuple of type `tuple[~D, ...]`
378
- - returns an empty tuple if `CA` is empty
379
- - pop no more that `max` values
386
+ - returns the results in a tuple
387
+ - pop no more that `maximum` values
380
388
  - will pop less if `CA` becomes empty
381
389
 
382
390
  """
@@ -392,34 +400,31 @@ class CA[D]():
392
400
  return tuple(ds)
393
401
 
394
402
  def rotl(self, n: int = 1, /) -> None:
395
- """Rotate `CA` arguments left n times."""
403
+ """Rotate `CA` components to the left n times."""
396
404
  if self._cnt < 2:
397
405
  return
398
406
  for _ in range(n, 0, -1):
399
407
  self.pushr(self.popl())
400
408
 
401
409
  def rotr(self, n: int = 1, /) -> None:
402
- """Rotate `CA` arguments right n times."""
410
+ """Rotate `CA` components to the right n times."""
403
411
  if self._cnt < 2:
404
412
  return
405
413
  for _ in range(n, 0, -1):
406
414
  self.pushl(self.popr())
407
415
 
408
416
  def map[U](self, f: Callable[[D], U], /) -> CA[U]:
409
- """Apply function f over contents, returns new `CA` instance.
417
+ """Apply function `f` over the `CA` contents,
410
418
 
411
- - parameter `f` function of type `f[~D, ~U] -> CA[~U]`
412
- - returns a new instance of type `CA[~U]`
419
+ - returns a new `CA` instance
413
420
 
414
421
  """
415
422
  return CA(map(f, self))
416
423
 
417
- def foldl[L](self, f: Callable[[L, D], L], /, initial: L | None = None) -> L:
418
- """Left fold `CA` via function and optional initial value.
424
+ def foldl[L](self, f: Callable[[L, D], L], initial: L | None = None, /) -> L:
425
+ """Left fold `CA` with function `f` and an optional `initial` value.
419
426
 
420
- - parameter `f` function of type `f[~L, ~D] -> ~L`
421
- - the first argument to `f` is for the accumulated value.
422
- - parameter `initial` is an optional initial value
427
+ - first argument to `f` is for the accumulated value
423
428
  - returns the reduced value of type `~L`
424
429
  - note that `~L` and `~D` can be the same type
425
430
  - if an initial value is not given then by necessity `~L = ~D`
@@ -443,12 +448,10 @@ class CA[D]():
443
448
  acc = f(acc, d)
444
449
  return acc
445
450
 
446
- def foldr[R](self, f: Callable[[D, R], R], /, initial: R | None = None) -> R:
447
- """Right fold `CA` via function and optional initial value.
451
+ def foldr[R](self, f: Callable[[D, R], R], initial: R | None = None, /) -> R:
452
+ """Right fold `CA` with function `f` and an optional `initial` value.
448
453
 
449
- - parameter `f` function of type `f[~D, ~R] -> ~R`
450
- - the second argument to f is for the accumulated value
451
- - parameter `initial` is an optional initial value
454
+ - second argument to f is for the accumulated value
452
455
  - returns the reduced value of type `~R`
453
456
  - note that `~R` and `~D` can be the same type
454
457
  - if an initial value is not given then by necessity `~R = ~D`
@@ -497,6 +500,6 @@ class CA[D]():
497
500
  self._front, self._rear = 0, self._cap - 1
498
501
 
499
502
 
500
- def ca[T](*ds: T) -> CA[T]:
503
+ def ca[D](*ds: D) -> CA[D]:
501
504
  """Function to produce a `CA` array from a variable number of arguments."""
502
505
  return CA(ds)
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dtools.circular-array
3
- Version: 3.12.1
3
+ Version: 3.13.0
4
4
  Summary: ### Developer Tools - Circular Array Data Structure
5
- Keywords: circular array,circle array,CA,dequeue,dqueue,FIFO,LIFO,pop,push,indexable,auto-resizing,auto resizing,resizing
5
+ Keywords: circular array,dequeue,pop,push,indexable,auto resizing
6
6
  Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
7
7
  Requires-Python: >=3.12
8
8
  Description-Content-Type: text/markdown
@@ -17,6 +17,7 @@ License-File: LICENSE
17
17
  Requires-Dist: pytest >=8.3.5 ; extra == "test"
18
18
  Project-URL: Changelog, https://github.com/grscheller/dtools-circular-array/blob/main/CHANGELOG.md
19
19
  Project-URL: Documentation, https://grscheller.github.io/dtools-docs/circular-array
20
+ Project-URL: Homepage, https://github.com/grscheller/dtools-docs
20
21
  Project-URL: Source, https://github.com/grscheller/dtools-circular-array
21
22
  Provides-Extra: test
22
23
 
@@ -39,24 +40,25 @@ namespace project.
39
40
  - O(1) amortized pushes and pops either end.
40
41
  - O(1) indexing
41
42
  - fully supports slicing
42
- - safely mutates while iterating over copies of previous state
43
+ - safely mutates over previous state
43
44
 
44
45
  ### Module circular_array
45
46
 
46
- A full featured, auto resizing circular array. Python package containing
47
- a module implementing a full featured, indexable, sliceable, double
48
- sided, auto-resizing circular array data structure.
47
+ A full featured auto resizing circular array data structure. Double
48
+ sided, indexable, sliceable, and iterable. When iterated, uses cached
49
+ copies of its present state so that the circular array itself can safely
50
+ be mutated.
49
51
 
50
- Useful either if used directly as an improved version of a Python List
51
- or in a "has-a" relationship when implementing other data structures.
52
+ Useful either if used directly like a Python list, or in a "has-a"
53
+ relationship when implementing other data structures.
52
54
 
53
55
  - *module* dtools.circular_array
54
- - *class* ca: circular array data structure
55
- - *function* CA: factory function to produce a ca from data
56
+ - *class* CA: circular array data structure
57
+ - *function* ca: factory function to produce a CA from data
56
58
 
57
- Above nomenclature modeled after of a builtin data type like `list`, where
58
- `ca` takes an optional iterator as an argument and CA is all caps to represent
59
- syntactic sugar like `[]` or `{}`.
59
+ Above nomenclature modeled after builtin data types like `list`, where
60
+ `CA` and `ca` correspond respectfully to `list` and `[]` in their use
61
+ cases.
60
62
 
61
63
  #### Usage
62
64
 
@@ -0,0 +1,7 @@
1
+ dtools/circular_array/__init__.py,sha256=T_Jqa8AzDhow6q5O6A_FP5kCHBohEYJYSpo5xcsfTuU,1168
2
+ dtools/circular_array/ca.py,sha256=xSvYBPAFAJU_KbHAjmSIFAt3Pq9YkVVojo0BIoxIZPY,15918
3
+ dtools/circular_array/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ dtools_circular_array-3.13.0.dist-info/licenses/LICENSE,sha256=csqbZRvA3Nyuav1aszWvswE8CZtaKr-hMjjjcKqms7w,10774
5
+ dtools_circular_array-3.13.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
6
+ dtools_circular_array-3.13.0.dist-info/METADATA,sha256=NRnV41SCn3OKLWHgud6_WpQg_dr9WGbeXraJ6CkzAZg,3448
7
+ dtools_circular_array-3.13.0.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- dtools/circular_array/__init__.py,sha256=2CvFEORjHTaRYTteVH-Ifo7THhbttgif71VigBM-3-Y,1189
2
- dtools/circular_array/ca.py,sha256=PRt-AOvR9WqwS6EdKFWXde7VxBc1yOD6kuCK_lXuWFQ,16683
3
- dtools/circular_array/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- dtools_circular_array-3.12.1.dist-info/licenses/LICENSE,sha256=csqbZRvA3Nyuav1aszWvswE8CZtaKr-hMjjjcKqms7w,10774
5
- dtools_circular_array-3.12.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
6
- dtools_circular_array-3.12.1.dist-info/METADATA,sha256=9HGyzkYTReGc9LUbP_X1qbWEK-EQKVwA_gAaZdI_5cI,3495
7
- dtools_circular_array-3.12.1.dist-info/RECORD,,