pythonic-fp-circulararray 6.1.0__tar.gz → 6.1.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 (35) hide show
  1. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/.github/workflows/static.yml +2 -2
  2. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/.gitignore +0 -1
  3. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/CHANGELOG.rst +8 -0
  4. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/PKG-INFO +1 -1
  5. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/docs/Makefile +3 -3
  6. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/docs/source/docs/index.rst +4 -2
  7. pythonic_fp_circulararray-6.1.1/docs/source/index.rst +30 -0
  8. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/docs/source/releases.rst +7 -1
  9. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/pyproject.toml +1 -1
  10. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/src/pythonic_fp/circulararray/auto.py +151 -64
  11. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/src/pythonic_fp/circulararray/fixed.py +153 -68
  12. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/src/pythonic_fp/circulararray/fixed.pyi +5 -5
  13. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/LICENSE +0 -0
  14. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/README.rst +0 -0
  15. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/docs/gen_conf.py +0 -0
  16. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/docs/requirements.txt +0 -0
  17. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/docs/source/_static/.gitkeep +0 -0
  18. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/docs/source/_templates/.gitkeep +0 -0
  19. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/docs/source/changelog.rst +0 -0
  20. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/docs/source/description.rst +0 -0
  21. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/docs/source/docs/auto.rst +0 -0
  22. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/docs/source/docs/fixed.rst +0 -0
  23. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/docs/source/usage.rst +0 -0
  24. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/src/pythonic_fp/circulararray/__init__.py +0 -0
  25. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/src/pythonic_fp/circulararray/__init__.pyi +0 -0
  26. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/src/pythonic_fp/circulararray/auto.pyi +3 -3
  27. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/src/pythonic_fp/circulararray/py.typed +0 -0
  28. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/tests/auto/test_ca.py +0 -0
  29. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/tests/auto/test_ca_capacity.py +0 -0
  30. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/tests/auto/test_ca_fold_with_none.py +0 -0
  31. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/tests/auto/test_repr_str_auto.py +0 -0
  32. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/tests/fixed/test_caf.py +0 -0
  33. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/tests/fixed/test_caf_capacity.py +0 -0
  34. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/tests/fixed/test_caf_fold_with_none.py +0 -0
  35. {pythonic_fp_circulararray-6.1.0 → pythonic_fp_circulararray-6.1.1}/tests/fixed/test_repr_str_fixed.py +0 -0
@@ -6,7 +6,7 @@ on:
6
6
  workflow_dispatch:
7
7
 
8
8
  env:
9
- RELEASE: '6.1.0'
9
+ RELEASE: '6.1.1'
10
10
  DEVEL: '6.1.1'
11
11
  PYTHON: '3.14'
12
12
 
@@ -42,7 +42,7 @@ jobs:
42
42
  - name: Build Release Docs
43
43
  run: |
44
44
  pip install pythonic-fp-circulararray
45
- docs/gen_conf.py release ${{ env.RELEASE }} CircularArray circulararray > docs/source/conf.py
45
+ docs/gen_conf.py release ${{ env.RELEASE }} Circulararray circulararray > docs/source/conf.py
46
46
  sphinx-build -M html docs/source docs/build/release
47
47
 
48
48
  - name: Build Development Docs
@@ -3,7 +3,6 @@
3
3
  dist/
4
4
  docs/build/
5
5
  docs/source/conf.py
6
- docs/source/index.rst
7
6
  **/.dmypy.json
8
7
  **/.mypy_cache/
9
8
  **/.pytest_cache/
@@ -17,6 +17,14 @@ See `Semantic Versioning 2.0.0 <https://semver.org>`_.
17
17
  Releases and Important Milestones
18
18
  ---------------------------------
19
19
 
20
+ PyPI 6.1.0 - 2026-05-10
21
+ ~~~~~~~~~~~~~~~~~~~~~~~
22
+
23
+ Documentation is now complete and is now in maintenance mode.
24
+
25
+ Maintainer appraises the Development Status for
26
+ pythonic-fp-circulararray to be ``"5 - Production/Stable"``.
27
+
20
28
  PyPI 6.1.0 - 2026-05-03
21
29
  ~~~~~~~~~~~~~~~~~~~~~~~
22
30
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-circulararray
3
- Version: 6.1.0
3
+ Version: 6.1.1
4
4
  Summary: Circular Array
5
5
  Keywords: auto resizing,circular array,circulararray,dequeue,indexable,pop,push
6
6
  Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
@@ -3,9 +3,9 @@
3
3
  # Last and future releases
4
4
  # - former needs to agree with PyPI
5
5
  # - later needs to agree with pyproject.toml
6
- PROJECT_NAME = CircularArray
7
- PYPI_NAME = circularArray
8
- RELEASE_VERSION = 6.1.0
6
+ PROJECT_NAME = Circular Array
7
+ PYPI_NAME = circulararray
8
+ RELEASE_VERSION = 6.1.1
9
9
  DEVEL_VERSION = 6.1.1
10
10
  CUSTOM_VERSION = 0.0.0
11
11
 
@@ -1,8 +1,10 @@
1
1
  Circular Arrays
2
- ---------------
2
+ ===============
3
3
 
4
4
  .. automodule:: pythonic_fp.circulararray
5
- :synopsis:
5
+ :no-members:
6
+ :ignore-module-all:
7
+ :no-index:
6
8
 
7
9
  .. toctree::
8
10
  :caption: Auto resizing circular array
@@ -0,0 +1,30 @@
1
+ pythonic-fp-circulararray
2
+ =========================
3
+
4
+ Project
5
+ `Pythonic FP - Circulararray <https://pypi.org/project/pythonic-fp-circulararray/>`_
6
+ one of the
7
+ `Pythonic FP <https://grscheller.github.io/pythonic-fp/>`_
8
+ PyPI projects.
9
+
10
+ |RELEASE_STRING|
11
+
12
+ .. toctree::
13
+ :caption: Overview
14
+ :hidden:
15
+
16
+ self
17
+
18
+ .. toctree::
19
+ :caption: User Documentation
20
+
21
+ description
22
+ usage
23
+ releases
24
+ changelog
25
+
26
+ .. toctree::
27
+ :caption: API Documentation
28
+ :maxdepth: 1
29
+
30
+ docs/index
@@ -8,7 +8,13 @@ PyPI releases
8
8
  +===========================================================================================+==============+
9
9
  | `development <https://grscheller.github.io/pythonic-fp-circulararray/development/html/>`_ | |
10
10
  +-------------------------------------------------------------------------------------------+--------------+
11
- | `v6.0.2 <https://grscheller.github.io/pythonic-fp-circulararray/release/html/>`_ | 2026-04-21 |
11
+ | `v6.1.1 <https://grscheller.github.io/pythonic-fp-circulararray/release/html/>`_ | 2026-05-10 |
12
+ +-------------------------------------------------------------------------------------------+--------------+
13
+ | v6.1.0 | 2026-05-03 |
14
+ +-------------------------------------------------------------------------------------------+--------------+
15
+ | v6.0.4 | 2026-04-25 |
16
+ +-------------------------------------------------------------------------------------------+--------------+
17
+ | v6.0.2 | 2026-04-21 |
12
18
  +-------------------------------------------------------------------------------------------+--------------+
13
19
  | v6.0.1 | 2026-01-08 |
14
20
  +-------------------------------------------------------------------------------------------+--------------+
@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"
4
4
 
5
5
  [project]
6
6
  name = "pythonic-fp-circulararray"
7
- version = "6.1.0"
7
+ version = "6.1.1"
8
8
  readme = "README.rst"
9
9
  requires-python = ">=3.13"
10
10
  authors = [
@@ -23,26 +23,32 @@ nada: Final[NoValue] = NoValue()
23
23
 
24
24
  class CA[X]:
25
25
  """
26
- .. admonition:: Variable storage capacity circular array CA
26
+ .. admonition:: Auto resizing circular array CA
27
27
 
28
28
  - O(1) pops either end
29
29
  - O(1) amortized pushes either end
30
30
  - O(1) indexing, fully supports slicing
31
- - auto-resizing more storage capacity when necessary, manually compatible
31
+ - auto-resizing more storage capacity when necessary,
32
+ manually compatible
32
33
  - iterable but not threadsafe
33
34
  - comparisons compare identity before equality, like builtins
34
35
  - in boolean context, falsy when empty, otherwise truthy
35
- - function ``ca`` produces auto-resizing circular array from arguments
36
+ - function ``ca`` produces auto-resizing circular array
37
+ from arguments
36
38
 
37
39
  """
38
40
  __slots__ = '_xs', '_cnt', '_cap', '_front', '_rear'
39
41
 
40
42
  def __init__(self, *xs: Iterable[X]) -> None:
41
43
  """
42
- :param xs: Takes 0 or 1 iterable parameters to initially
43
- populate the ``CA`` left (front) to right (back).
44
- :raises ValueError: When more than one iterable is provided.
45
- :raises TypeError: When passed a non-iterable parameter.
44
+ .. admonition:: initializer
45
+
46
+ Populate ``CA`` with an optional iterable
47
+ from front (left) to rear (right).
48
+
49
+ :param xs: Takes 0 or 1 iterable parameters.
50
+ :raises ValueError: When more than one parameter is provided.
51
+ :raises TypeError: When passed a non-iterable parameter.
46
52
 
47
53
  """
48
54
  if (size := len(xs)) > 1:
@@ -140,21 +146,39 @@ class CA[X]:
140
146
  )
141
147
 
142
148
  def __bool__(self) -> bool:
149
+ """
150
+ .. admonition:: bool
151
+
152
+ - falsy when empty
153
+ - truthy when not empty
154
+
155
+ :returns: ``True`` when not empty,
156
+ ``False`` otherwise.
157
+
158
+ """
143
159
  return self._cnt > 0
144
160
 
145
161
  def __len__(self) -> int:
162
+ """
163
+ .. admonition:: length
164
+
165
+ Number of items in the ``CA``.
166
+
167
+ :returns: The number of items in the ``CA``.
168
+
169
+ """
146
170
  return self._cnt
147
171
 
148
172
  def __eq__(self, other: object) -> bool:
149
173
  """
150
- .. admonition:: Equality comparison
174
+ .. admonition:: equality comparison
151
175
 
152
176
  Efficiently compare ``CA`` to another object.
153
177
 
154
- :param other: The object to be compared.
155
- :returns: ``True`` if ``other`` is another ``CA`` whose
156
- contents compare as equal to the corresponding
157
- contents of the ``CA``, otherwise ``False``.
178
+ :param other: The object to be compared.
179
+ :returns: ``True`` if ``other`` is another ``CA`` whose
180
+ contents compare as equal to the corresponding
181
+ contents of the ``CA``, otherwise ``False``.
158
182
 
159
183
  """
160
184
  if self is other:
@@ -195,6 +219,22 @@ class CA[X]:
195
219
  return True
196
220
 
197
221
  def __iter__(self) -> Iterator[X]:
222
+ """
223
+ .. admonition:: iterate
224
+
225
+ Iterates circular array, front (left) to rear (right).
226
+
227
+ .. warning
228
+
229
+ Not thread safe, especially for long living iterators.
230
+
231
+ .. tip::
232
+
233
+ Cache contents to make more thread tolerant. Put
234
+ a lock around circular array during caching process
235
+ to make threadsafe.
236
+
237
+ """
198
238
  if self._cnt > 0:
199
239
  (
200
240
  capacity,
@@ -214,6 +254,22 @@ class CA[X]:
214
254
  yield cast(X, current_state[position])
215
255
 
216
256
  def __reversed__(self) -> Iterator[X]:
257
+ """
258
+ .. admonition:: reverse iterate
259
+
260
+ Iterates circular array, rear (right) to front (left).
261
+
262
+ .. warning
263
+
264
+ Not thread safe, especially for long living iterators.
265
+
266
+ .. tip::
267
+
268
+ Cache contents to make more thread tolerant. Put
269
+ a lock around circular array during caching process
270
+ to make threadsafe.
271
+
272
+ """
217
273
  if self._cnt > 0:
218
274
  (
219
275
  capacity,
@@ -238,6 +294,13 @@ class CA[X]:
238
294
  def __getitem__(self, idx: slice) -> 'CA[X]': ...
239
295
 
240
296
  def __getitem__(self, idx: int | slice) -> X | 'CA[X]':
297
+ """
298
+ .. admonition:: getitem
299
+
300
+ Auto resizing circular arrays are fully indexable
301
+ and sliceable.
302
+
303
+ """
241
304
  if isinstance(idx, slice):
242
305
  return CA(list(self)[idx])
243
306
 
@@ -263,6 +326,13 @@ class CA[X]:
263
326
  def __setitem__(self, idx: slice, vals: Iterable[X]) -> None: ...
264
327
 
265
328
  def __setitem__(self, idx: int | slice, vals: X | Iterable[X]) -> None:
329
+ """
330
+ .. admonition:: setitem
331
+
332
+ Auto resizing circular arrays are fully indexable
333
+ and sliceable.
334
+
335
+ """
266
336
  if isinstance(idx, slice):
267
337
  if isinstance(vals, Iterable):
268
338
  item_list = list(self)
@@ -306,6 +376,13 @@ class CA[X]:
306
376
  def __delitem__(self, idx: slice) -> None: ...
307
377
 
308
378
  def __delitem__(self, idx: int | slice) -> None:
379
+ """
380
+ .. admonition:: delitem
381
+
382
+ Auto resizing circular arrays are fully indexable
383
+ and sliceable.
384
+
385
+ """
309
386
  item_list = list(self)
310
387
  del item_list[idx]
311
388
  _ca = CA(item_list)
@@ -326,38 +403,37 @@ class CA[X]:
326
403
 
327
404
  def __repr__(self) -> str:
328
405
  """
329
- .. admonition:: String representation
406
+ .. admonition:: repr string
330
407
 
331
- Return 'CA("repr(x1)", "repr(x2)", ..., "repr(xn)")'
332
- where x1, x2, ..., xn are the circular array's
333
- contents and "repr(xi)" is the repr-string for xi.
408
+ Construct string 'CA(x₁, x₂, … xₙ)' where
409
+ x₁, x₂, … xₙ are the contents displayed with ``repr()``.
334
410
 
335
- :returns: A string to reproduce the ``CA``.
411
+ :returns: A string to reproduce the ``CA``.
336
412
 
337
413
  """
338
414
  return 'ca(' + ', '.join(map(repr, self)) + ')'
339
415
 
340
416
  def __str__(self) -> str:
341
417
  r"""
342
- .. admonition:: User string
418
+ .. admonition:: user string
343
419
 
344
- Return string '(\| x1, x2, ..., xn \|)'
345
- where x1, x2, ..., xn are the circular array's
346
- contents displayed as strings.
420
+ Construct string '(\| x₁, x₂, … xₙ \|)' where
421
+ x₁, x₂, ..., xₙ are the contents displayed with ``str()``.
347
422
 
348
- :returns: A string meaningful to an end user.
423
+ :returns: A estring meaningful to an end user.
349
424
 
350
425
  """
351
426
  return '(| ' + ', '.join(map(str, self)) + ' |)'
352
427
 
353
428
  def pushl(self, *xs: X) -> None:
354
429
  """
355
- .. admonition:: Push left
430
+ .. admonition:: push left
356
431
 
357
432
  Push items from the left onto the ``CA`` in the
358
433
  order they were iterated.
359
434
 
360
- :param xs: Items to be pushed onto the front of the circular array from the left.
435
+ :param xs: Items to be pushed onto the front of the ``CA``
436
+ from the left.
361
437
 
362
438
  """
363
439
  for x in xs:
@@ -375,12 +451,13 @@ class CA[X]:
375
451
 
376
452
  def pushr(self, *xs: X) -> None:
377
453
  """
378
- .. admonition:: Push right
454
+ .. admonition:: push right
379
455
 
380
456
  Push items from the right onto the ``CA`` in the
381
457
  order they were iterated.
382
458
 
383
- :param xs: Items to be pushed onto the rear of the ``CA`` from the right.
459
+ :param xs: Items to be pushed onto the rear of
460
+ the ``CA`` from the right.
384
461
 
385
462
  """
386
463
  for item in xs:
@@ -398,12 +475,12 @@ class CA[X]:
398
475
 
399
476
  def popl(self) -> X:
400
477
  """
401
- .. admonition:: Pop left
478
+ .. admonition:: pop left
402
479
 
403
480
  Pop a single items off the left side of the ``CA``.
404
481
 
405
- :returns: Item popped from left side (front) of circular array.
406
- :raises ValueError: When called on an empty circular array.
482
+ :returns: Item popped from left side (front) of the ``CA``.
483
+ :raises ValueError: When called on an empty ``CA``.
407
484
 
408
485
  """
409
486
  if self._cnt > 1:
@@ -439,12 +516,12 @@ class CA[X]:
439
516
 
440
517
  def popr(self) -> X:
441
518
  """
442
- .. admonition:: Pop right
519
+ .. admonition:: pop right
443
520
 
444
521
  Pop a single items off the right side of the ``CA``.
445
522
 
446
- :returns: Item popped from right side (rear) of circular array.
447
- :raises ValueError: When called on an empty circular array.
523
+ :returns: Item popped from right side (rear) of the ``CA``.
524
+ :raises ValueError: When called on an empty ``CA``.
448
525
 
449
526
  """
450
527
  if self._cnt > 1:
@@ -480,14 +557,14 @@ class CA[X]:
480
557
 
481
558
  def popld(self, default: X) -> X:
482
559
  """
483
- .. admonition:: Pop Left with default
560
+ .. admonition:: pop Left with default
484
561
 
485
562
  Pop a single items off the left side of the ``CA``.
486
563
 
487
- :param default: Default value to return if ``CA`` is empty.
488
- :returns: Item popped from left side (front) of circular array
489
- if not empty, otherwise return the provided default
490
- value.
564
+ :param default: Default value to return if ``CA`` is empty.
565
+ :returns: Item popped from left side (front) of the ``CA``
566
+ if not empty, otherwise return the provided
567
+ default value.
491
568
 
492
569
  """
493
570
  try:
@@ -497,14 +574,14 @@ class CA[X]:
497
574
 
498
575
  def poprd(self, default: X) -> X:
499
576
  """
500
- .. admonition:: Pop Right with default
577
+ .. admonition:: pop Right with default
501
578
 
502
579
  Pop a single items off the right side of the ``CA``.
503
580
 
504
- :param default: Default value to return if ``CA`` is empty.
505
- :returns: Item popped from right side (rear) of circular array
506
- if not empty, otherwise return the provided default
507
- value.
581
+ :param default: Default value to return if ``CA`` is empty.
582
+ :returns: Item popped from right side (rear) of the ``CA``
583
+ if not empty, otherwise return the provided
584
+ default value.
508
585
 
509
586
  """
510
587
  try:
@@ -518,8 +595,9 @@ class CA[X]:
518
595
 
519
596
  Pop items off the left side of the ``CA``.
520
597
 
521
- :param maximum: Maximum number of items to pop, may pop less if not enough items in ``CA``.
522
- :returns: A ``tuple`` of the items popped, left to right.
598
+ :param maximum: Maximum number of items to pop,
599
+ may pop less if not enough items in ``CA``.
600
+ :returns: A ``tuple`` of the items popped, left to right.
523
601
 
524
602
  """
525
603
  xs: list[X] = []
@@ -540,8 +618,9 @@ class CA[X]:
540
618
 
541
619
  Pop items off the right side of the ``CA``.
542
620
 
543
- :param maximum: Maximum number of items to pop, may pop less if not enough items in ``CA``.
544
- :returns: A ``tuple`` of the items popped, right to left.
621
+ :param maximum: Maximum number of items to pop,
622
+ may pop less if not enough items in ``CA``.
623
+ :returns: A ``tuple`` of the items popped, right to left.
545
624
 
546
625
  """
547
626
  item_list: list[X] = []
@@ -561,7 +640,8 @@ class CA[X]:
561
640
  Rotate contents of ``CA`` to the left putting first
562
641
  item onto rear.
563
642
 
564
- :param n: Number of times to shift items left. Default 1 time.
643
+ :param n: Number of times to shift items left.
644
+ Default 1 time.
565
645
 
566
646
  """
567
647
  if self._cnt < 2:
@@ -576,7 +656,8 @@ class CA[X]:
576
656
  Rotate contents of ``CA`` to the right putting last
577
657
  item onto front.
578
658
 
579
- :param n: Number of times to shift items right. Default 1 time.
659
+ :param n: Number of times to shift items right.
660
+ Default 1 time.
580
661
 
581
662
  """
582
663
  if self._cnt < 2:
@@ -590,8 +671,8 @@ class CA[X]:
590
671
 
591
672
  Apply function ``f`` over the circular array's contents.
592
673
 
593
- :param f: Callable from type ``X`` to type ``Y``.
594
- :returns: New auto-resizing circular array instance.
674
+ :param f: Callable from type ``X`` to type ``Y``.
675
+ :returns: New auto-resizing circular array instance.
595
676
 
596
677
  """
597
678
  return CA(map(f, self))
@@ -607,10 +688,12 @@ class CA[X]:
607
688
 
608
689
  Fold ``CA`` left with a function and optional starting item.
609
690
 
610
- :param f: Folding function, first argument to ``f`` is for the accumulator.
611
- :param start: Optional starting item.
612
- :returns: Reduced value produced by the left fold.
613
- :raises ValueError: When circular array empty and ``start`` not given.
691
+ :param f: Folding function, first argument to ``f`` is for
692
+ the accumulator.
693
+ :param start: Optional starting item.
694
+ :returns: Reduced value produced by the left fold.
695
+ :raises ValueError: When circular array empty and ``start``
696
+ not given.
614
697
 
615
698
  """
616
699
  if self._cnt == 0:
@@ -641,10 +724,12 @@ class CA[X]:
641
724
 
642
725
  Fold ``CA`` right with a function and optional starting item.
643
726
 
644
- :param f: Folding function, second argument to ``f`` is for the accumulator.
645
- :param start: Optional starting item.
646
- :returns: Reduced value produced by the right fold.
647
- :raises ValueError: When circular array empty and ``start`` not given.
727
+ :param f: Folding function, second argument to ``f`` is for
728
+ the accumulator.
729
+ :param start: Optional starting item.
730
+ :returns: Reduced value produced by the right fold.
731
+ :raises ValueError: When circular array empty and ``start``
732
+ not given.
648
733
 
649
734
  """
650
735
  if self._cnt == 0:
@@ -670,7 +755,7 @@ class CA[X]:
670
755
 
671
756
  Get the current storage capacity of the circular array.
672
757
 
673
- :returns: Current storage capacity.
758
+ :returns: Current storage capacity.
674
759
 
675
760
  """
676
761
  return self._cap
@@ -700,7 +785,7 @@ class CA[X]:
700
785
 
701
786
  Find fraction of the storage capacity which is filled.
702
787
 
703
- :returns: The ratio count/capacity.
788
+ :returns: The ratio count/capacity.
704
789
 
705
790
  """
706
791
  return self._cnt / self._cap
@@ -713,7 +798,8 @@ class CA[X]:
713
798
  minimum storage capacity. To just compact the circular
714
799
  array, do not provide ``minimum_capacity``.
715
800
 
716
- :param minimum_capacity: Minimum storage capacity to compact the circular array.
801
+ :param minimum_capacity: Minimum storage capacity to compact
802
+ the circular array.
717
803
 
718
804
  """
719
805
  self._compact_storage_capacity()
@@ -733,10 +819,11 @@ def ca[T](*ts: T) -> CA[T]:
733
819
  """
734
820
  .. admonition:: Circular array factory function
735
821
 
736
- Produce a circular array from a variable number of arguments.
822
+ Produce a auto resizing circular array from
823
+ a variable number of arguments.
737
824
 
738
- :param ts: Initial items for a new auto-resizing circular array.
739
- :returns: New variable storage capacity circular array.
825
+ :param ts: Initial items for a new auto-resizing circular array.
826
+ :returns: New variable storage capacity circular array.
740
827
 
741
828
  """
742
829
  return CA(ts)
@@ -31,19 +31,24 @@ class CAF[X]:
31
31
  - fixed total storage capacity
32
32
  - iterable but not threadsafe
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
  """
38
40
  __slots__ = '_xs', '_cnt', '_cap', '_front', '_rear'
39
41
 
40
42
  def __init__(self, *xs: Iterable[X], cap: int = 2) -> None:
41
43
  """
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.
44
+ .. admonition:: initializer
45
+
46
+ Populate ``CAF`` with an optional iterable
47
+ from front (left) to rear (right).
48
+
49
+ :param xs: Takes 0 or 1 iterable parameters.
50
+ :raises ValueError: When more than one parameter is provided.
51
+ :raises TypeError: When passed a non-iterable parameter.
47
52
 
48
53
  """
49
54
  cap = max(2, cap)
@@ -68,21 +73,39 @@ class CAF[X]:
68
73
  self._rear = cnt - 1
69
74
 
70
75
  def __bool__(self) -> bool:
76
+ """
77
+ .. admonition:: bool
78
+
79
+ - falsy if either empty or full
80
+ - truthy otherwise
81
+
82
+ :returns: ``True`` when partially filled,
83
+ ``False`` otherwise.
84
+
85
+ """
71
86
  return 0 < self._cnt < self._cap
72
87
 
73
88
  def __len__(self) -> int:
89
+ """
90
+ .. admonition:: length
91
+
92
+ Number of items in the ``CAF``.
93
+
94
+ :returns: The number of items in the ``CAF``.
95
+
96
+ """
74
97
  return self._cnt
75
98
 
76
99
  def __eq__(self, other: object) -> bool:
77
100
  """
78
- .. admonition:: Equality comparison
101
+ .. admonition:: equality comparison
79
102
 
80
103
  Efficiently compare ``CAF`` to another object.
81
104
 
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``.
105
+ :param other: The object to be compared.
106
+ :returns: ``True`` if ``other`` is another ``CAF`` whose
107
+ contents compare as equal to the corresponding
108
+ contents of the ``CAF``, otherwise ``False``.
86
109
 
87
110
  """
88
111
  if self is other:
@@ -123,6 +146,22 @@ class CAF[X]:
123
146
  return True
124
147
 
125
148
  def __iter__(self) -> Iterator[X]:
149
+ """
150
+ .. admonition:: iterate
151
+
152
+ Iterates circular array, front (left) to rear (right).
153
+
154
+ .. warning
155
+
156
+ Not thread safe, especially for long living iterators.
157
+
158
+ .. tip::
159
+
160
+ Cache contents to make more thread tolerant. Put
161
+ a lock around circular array during caching process
162
+ to make threadsafe.
163
+
164
+ """
126
165
  if self._cnt > 0:
127
166
  (
128
167
  cap,
@@ -142,6 +181,22 @@ class CAF[X]:
142
181
  yield cast(X, current_state[position])
143
182
 
144
183
  def __reversed__(self) -> Iterator[X]:
184
+ """
185
+ .. admonition:: reverse iterate
186
+
187
+ Iterates circular array, rear (right) to front (left).
188
+
189
+ .. warning
190
+
191
+ Not thread safe, especially for long living iterators.
192
+
193
+ .. tip::
194
+
195
+ Cache contents to make more thread tolerant. Put
196
+ a lock around circular array during caching process
197
+ to make threadsafe.
198
+
199
+ """
145
200
  if self._cnt > 0:
146
201
  (
147
202
  cap,
@@ -161,6 +216,13 @@ class CAF[X]:
161
216
  yield cast(X, current_state[position])
162
217
 
163
218
  def __getitem__(self, idx: int) -> X:
219
+ """
220
+ .. admonition:: getitem
221
+
222
+ Fixed capacity circular arrays are indexable but
223
+ not sliceable.
224
+
225
+ """
164
226
  cnt = self._cnt
165
227
  if 0 <= idx < cnt:
166
228
  return cast(X, self._xs[(self._front + idx) % self._cap])
@@ -178,6 +240,13 @@ class CAF[X]:
178
240
  raise IndexError(msg1 + msg2 + msg3)
179
241
 
180
242
  def __setitem__(self, idx: int, val: X) -> None:
243
+ """
244
+ .. admonition:: setitem
245
+
246
+ Fixed capacity circular arrays are indexable but
247
+ not sliceable.
248
+
249
+ """
181
250
  cnt = self._cnt
182
251
  if 0 <= idx < cnt:
183
252
  self._xs[(self._front + idx) % self._cap] = val
@@ -193,6 +262,13 @@ class CAF[X]:
193
262
  raise IndexError(msg1 + msg2 + msg3)
194
263
 
195
264
  def __delitem__(self, idx: int) -> None:
265
+ """
266
+ .. admonition:: delitem
267
+
268
+ Fixed capacity circular arrays are indexable but
269
+ not sliceable.
270
+
271
+ """
196
272
  item_list = list(self)
197
273
  del item_list[idx]
198
274
  _ca = CAF(item_list, cap = self._cap)
@@ -211,38 +287,37 @@ class CAF[X]:
211
287
 
212
288
  def __repr__(self) -> str:
213
289
  """
214
- .. admonition:: String representation
290
+ .. admonition:: repr string
215
291
 
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.
292
+ Construct string 'CAF(x₁, x₂, … xₙ)' where
293
+ x₁, x₂, … xₙ are the contents displayed with ``repr()``.
219
294
 
220
- :returns: A string to reproduce the ``CAF``.
295
+ :returns: A string to reproduce the ``CAF``.
221
296
 
222
297
  """
223
298
  return 'caf(' + ', '.join(map(repr, self)) + ')'
224
299
 
225
300
  def __str__(self) -> str:
226
301
  r"""
227
- .. admonition:: User string
302
+ .. admonition:: user string
303
+ Construct string '(\|x₁, x₂, … xₙ\|)' where
304
+ x₁, x₂, ..., xₙ are the contents displayed with ``str()``.
228
305
 
229
- Return '(\|x1, x2, ..., xn\|)'
230
- where x1, x2, ..., xn are the circular array's
231
- contents displayed as strings.
232
-
233
- :returns: A string meaningful to an end user.
306
+ :returns: A string meaningful to an end user.
234
307
 
235
308
  """
236
309
  return '(|' + ', '.join(map(str, self)) + '|)'
237
310
 
238
311
  def pushl(self, x: X) -> None:
239
312
  """
240
- .. admonition:: Push left
313
+ .. admonition:: push left
241
314
 
242
315
  Push single item from the left onto the ``CAF``.
243
316
 
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.
317
+ :param x: Single item to be pushed onto the front of
318
+ the ``CAF`` from the left.
319
+ :raises ValueError: When called on a full fixed storage
320
+ capacity circular array.
246
321
 
247
322
  """
248
323
  if self._cnt == self._cap:
@@ -261,12 +336,14 @@ class CAF[X]:
261
336
 
262
337
  def pushr(self, x: X) -> None:
263
338
  """
264
- .. admonition:: Push right
339
+ .. admonition:: push right
265
340
 
266
341
  Push single item from the right onto the ``CAF``.
267
342
 
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.
343
+ :param x: Single item to be pushed onto the rear of
344
+ the ``CAF`` from the right.
345
+ :raises ValueError: When called on a full fixed
346
+ storage capacity circular array.
270
347
 
271
348
  """
272
349
  if self._cnt == self._cap:
@@ -285,12 +362,12 @@ class CAF[X]:
285
362
 
286
363
  def popl(self) -> X:
287
364
  """
288
- .. admonition:: Pop left
365
+ .. admonition:: pop left
289
366
 
290
367
  Pop a single items off the left side of the ``CAF``.
291
368
 
292
- :returns: Item popped from left side (front) of circular array.
293
- :raises ValueError: When called on an empty circular array.
369
+ :returns: Item popped from left side (front) of the ``CAF``.
370
+ :raises ValueError: When called on an empty ``CAF``.
294
371
 
295
372
  """
296
373
  if self._cnt > 1:
@@ -326,12 +403,12 @@ class CAF[X]:
326
403
 
327
404
  def popr(self) -> X:
328
405
  """
329
- .. admonition:: Pop right
406
+ .. admonition:: pop right
330
407
 
331
408
  Pop a single items off the right side of the ``CAF``.
332
409
 
333
- :returns: Item popped from right side (rear) of circular array.
334
- :raises ValueError: When called on an empty circular array.
410
+ :returns: Item popped from right side (rear) of the ``CAF``.
411
+ :raises ValueError: When called on an empty ``CAF``.
335
412
 
336
413
  """
337
414
  if self._cnt > 1:
@@ -367,14 +444,14 @@ class CAF[X]:
367
444
 
368
445
  def popld(self, default: X) -> X:
369
446
  """
370
- .. admonition:: Pop Left with default
447
+ .. admonition:: pop Left with default
371
448
 
372
449
  Pop a single items off the left side of the ``CAF``.
373
450
 
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.
451
+ :param default: Default value to return if ``CAF`` is empty.
452
+ :returns: Item popped from left side (front) of the ``CAF``
453
+ if not empty, otherwise return the provided
454
+ default value.
378
455
 
379
456
  """
380
457
  try:
@@ -384,14 +461,14 @@ class CAF[X]:
384
461
 
385
462
  def poprd(self, default: X) -> X:
386
463
  """
387
- .. admonition:: Pop Right with default
464
+ .. admonition:: pop Right with default
388
465
 
389
466
  Pop a single items off the right side of the ``CAF``.
390
467
 
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.
468
+ :param default: Default value to return if ``CAF`` is empty.
469
+ :returns: Item popped from right side (rear) of the ``CAF``
470
+ if not empty, otherwise return the provided
471
+ default value.
395
472
 
396
473
  """
397
474
  try:
@@ -405,8 +482,9 @@ class CAF[X]:
405
482
 
406
483
  Pop items off the left side of the ``CAF``.
407
484
 
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.
485
+ :param maximum: Maximum number of items to pop,
486
+ may pop less if not enough items in ``CAF``.
487
+ :returns: A ``tuple`` of the items popped, left to right.
410
488
 
411
489
  """
412
490
  xs: list[X] = []
@@ -427,8 +505,9 @@ class CAF[X]:
427
505
 
428
506
  Pop items off the right side of the ``CAF``.
429
507
 
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.
508
+ :param maximum: Maximum number of items to pop,
509
+ may pop less if not enough items in ``CAF``.
510
+ :returns: A ``tuple`` of the items popped, right to left.
432
511
 
433
512
  """
434
513
  xs: list[X] = []
@@ -448,7 +527,8 @@ class CAF[X]:
448
527
  Rotate contents of ``CAF`` to the left putting first
449
528
  item onto rear.
450
529
 
451
- :param n: Number of times to shift items left. Default 1 time.
530
+ :param n: Number of times to shift items left.
531
+ Default 1 time.
452
532
 
453
533
  """
454
534
  if self._cnt < 2:
@@ -463,7 +543,8 @@ class CAF[X]:
463
543
  Rotate contents of ``CAF`` to the right putting last
464
544
  item onto front.
465
545
 
466
- :param n: Number of times to shift items right. Default 1 time.
546
+ :param n: Number of times to shift items right.
547
+ Default 1 time.
467
548
 
468
549
  """
469
550
  if self._cnt < 2:
@@ -477,8 +558,8 @@ class CAF[X]:
477
558
 
478
559
  Apply function ``f`` over the circular array's contents.
479
560
 
480
- :param f: Callable from type ``X`` to type ``Y``.
481
- :returns: New fixed capacity circular array instance.
561
+ :param f: Callable from type ``X`` to type ``Y``.
562
+ :returns: New fixed capacity circular array instance.
482
563
 
483
564
  """
484
565
  return CAF(map(f, self), cap = self._cap)
@@ -494,10 +575,12 @@ class CAF[X]:
494
575
 
495
576
  Fold ``CAF`` left with a function and optional starting item.
496
577
 
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.
578
+ :param f: Folding function, first argument to ``f`` is for
579
+ the accumulator.
580
+ :param start: Optional starting item.
581
+ :returns: Reduced value produced by the left fold.
582
+ :raises ValueError: When circular array empty and ``start``
583
+ not given.
501
584
 
502
585
  """
503
586
  if self._cnt == 0:
@@ -528,10 +611,12 @@ class CAF[X]:
528
611
 
529
612
  Fold ``CAF`` right left with a function and optional starting item.
530
613
 
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.
614
+ :param f: Folding function, second argument to ``f`` is for
615
+ the accumulator.
616
+ :param start: Optional starting item.
617
+ :returns: Reduced value produced by the right fold.
618
+ :raises ValueError: When circular array empty and ``start``
619
+ not given.
535
620
 
536
621
  """
537
622
  if self._cnt == 0:
@@ -557,8 +642,7 @@ class CAF[X]:
557
642
 
558
643
  Get the fixed storage capacity of the circular array.
559
644
 
560
-
561
- :returns: Fixed storage capacity.
645
+ :returns: Fixed storage capacity.
562
646
 
563
647
  """
564
648
  return self._cap
@@ -588,7 +672,7 @@ class CAF[X]:
588
672
 
589
673
  Find fraction of the storage capacity which is filled.
590
674
 
591
- :returns: The ratio count/capacity.
675
+ :returns: The ratio count/capacity.
592
676
 
593
677
  """
594
678
  return self._cnt / self._cap
@@ -598,11 +682,12 @@ def caf[T](*ts: T, cap: int = 2) -> CAF[T]:
598
682
  """
599
683
  .. admonition:: Circular array factory function
600
684
 
601
- Produce a circular array from a variable number of arguments.
685
+ Produce a fixed capacity circular array from
686
+ a variable number of arguments.
602
687
 
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.
688
+ :param ts: Initial items for a new fixed capacity circular array.
689
+ :param cap: The minimum storage capacity to set.
690
+ :returns: New fixed storage capacity circular array.
606
691
 
607
692
  """
608
693
  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 __eq__(self, other: object) -> bool: ...
11
+ def __iter__(self) -> Iterator[X]: ...
12
+ def __reversed__(self) -> Iterator[X]: ...
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: ...
@@ -5,10 +5,11 @@ __all__ = ['CA', 'ca']
5
5
 
6
6
  class CA[X]:
7
7
  def __init__(self, *xs: Iterable[X]) -> 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 __eq__(self, other: object) -> bool: ...
11
+ def __iter__(self) -> Iterator[X]: ...
12
+ def __reversed__(self) -> Iterator[X]: ...
12
13
  @overload
13
14
  def __getitem__(self, idx: int) -> X: ...
14
15
  @overload
@@ -21,7 +22,6 @@ class CA[X]:
21
22
  def __delitem__(self, idx: int) -> None: ...
22
23
  @overload
23
24
  def __delitem__(self, idx: slice) -> None: ...
24
- def __eq__(self, other: object) -> bool: ...
25
25
  def pushl(self, *xs: X) -> None: ...
26
26
  def pushr(self, *xs: X) -> None: ...
27
27
  def popl(self) -> X: ...