pythonic-fp-queues 5.1.1__py3-none-any.whl → 5.1.3__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.
@@ -1,4 +1,4 @@
1
- # Copyright 2023-2024 Geoffrey R. Scheller
1
+ # Copyright 2023-2026 Geoffrey R. Scheller
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -16,21 +16,13 @@
16
16
  Queues
17
17
  ------
18
18
 
19
- .. admonition:: Stateful Queues based on a circular array.
19
+ .. admonition:: Stateful Queues
20
20
 
21
- Geared to specific algorithms by limiting what can be done with the
22
- queues. Sometimes the power of a data structure is not what it
23
- empowers you to do, but what it prevents you from doing to yourself.
21
+ By limiting how their data can be accessed, each queue type
22
+ supports different algorithmic use cases.
24
23
 
25
- +-------------------------+-----------+--------------------------+
26
- | module | class | name |
27
- +=========================+===========+==========================+
28
- | pythonic_fp.queues.fifo | FIFOQueue | First-In-First-Out Queue |
29
- +-------------------------+-----------+--------------------------+
30
- | pythonic_fp.queues.lifo | LIFOQueue | Last-In-First-Out Queue |
31
- +-------------------------+-----------+--------------------------+
32
- | pythonic_fp.queues.de | DEQueue | Double-Ended Queue |
33
- +-------------------------+-----------+--------------------------+
24
+ Sometimes the power of a data structure comes not what it empowers
25
+ you to do, but what it prevents you from doing to yourself.
34
26
 
35
27
  """
36
28
 
pythonic_fp/queues/de.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2023-2025 Geoffrey R. Scheller
1
+ # Copyright 2023-2026 Geoffrey R. Scheller
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -21,84 +21,164 @@ __all__ = ['DEQueue', 'de_queue']
21
21
 
22
22
 
23
23
  class DEQueue[D]:
24
- """Stateful Double-Ended (DE) Queue data structure.
24
+ """
25
+ .. admonition:: DEQueue
26
+
27
+ Stateful Double-Ended (DE) Queue data structure.
25
28
 
26
- - O(1) pops each end
27
- - O(1) amortized pushes each end
28
- - O(1) length determination
29
- - in a Boolean context, truthy if not empty, falsy if empty
30
- - will automatically increase storage capacity when needed
31
- - neither indexable nor sliceable by design
29
+ - has a left and a right side
30
+ - O(1) pops each end
31
+ - O(1) amortized pushes each end
32
+ - O(1) length determination
33
+ - in a Boolean context, truthy if not empty, falsy if empty
34
+ - will automatically increase storage capacity when needed
35
+ - neither indexable nor sliceable by design
32
36
 
33
37
  """
34
38
 
35
39
  __slots__ = ('_ca',)
36
40
 
37
- def __init__(self, *dss: Iterable[D]) -> None:
41
+ def __init__(self, *ds: Iterable[D]) -> None:
38
42
  """
39
- :param dss: "Optionally" takes a single iterable to initialize data in FIFO order.
40
- :raises TypeError: When ``dss[0]`` not Iterable.
41
- :raises ValueError: If more than 1 iterable is given.
43
+ .. admonition:: Initializer
44
+
45
+ Initialize ``DEQueue`` with 0 or 1 iterables to populate
46
+ the queue left (front) to right (rear).
47
+
48
+ :param ds: Takes 0 or 1 iterable parameters.
49
+ :raises ValueError: When more than one parameter is provided.
50
+ :raises TypeError: When passed a non-iterable parameter.
42
51
 
43
52
  """
44
- if (size := len(dss)) > 1:
53
+ if (size := len(ds)) > 1:
45
54
  msg = f'DEQueue expects at most 1 argument, got {size}'
46
55
  raise ValueError(msg)
47
- self._ca = CA(dss[0]) if size == 1 else CA()
56
+ self._ca = CA(ds[0]) if size == 1 else CA()
48
57
 
49
58
  def __bool__(self) -> bool:
59
+ """
60
+ .. admonition:: Truthiness
61
+
62
+ Queue truthy when non-empty, falsy when empty.
63
+
64
+ """
50
65
  return len(self._ca) > 0
51
66
 
52
67
  def __len__(self) -> int:
68
+ """
69
+ .. admonition:: Get length
70
+
71
+ Return the number of data elements in the ``DEQueue``.
72
+
73
+ """
53
74
  return len(self._ca)
54
75
 
55
76
  def __eq__(self, other: object) -> bool:
77
+ """
78
+ .. admonition:: Equality comparison
79
+
80
+ If ``other`` is a ``DEQueue`` and the corresponding
81
+ elements of ``self`` and ``other`` compare as equal,
82
+ then return ``True``. Otherwise return ``False``.
83
+
84
+ :returns: ``self == other``
85
+
86
+ """
56
87
  if not isinstance(other, DEQueue):
57
88
  return False
58
89
  return self._ca == other._ca
59
90
 
60
91
  def __iter__(self) -> Iterator[D]:
92
+ """
93
+ .. admonition:: Iteration
94
+
95
+ Iterate over current state left to right.
96
+
97
+ :returns: An iterator of the data.
98
+
99
+ """
61
100
  return iter(list(self._ca))
62
101
 
63
102
  def __reversed__(self) -> Iterator[D]:
103
+ """
104
+ .. admonition:: Iteration
105
+
106
+ Iterate over current state right to left.
107
+
108
+ :returns: An iterator of the data.
109
+
110
+ """
64
111
  return reversed(list(self._ca))
65
112
 
66
113
  def __repr__(self) -> str:
114
+ """
115
+ .. admonition:: String representation
116
+
117
+ Construct string 'DEQueue(d₁, d₂, … dₙ)' where
118
+
119
+ - d₁, d₂, … dₙ are the contents displayed with ``repr()``
120
+
121
+ :returns: A string to reproduce the ``DEQueue``.
122
+
123
+ """
67
124
  if len(self) == 0:
68
125
  return 'DEQueue()'
69
126
  return 'DEQueue(' + ', '.join(map(repr, self._ca)) + ')'
70
127
 
71
128
  def __str__(self) -> str:
129
+ r"""
130
+ .. admonition:: User string
131
+
132
+ Construct string '>< d₁ | d₂ | … | dₙ ><' where
133
+
134
+ - d₁, d₂, ..., dₙ are the contents displayed with ``str()``
135
+
136
+ :returns: A string meaningful to an end user.
137
+
138
+ """
72
139
  return '>< ' + ' | '.join(map(str, self)) + ' ><'
73
140
 
74
141
  def copy(self) -> 'DEQueue[D]':
75
- """Shallow copy.
142
+ """
143
+ .. admonition:: Copy
144
+
145
+ Shallow copy the ``DEQueue``.
76
146
 
77
- :returns: Shallow copy of the DEQueue.
147
+ :returns: New ``DEQueue`` instance containing the same references.
78
148
 
79
149
  """
80
150
  return DEQueue(self._ca)
81
151
 
82
152
  def pushl(self, *ds: D) -> None:
83
- """Push data onto left side of DEQueue.
153
+ """
154
+ .. admonition:: Push left
155
+
156
+ Push data onto left side of ``DEQueue``.
84
157
 
85
- :param ds: Items to be pushed onto DEQueue from the left.
158
+ :param ds: Data to be pushed onto ``DEQueue`` from the left.
86
159
 
87
160
  """
88
161
  self._ca.pushl(*ds)
89
162
 
90
163
  def pushr(self, *ds: D) -> None:
91
- """Push data onto right side of DEQueue.
164
+ """
165
+ .. admonition:: Push right
166
+
167
+ Push data onto right side of ``DEQueue``.
92
168
 
93
- :param ds: Items to be pushed onto DEQueue from the right.
169
+ :param ds: Data to be pushed onto ``DEQueue`` from the right.
94
170
 
95
171
  """
96
172
  self._ca.pushr(*ds)
97
173
 
98
174
  def popl(self) -> MayBe[D]:
99
- """Pop next item from left side DEQueue, if it exists.
175
+ """
176
+ .. admonition:: Pop left
100
177
 
101
- :returns: MayBe of popped item if queue was not empty, empty MayBe otherwise.
178
+ Pop next item from left side ``DEQueue``, if it exists.
179
+
180
+ :returns: ``MayBe`` of popped item if queue was not empty,
181
+ empty ``MayBe`` otherwise.
102
182
 
103
183
  """
104
184
  if self._ca:
@@ -106,9 +186,13 @@ class DEQueue[D]:
106
186
  return MayBe()
107
187
 
108
188
  def popr(self) -> MayBe[D]:
109
- """Pop next item off right side DEQueue, if it exists.
189
+ """
190
+ .. admonition:: Pop right
110
191
 
111
- :returns: MayBe of popped item if queue was not empty, empty MayBe otherwise.
192
+ Pop next item off right side ''DEQueue``, if it exists.
193
+
194
+ :returns: ``MayBe`` of popped item if queue was not empty,
195
+ empty ``MayBe`` otherwise.
112
196
 
113
197
  """
114
198
  if self._ca:
@@ -116,9 +200,13 @@ class DEQueue[D]:
116
200
  return MayBe()
117
201
 
118
202
  def peakl(self) -> MayBe[D]:
119
- """Peak left side of DEQueue. Does not consume item.
203
+ """
204
+ .. admonition:: Peak left
120
205
 
121
- :returns: MayBe of leftmost item if queue not empty, empty MayBe otherwise.
206
+ Peak left side of ``DEQueue``. Does not consume item.
207
+
208
+ :returns: ``MayBe`` of leftmost item if queue not empty,
209
+ empty ``MayBe`` otherwise.
122
210
 
123
211
  """
124
212
  if self._ca:
@@ -126,9 +214,13 @@ class DEQueue[D]:
126
214
  return MayBe()
127
215
 
128
216
  def peakr(self) -> MayBe[D]:
129
- """Peak right side of DEQueue. Does not consume item.
217
+ """
218
+ .. admonition:: Peak right
130
219
 
131
- :returns: MayBe of rightmost item if queue not empty, empty MayBe otherwise.
220
+ Peak right side of ``DEQueue``. Does not consume item.
221
+
222
+ :returns: ``MayBe`` of rightmost item if queue not empty,
223
+ empty ``MayBe`` otherwise.
132
224
 
133
225
  """
134
226
  if self._ca:
@@ -141,11 +233,15 @@ class DEQueue[D]:
141
233
  def foldl[L](self, f: Callable[[L, D], L], start: L) -> MayBe[L]: ...
142
234
 
143
235
  def foldl[L](self, f: Callable[[L, D], L], start: L | None = None) -> MayBe[L]:
144
- """Reduces DEQueue left to right.
236
+ """
237
+ .. admonition:: Fold left
238
+
239
+ Reduce ``DEQueue`` left to right.
145
240
 
146
241
  :param f: Reducing function, first argument is for accumulator.
147
242
  :param start: Optional starting value.
148
- :returns: MayBe of reduced value with f, empty MayBe if queue empty and no starting value given.
243
+ :returns: ``MayBe`` of reduced value with ``f``, empty ``MayBe`` if
244
+ queue empty and no starting value given.
149
245
 
150
246
  """
151
247
  if start is None:
@@ -160,11 +256,15 @@ class DEQueue[D]:
160
256
  def foldr[R](self, f: Callable[[D, R], R], start: R) -> MayBe[R]: ...
161
257
 
162
258
  def foldr[R](self, f: Callable[[D, R], R], start: R | None = None) -> MayBe[R]:
163
- """Reduces DEQueue right to left.
259
+ """
260
+ .. admonition:: Fold right
261
+
262
+ Reduce ``DEQueue`` right to left.
164
263
 
165
264
  :param f: Reducing function, second argument is for accumulator.
166
265
  :param start: Optional starting value.
167
- :returns: MayBe of reduced value with f, empty MayBe if queue empty and no starting value given.
266
+ :returns: ``MayBe`` of reduced value with ``f``, empty ``MayBe``
267
+ if queue empty and no starting value given.
168
268
 
169
269
  """
170
270
  if start is None:
@@ -174,24 +274,31 @@ class DEQueue[D]:
174
274
  return MayBe(self._ca.foldr(f, start))
175
275
 
176
276
  def map[U](self, f: Callable[[D], U]) -> 'DEQueue[U]':
177
- """Map left to right.
277
+ """
278
+ .. admonition:: Map
178
279
 
179
- .. tip::
280
+ Map left to right.
180
281
 
181
- Order map done does not matter if ``f`` is pure.
282
+ .. tip::
283
+
284
+ Order map done does not matter if ``f`` is pure.
182
285
 
183
286
  :param f: Function to map over queue.
184
- :returns: New DEQueue instance, retain original order.
287
+ :returns: New ``DEQueue`` instance, retain original order.
185
288
 
186
289
  """
187
290
  return DEQueue(map(f, self._ca))
188
291
 
189
292
 
190
293
  def de_queue[D](*ds: D) -> DEQueue[D]:
191
- """DEQueue factory function.
294
+ """
295
+ .. admonition:: Create DEQueue
296
+
297
+ Factory function to create a ``DEQueue``
298
+ instance from the function's arguments.
192
299
 
193
- :param ds: Initial items as if pushed on from right to left.
194
- :returns: DEQueue with items initialized in FIFO order.
300
+ :param ds: Initial data to be pushed on right to left.
301
+ :returns: A new ``DEQueue`` instance.
195
302
 
196
303
  """
197
304
  return DEQueue(ds)
@@ -1,4 +1,4 @@
1
- # Copyright 2023-2024 Geoffrey R. Scheller
1
+ # Copyright 2023-2026 Geoffrey R. Scheller
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -21,72 +21,141 @@ __all__ = ['FIFOQueue', 'fifo_queue']
21
21
 
22
22
 
23
23
  class FIFOQueue[D]:
24
- """Stateful First-In-First-Out (FIFO) Queue data structure.
24
+ """
25
+ .. admonition:: FIFOQueue
26
+
27
+ Stateful First-In-First-Out (FIFO) Queue data structure.
25
28
 
26
- - O(1) pops
27
- - O(1) amortized pushes
28
- - O(1) length determination
29
- - in a Boolean context, truthy if not empty, falsy if empty
30
- - will automatically increase storage capacity when needed
31
- - neither indexable nor sliceable by design
29
+ - O(1) pops
30
+ - O(1) amortized pushes
31
+ - O(1) length determination
32
+ - in a Boolean context, truthy if not empty, falsy if empty
33
+ - will automatically increase storage capacity when needed
34
+ - neither indexable nor sliceable by design
32
35
 
33
36
  """
34
37
 
35
38
  __slots__ = ('_ca',)
36
39
 
37
- def __init__(self, *dss: Iterable[D]) -> None:
40
+ def __init__(self, *ds: Iterable[D]) -> None:
38
41
  """
39
- :param dss: Takes 1 or 0 iterables, initializes items in natural FIFO order.
40
- :raises ValueError: If more than 1 iterable is given.
42
+ .. admonition:: Initializer
43
+
44
+ Initialize ``FIFOQueue`` with 0 or 1 iterables to populate
45
+ the queue in natural FIFO order.
46
+
47
+ :param ds: Takes 0 or 1 iterable parameters.
48
+ :raises ValueError: When more than one parameter is provided.
49
+ :raises TypeError: When passed a non-iterable parameter.
41
50
 
42
51
  """
43
- if (size := len(dss)) > 1:
52
+ if (size := len(ds)) > 1:
44
53
  msg = f'FIFOQueue expects at most 1 iterable argument, got {size}'
45
54
  raise ValueError(msg)
46
- self._ca = CA(dss[0]) if size == 1 else CA()
55
+ self._ca = CA(ds[0]) if size == 1 else CA()
47
56
 
48
57
  def __bool__(self) -> bool:
58
+ """
59
+ .. admonition:: Truthiness
60
+
61
+ ``FIFOQueue`` truthy when non-empty, falsy when empty.
62
+
63
+ """
49
64
  return len(self._ca) > 0
50
65
 
51
66
  def __len__(self) -> int:
67
+ """
68
+ .. admonition:: Get length
69
+
70
+ Return the number of data elements in the ``FIFOQueue``.
71
+
72
+ """
52
73
  return len(self._ca)
53
74
 
54
75
  def __eq__(self, other: object) -> bool:
76
+ """
77
+ .. admonition:: Equality comparison
78
+
79
+ If ``other`` is a ``FIFOQueue`` and the corresponding
80
+ elements of ``self`` and ``other`` compare as equal,
81
+ then return ``True``. Otherwise return ``False``.
82
+
83
+ :returns: ``self == other``
84
+
85
+ """
55
86
  if not isinstance(other, FIFOQueue):
56
87
  return False
57
88
  return self._ca == other._ca
58
89
 
59
90
  def __iter__(self) -> Iterator[D]:
91
+ """
92
+ .. admonition:: Iteration
93
+
94
+ Iterate over current state in natural FIFO order.
95
+
96
+ :returns: An iterator of the data.
97
+
98
+ """
60
99
  return iter(list(self._ca))
61
100
 
62
101
  def __repr__(self) -> str:
102
+ """
103
+ .. admonition:: String representation
104
+
105
+ Construct string 'FIFOQueue(d₁, d₂, … dₙ)' where
106
+
107
+ - d₁, d₂, … dₙ are the contents displayed with ``repr()``
108
+
109
+ :returns: A string to reproduce the ``FIFOQueue``.
110
+
111
+ """
63
112
  if len(self) == 0:
64
113
  return 'FIFOQueue()'
65
114
  return 'FIFOQueue(' + ', '.join(map(repr, self._ca)) + ')'
66
115
 
67
116
  def __str__(self) -> str:
117
+ """
118
+ .. admonition:: User string
119
+
120
+ Construct string '<< d₁ < d₂ < … < dₙ <<' where
121
+
122
+ - d₁, d₂, ..., dₙ are the contents displayed with ``str()``
123
+
124
+ :returns: A string meaningful to an end user.
125
+
126
+ """
68
127
  return '<< ' + ' < '.join(map(str, self)) + ' <<'
69
128
 
70
129
  def copy(self) -> 'FIFOQueue[D]':
71
- """Shallow copy.
130
+ """
131
+ .. admonition:: Copy
72
132
 
73
- :returns: Shallow copy of the FIFOQueue.
133
+ Shallow copy the ``FIFOQueue``.
134
+
135
+ :returns: New ``FIFOQueue`` instance containing the same references.
74
136
 
75
137
  """
76
138
  return FIFOQueue(self._ca)
77
139
 
78
140
  def push(self, *ds: D) -> None:
79
- """Push items onto FIFOQueue.
141
+ """
142
+ .. admonition:: Push
143
+
144
+ Push data items onto ``FIFOQueue``.
80
145
 
81
- :param ds: Items to be pushed onto FIFOQueue.
146
+ :param ds: Items to be pushed onto ''FIFOQueue''.
82
147
 
83
148
  """
84
149
  self._ca.pushr(*ds)
85
150
 
86
151
  def pop(self) -> MayBe[D]:
87
- """Pop oldest data item off of FIFOQueue.
152
+ """
153
+ .. admonition:: Pop
154
+
155
+ Pop oldest data item off of ``FIFOQueue``.
88
156
 
89
- :returns: MayBe of popped data item if queue was not empty, empty MayBe otherwise.
157
+ :returns: ``MayBe`` of popped data item if ``FIFOQueue``
158
+ was not empty, empty ``MayBe`` otherwise.
90
159
 
91
160
  """
92
161
  if self._ca:
@@ -94,9 +163,13 @@ class FIFOQueue[D]:
94
163
  return MayBe()
95
164
 
96
165
  def peak_last_in(self) -> MayBe[D]:
97
- """Peak at newest item on queue.
166
+ """
167
+ .. admonition:: Peak last
98
168
 
99
- :returns: MayBe of newest item on queue, empty MayBe if queue empty.
169
+ Peak at newest item on ``FIFOQueue``.
170
+
171
+ :returns: ``MayBe`` of newest item on ``FIFOQueue``,
172
+ empty ``MayBe`` if ``FIFOQueue`` empty.
100
173
 
101
174
  """
102
175
  if self._ca:
@@ -104,9 +177,13 @@ class FIFOQueue[D]:
104
177
  return MayBe()
105
178
 
106
179
  def peak_next_out(self) -> MayBe[D]:
107
- """Peak at oldest data item on queue.
180
+ """
181
+ .. admonition:: Peak next out
182
+
183
+ Peak at oldest data item on ``FIFOQueue``.
108
184
 
109
- :returns: MayBe of oldest item on queue, empty MayBe if queue empty.
185
+ :returns: ``MayBe`` of oldest item on ``FIFOQueue``,
186
+ empty ``MayBe`` if ``FIFOueue`` empty.
110
187
 
111
188
  """
112
189
  if self._ca:
@@ -119,11 +196,15 @@ class FIFOQueue[D]:
119
196
  def fold[T](self, f: Callable[[T, D], T], start: T) -> MayBe[T]: ...
120
197
 
121
198
  def fold[T](self, f: Callable[[T, D], T], start: T | None = None) -> MayBe[T]:
122
- """Reduces FIFOQueue in natural FIFO Order, oldest to newest.
199
+ """
200
+ .. admonition:: Fold
201
+
202
+ Reduces ``FIFOQueue`` in natural FIFO Order, oldest to newest.
123
203
 
124
204
  :param f: Reducing function, first argument is for accumulator.
125
205
  :param start: Optional starting value.
126
- :returns: MayBe of reduced value, empty MayBe if queue empty and no starting value given.
206
+ :returns: ``MayBe`` of reduced value with ``f``, empty ``MayBe``
207
+ if ``FIFOQueue`` empty and no starting value given.
127
208
 
128
209
  """
129
210
  if start is None:
@@ -133,20 +214,27 @@ class FIFOQueue[D]:
133
214
  return MayBe(self._ca.foldl(f, start))
134
215
 
135
216
  def map[U](self, f: Callable[[D], U]) -> 'FIFOQueue[U]':
136
- """Map f over the FIFOQueue, retain original order.
217
+ """
218
+ .. admonition:: Map
137
219
 
138
- :param f: Function to map over queue.
139
- :returns: New FIFOQueue instance.
220
+ Map ``f`` over the ``FIFOQueue``, retain original order.
221
+
222
+ :param f: Function to map over ``FIFOQueue``.
223
+ :returns: New ``FIFOQueue`` instance.
140
224
 
141
225
  """
142
226
  return FIFOQueue(map(f, self._ca))
143
227
 
144
228
 
145
229
  def fifo_queue[D](*ds: D) -> FIFOQueue[D]:
146
- """FIFOQueue factory function.
230
+ """
231
+ .. admonition:: Create FIFOQueue
232
+
233
+ Factory function to create an ``FIFOQueue``
234
+ instance from the function's arguments.
147
235
 
148
- :param ds: Initial items pushed on in FIFO order.
149
- :returns: FIFOQueue with initialized items from ``ds``.
236
+ :param ds: Initial data to be pushed on in FIFO order.
237
+ :returns: New ``FIFOQueue`` instance.
150
238
 
151
239
  """
152
240
  return FIFOQueue(ds)
@@ -1,4 +1,4 @@
1
- # Copyright 2023-2024 Geoffrey R. Scheller
1
+ # Copyright 2023-2026 Geoffrey R. Scheller
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -22,71 +22,140 @@ __all__ = ['LIFOQueue', 'lifo_queue']
22
22
 
23
23
 
24
24
  class LIFOQueue[D]:
25
- """Stateful Last-In-First-Out (LIFO) Queue data structure.
25
+ """
26
+ .. admonition:: LIFOQueue
27
+
28
+ Stateful Last-In-First-Out (LIFO) Queue data structure.
26
29
 
27
- - O(1) pops
28
- - O(1) amortized pushes
29
- - O(1) length determination
30
- - in a Boolean context, true if not empty, false if empty
31
- - will automatically increase storage capacity when needed
32
- - neither indexable nor sliceable by design
30
+ - O(1) pops
31
+ - O(1) amortized pushes
32
+ - O(1) length determination
33
+ - in a Boolean context, true if not empty, false if empty
34
+ - will automatically increase storage capacity when needed
35
+ - neither indexable nor sliceable by design
33
36
 
34
37
  """
35
38
  __slots__ = ('_ca',)
36
39
 
37
- def __init__(self, *dss: Iterable[D]) -> None:
40
+ def __init__(self, *ds: Iterable[D]) -> None:
38
41
  """
39
- :param dss: Takes 1 or 0 iterables, initializes data in natural LIFO order.
40
- :raises ValueError: If more than 1 iterable is given.
42
+ .. admonition:: Initializer
43
+
44
+ Initialize ``LIFOQueue`` with 0 or 1 iterables to populate
45
+ the queue in natural LIFO order.
46
+
47
+ :param ds: Takes 0 or 1 iterable parameters.
48
+ :raises ValueError: When more than one parameter is provided.
49
+ :raises TypeError: When passed a non-iterable parameter.
41
50
 
42
51
  """
43
- if (size := len(dss)) > 1:
52
+ if (size := len(ds)) > 1:
44
53
  msg = f'LIFOQueue expects at most 1 iterable argument, got {size}'
45
54
  raise ValueError(msg)
46
- self._ca = CA(dss[0]) if size == 1 else CA()
55
+ self._ca = CA(ds[0]) if size == 1 else CA()
47
56
 
48
57
  def __bool__(self) -> bool:
58
+ """
59
+ .. admonition:: Truthiness
60
+
61
+ ``LIFOQueue`` truthy when non-empty, falsy when empty.
62
+
63
+ """
49
64
  return len(self._ca) > 0
50
65
 
51
66
  def __len__(self) -> int:
67
+ """
68
+ .. admonition:: Get length
69
+
70
+ Return the number of data elements in the ``LIFOQueue``.
71
+
72
+ """
52
73
  return len(self._ca)
53
74
 
54
75
  def __eq__(self, other: object) -> bool:
76
+ """
77
+ .. admonition:: Equality comparison
78
+
79
+ If ``other`` is a ``LIFOQueue`` and the corresponding
80
+ elements of ``self`` and ``other`` compare as equal,
81
+ then return ``True``. Otherwise return ``False``.
82
+
83
+ :returns: ``self == other``
84
+
85
+ """
55
86
  if not isinstance(other, LIFOQueue):
56
87
  return False
57
88
  return self._ca == other._ca
58
89
 
59
90
  def __iter__(self) -> Iterator[D]:
91
+ """
92
+ .. admonition:: Iteration
93
+
94
+ Iterate over current state in natural LIFO order.
95
+
96
+ :returns: Iterator of the data.
97
+
98
+ """
60
99
  return reversed(list(self._ca))
61
100
 
62
101
  def __repr__(self) -> str:
102
+ """
103
+ .. admonition:: String representation
104
+
105
+ Construct string 'LIFOQueue(d₁, d₂, … dₙ)' where
106
+
107
+ - d₁, d₂, … dₙ are the contents displayed with ``repr()``
108
+
109
+ :returns: A string to reproduce the ``LIFOQueue``.
110
+
111
+ """
63
112
  if len(self) == 0:
64
113
  return 'LIFOQueue()'
65
114
  return 'LIFOQueue(' + ', '.join(map(repr, self._ca)) + ')'
66
115
 
67
116
  def __str__(self) -> str:
117
+ r"""
118
+ .. admonition:: User string
119
+
120
+ Construct string '|| d₁ > d₂ > … > dₙ ><' where
121
+
122
+ - d₁, d₂, ..., dₙ are the contents displayed with ``str()``
123
+
124
+ :returns: A string meaningful to an end user.
125
+
126
+ """
68
127
  return '|| ' + ' > '.join(map(str, self)) + ' ><'
69
128
 
70
129
  def copy(self) -> 'LIFOQueue[D]':
71
- """Shallow copy.
130
+ """
131
+ .. admonition:: Copy
132
+
133
+ Shallow copy the ``LIFOQueue``.
72
134
 
73
- :returns: Shallow copy of the LIFOQueue.
135
+ :returns: New ``LIFOQueue`` instance containing the same references.
74
136
 
75
137
  """
76
138
  return LIFOQueue(reversed(self._ca))
77
139
 
78
140
  def push(self, *ds: D) -> None:
79
- """Push items onto LIFOQueue.
141
+ """
142
+ .. admonition:: Push
80
143
 
81
- :param ds: Items to be pushed onto LIFOQueue.
144
+ Push items onto ``LIFOQueue``.
145
+
146
+ :param ds: Items to be pushed onto ``LIFOQueue``.
82
147
 
83
148
  """
84
149
  self._ca.pushr(*ds)
85
150
 
86
151
  def pop(self) -> MayBe[D]:
87
- """Pop newest data item off of LIFOQueue.
152
+ """
153
+ .. admonition:: Pop
154
+
155
+ Pop newest data item off of ``LIFOQueue``.
88
156
 
89
- :returns: MayBe of popped item if queue was not empty, empty MayBe otherwise.
157
+ :returns: ``MayBe`` of popped data item if ``LIFOQueue``
158
+ was not empty, empty `MayBe` otherwise.
90
159
 
91
160
  """
92
161
  if self._ca:
@@ -94,9 +163,12 @@ class LIFOQueue[D]:
94
163
  return MayBe()
95
164
 
96
165
  def peak(self) -> MayBe[D]:
97
- """Peak at newest item on queue.
166
+ """
167
+ .. admonition:: Peak last
168
+
169
+ Peak at newest item on ``LIFOQueue``.
98
170
 
99
- :returns: MayBe of newest item on queue, empty MayBe if queue empty.
171
+ :returns: ``MayBe`` of newest item on queue, empty ``MayBe`` if queue empty.
100
172
 
101
173
  """
102
174
  if self._ca:
@@ -109,11 +181,15 @@ class LIFOQueue[D]:
109
181
  def fold[T](self, f: Callable[[T, D], T], start: T) -> MayBe[T]: ...
110
182
 
111
183
  def fold[T](self, f: Callable[[T, D], T], start: T | None = None) -> MayBe[T]:
112
- """Reduces LIFOQUEUE in natural LIFO Order, newest to oldest.
184
+ """
185
+ .. admonition:: Fold
186
+
187
+ Reduces ``LIFOQUEUE`` in natural LIFO Order, newest to oldest.
113
188
 
114
189
  :param f: Reducing function, first argument is for accumulator.
115
190
  :param start: Optional starting value.
116
- :returns: MayBe of reduced value, empty MayBe if queue empty and no starting value given.
191
+ :returns: ``MayBe`` of reduced value with ``f``, empty ``MayBe``
192
+ if ``LIFOQueue`` empty and no starting value given.
117
193
 
118
194
  """
119
195
  if start is None:
@@ -123,20 +199,27 @@ class LIFOQueue[D]:
123
199
  return MayBe(self._ca.foldr(swap(f), start))
124
200
 
125
201
  def map[U](self, f: Callable[[D], U]) -> 'LIFOQueue[U]':
126
- """Map f over the LIFOQueue, retain original order.
202
+ """
203
+ .. admonition:: Map
204
+
205
+ Map ``f`` over the ``LIFOQueue``, retain original order.
127
206
 
128
- :param f: Function to map over queue.
129
- :returns: New LIFOQueue instance.
207
+ :param f: Function to map over ``LIFOQueue``.
208
+ :returns: New ``LIFOQueue`` instance.
130
209
 
131
210
  """
132
211
  return LIFOQueue(reversed(CA(map(f, reversed(self._ca)))))
133
212
 
134
213
 
135
214
  def lifo_queue[D](*ds: D) -> LIFOQueue[D]:
136
- """LIFOQueue factory function.
215
+ """
216
+ .. admonition:: Create LIFOQueue
217
+
218
+ Factory function to create an ``LIFOQUEUE``
219
+ instance from the function's arguments.
137
220
 
138
- :param ds: Initial items pushed on in LIFO order.
139
- :returns: LIFOQueue with initialized items from ``ds``.
221
+ :param ds: Items pushed onto queue in LIFO order.
222
+ :returns: New ``LIFOQueue`` instance.
140
223
 
141
224
  """
142
225
  return LIFOQueue(ds)
@@ -1,25 +1,26 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-queues
3
- Version: 5.1.1
3
+ Version: 5.1.3
4
4
  Summary: Queues
5
5
  Keywords: queue,fifo,lifo,dqueue
6
6
  Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
7
- Requires-Python: >=3.12
7
+ Requires-Python: >=3.13
8
8
  Description-Content-Type: text/x-rst
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
- Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
15
  Classifier: Typing :: Typed
16
16
  License-File: LICENSE
17
- Requires-Dist: pythonic-fp-circulararray>=6.0.1
17
+ Requires-Dist: pythonic-fp-circulararray>=6.0.4
18
18
  Requires-Dist: pythonic-fp-fptools>=5.2.0
19
+ Requires-Dist: pythonic-fp-gadgets>=4.1.0
19
20
  Requires-Dist: pytest>=8.4.1 ; extra == "test"
20
21
  Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-queues/blob/main/CHANGELOG.rst
21
- Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/queues/development/build/html/
22
- Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/homepage/build/html/
22
+ Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/projects/queues.html
23
+ Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/
23
24
  Project-URL: Source, https://github.com/grscheller/pythonic-fp-queues
24
25
  Provides-Extra: test
25
26
 
@@ -27,8 +28,8 @@ Pythonic FP - Queues
27
28
  ====================
28
29
 
29
30
  PyPI project
30
- `pythonic-fp.queues
31
- <https://pypi.org/project/pythonic-fp.queues>`_.
31
+ `pythonic-fp-queues
32
+ <https://pypi.org/project/pythonic-fp-queues>`_.
32
33
 
33
34
  +-------------------------+-----------+--------------------------+
34
35
  | module | class | name |
@@ -42,19 +43,23 @@ PyPI project
42
43
 
43
44
  Part of the
44
45
  `pythonic-fp
45
- <https://grscheller.github.io/pythonic-fp>`_
46
+ <https://grscheller.github.io/pythonic-fp/>`_
46
47
  PyPI projects.
47
48
 
48
49
  Documentation
49
50
  -------------
50
51
 
52
+ Documentation and other links for this project are hosted on
53
+ `GitHub Pages
54
+ <https://grscheller.github.io/pythonic-fp/projects/queues.html>`_.
55
+
51
56
  Documentation for this project is hosted on
52
57
  `GitHub Pages
53
- <https://grscheller.github.io/pythonic-fp/queues>`_.
58
+ <https://grscheller.github.io/pythonic-fp-queues/development/html/>`_.
54
59
 
55
60
  Copyright and License
56
61
  ---------------------
57
62
 
58
- Copyright (c) 2023-2025 Geoffrey R. Scheller. Licensed under the Apache
63
+ Copyright (c) 2023-2026 Geoffrey R. Scheller. Licensed under the Apache
59
64
  License, Version 2.0. See the LICENSE file for details.
60
65
 
@@ -0,0 +1,13 @@
1
+ pythonic_fp/queues/__init__.py,sha256=NOkkXOQaHmiemvY4Ke5ZdFJCl3_P3bmV87Xz5Y-R9cU,1028
2
+ pythonic_fp/queues/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ pythonic_fp/queues/de.py,sha256=ICPHkGz0JKIk8aLk75ZUSPS6T9jSTynkJ-2A5Sy_iig,8532
4
+ pythonic_fp/queues/de.pyi,sha256=db74UiSLFme25Yhc28Hhw3EKb2GfvU4wNBJtkTlr_e4,1150
5
+ pythonic_fp/queues/fifo.py,sha256=qQhv57VuF2QuaRtGJhCtj5qtGPjoGKlQS9RbZIGsvmY,6803
6
+ pythonic_fp/queues/fifo.pyi,sha256=19TGU3Qg91hCLo5A-5p9vmREcl38EUWhIAvJZtlb1eA,885
7
+ pythonic_fp/queues/lifo.py,sha256=lQAzoCOzQrw3gF2A_GgF_4XkYpNivswPyZS-Qp5bxYw,6471
8
+ pythonic_fp/queues/lifo.pyi,sha256=HdJ-t7R2w3VfCT06raCTXespdUZfpBgMepBlcxDvyuk,832
9
+ pythonic_fp/queues/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ pythonic_fp_queues-5.1.3.dist-info/licenses/LICENSE,sha256=IJMkVWQUVy-SonK6SMaMotDQ6Zb-lVi2bUTiGp1GUO8,10774
11
+ pythonic_fp_queues-5.1.3.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
12
+ pythonic_fp_queues-5.1.3.dist-info/METADATA,sha256=CeQO0Dt1zxfeu94F7ziEET_hegfeZUjlpzzoIzzdQr4,2392
13
+ pythonic_fp_queues-5.1.3.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- pythonic_fp/queues/__init__.py,sha256=MDXOn4_zIir0vvzaDpodmSCHN1usLSIqebEpFI9TPhQ,1625
2
- pythonic_fp/queues/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- pythonic_fp/queues/de.py,sha256=EApnwnvGmOrzvbx0MEhspp_wlDtqMuJlJKPRip1b4hY,6084
4
- pythonic_fp/queues/de.pyi,sha256=db74UiSLFme25Yhc28Hhw3EKb2GfvU4wNBJtkTlr_e4,1150
5
- pythonic_fp/queues/fifo.py,sha256=aj34iqFfh4YTHKG9_QEZpSvnUdzkng-IeCjZQxOuWQ8,4602
6
- pythonic_fp/queues/fifo.pyi,sha256=19TGU3Qg91hCLo5A-5p9vmREcl38EUWhIAvJZtlb1eA,885
7
- pythonic_fp/queues/lifo.py,sha256=gvrZKgUbBVNA1I03Q1AGh8rLBOzmnpI2herrjCTzR7A,4414
8
- pythonic_fp/queues/lifo.pyi,sha256=HdJ-t7R2w3VfCT06raCTXespdUZfpBgMepBlcxDvyuk,832
9
- pythonic_fp/queues/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- pythonic_fp_queues-5.1.1.dist-info/licenses/LICENSE,sha256=IJMkVWQUVy-SonK6SMaMotDQ6Zb-lVi2bUTiGp1GUO8,10774
11
- pythonic_fp_queues-5.1.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
12
- pythonic_fp_queues-5.1.1.dist-info/METADATA,sha256=ODc-wRv37wtjI64ZGS8nAHus6xgh4KQCzQgeuzOVWrY,2218
13
- pythonic_fp_queues-5.1.1.dist-info/RECORD,,