pythonic-fp.splitends 2.0.0__py3-none-any.whl → 2.0.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 2024-2025 Geoffrey R. Scheller
1
+ # Copyright 2024-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.
@@ -12,26 +12,30 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- """Mutable stack objects that can safely share data.
15
+ """
16
+ .. admonition:: Mutable stack objects that can safely share data
17
+
18
+ Python package implementing a singularly linked stack of nodes called a ``SplitEnd``.
19
+ While mutable, these data structures can safely share immutable data nodes between
20
+ themselves. These nodes, of type ``SENode``, always contain data. A root node is
21
+ a node whose previous node is itself. Root nodes mark the bottom of the stack.
22
+
23
+ Like one of many "split ends" from shafts of hair, a ``SplitEnd`` can be "snipped"
24
+ shorter or "extended" further from its "end" node at the top of the stack. Its "root"
25
+ node is at the bottom of the stack and can not be "snipped" or "cut" off.
16
26
 
17
- Python package implementing a singularly linked stack of nodes called a ``SplitEnd``.
18
- While mutable, these data structures can safely share immutable data nodes between
19
- themselves. These nodes, of type ``SENode``, always contain data. A root node is
20
- a node whose previous node is itself. Root nodes mark the bottom of the stack.
27
+ A ``SplitEnd`` can be duplicated onto a compatible root node. By compatible, the
28
+ new root must contain data that compares as equal to the old root node.
21
29
 
22
- Like one of many "split ends" from shafts of hair, a ``SplitEnd`` can be "snipped"
23
- shorter or "extended" further from its "end" node at the top of the stack. Its "root"
24
- node is at the bottom of the stack and can not be "snipped" or "cut" off.
30
+ .. admonition:: Future directions
25
31
 
26
- A ``SplitEnd`` can be duplicated onto a compatible root node. By compatible, the
27
- new root must contain data that compares as equal to the old root node.
32
+ A ``scalp`` is a container of root nodes all of whose contained data must
33
+ be hashable. The ``scalp.add(d)`` method will return the unique root node with data
34
+ that compares as equal to ``d``, or create a new root node if such a contained node
35
+ does not exist.
28
36
 
29
- TODO: A ``scalp`` is a container of root nodes all of whose contained data must be
30
- hashable. The ``scalp.add(d)`` method will return the unique root node with data
31
- that compares as equal to ``d``, or create a new root node if such a contained node
32
- does not exist.
33
37
  """
34
38
 
35
39
  __author__ = 'Geoffrey R. Scheller'
36
- __copyright__ = 'Copyright (c) 2023-2025 Geoffrey R. Scheller'
40
+ __copyright__ = 'Copyright (c) 2023-2026 Geoffrey R. Scheller'
37
41
  __license__ = 'Apache License 2.0'
@@ -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.
@@ -14,27 +14,33 @@
14
14
 
15
15
  """
16
16
  Class SplitEnds
17
- ===============
17
+ ---------------
18
18
 
19
- **LIFO stacks safely sharing immutable data.**
19
+ .. admonition:: LIFO stacks safely sharing immutable data.
20
20
 
21
- - each ``SplitEnd`` is a very simple stateful (mutable) LIFO stack
22
- - data can be either "extended" to or "snipped" off the "end"
23
- - the "root" of a ``SplitEnd``
24
- - it is fixed and cannot be removed from the ``SplitEnd``
25
- - different mutable split ends can safely share the same "tail"
26
- - each ``SplitEnd`` sees itself as a singularly linked list
27
- - bush-like datastructures can be formed using multiple ``SplitEnds``
28
- - the ``SplitEnd.split`` and ``len`` methods are O(1)
29
- - in boolean context returns true if the ``SplitEnd`` is not just its "root"
21
+ - each ``SplitEnd`` is a very simple stateful (mutable) LIFO stack
22
+ - data can be either "extended" to or "snipped" off the "end"
23
+ - "root" of a ``SplitEnd`` is embedded in a ``scalp``
24
+
25
+ - the root data is immutable
26
+ - it cannot be split off
27
+
28
+ - different mutable split ends can safely share the same "tail"
29
+ - each ``SplitEnd`` sees itself as a singularly linked list
30
+ - bush-like datastructures can be formed using multiple ``SplitEnds``
31
+ - the ``SplitEnd.split`` and ``len`` methods are O(1)
32
+ - in a boolean context
33
+
34
+ - falsy just a "root"
35
+ - truthy otherwise
30
36
 
31
37
  """
32
38
 
33
39
  from collections.abc import Callable, Iterator
34
- from pythonic_fp.iterables.folding import reduce_left, fold_left
35
40
  from typing import cast, Final, overload
36
- from pythonic_fp.queues.lifo import LIFOQueue
37
41
  from pythonic_fp.gadgets.sentinels.flavored import Sentinel
42
+ from pythonic_fp.iterables.folding import reduce_left, fold_left
43
+ from pythonic_fp.queues.lifo import LIFOQueue
38
44
  from .splitend_node import SENode
39
45
 
40
46
  __all__ = ['SplitEnd']
@@ -50,8 +56,11 @@ class SplitEnd[D]:
50
56
 
51
57
  def __init__(self, *ds: D, root: SENode[D] | _Sentinel = _sentinel) -> None:
52
58
  """
53
- :param root_data: Irremovable initial data at bottom of stack.
54
- :param data: Removable data to be pushed onto splitend stack.
59
+ .. admonition:: init
60
+
61
+ :param root_data: Irremovable initial data at bottom of stack.
62
+ :param ds: Removable data to be pushed onto splitend stack.
63
+
55
64
  """
56
65
  if root is _sentinel:
57
66
  if ds:
@@ -75,27 +84,57 @@ class SplitEnd[D]:
75
84
  self._end, self._root, self._count = end, root_node, count
76
85
 
77
86
  def __iter__(self) -> Iterator[D]:
87
+ """
88
+ .. admonition:: iter
89
+
90
+ Iterate from end to root.
91
+
92
+ :yields: data from end to root
93
+
94
+ """
78
95
  return iter(self._end)
79
96
 
80
97
  def __reversed__(self) -> Iterator[D]:
98
+ """
99
+ .. admonition:: reverse iter
100
+
101
+ Iterate from end to root.
102
+
103
+ :yields: data from end to root
104
+
105
+ """
81
106
  return reversed(list(self))
82
107
 
83
108
  def __bool__(self) -> bool:
84
109
  """
85
- :returns: ``True`` is ``SplitEnd`` is not just its root node.
110
+ .. admonition:: bool
111
+
112
+ :returns: ``True`` if ``SplitEnd`` is not just its root node.
113
+
86
114
  """
87
115
  return bool(self._end)
88
116
 
89
117
  def __len__(self) -> int:
90
- return self._count
118
+ """
119
+ .. admonition:: len
91
120
 
92
- def __repr__(self) -> str:
93
- return 'SplitEend(' + ', '.join(map(repr, reversed(self))) + ')'
121
+ :returns: The number of nodes on the ``Splitend``.
94
122
 
95
- def __str__(self) -> str:
96
- return '>< ' + ' -> '.join(map(str, self)) + ' ||'
123
+ """
124
+ return self._count
97
125
 
98
126
  def __eq__(self, other: object, /) -> bool:
127
+ """
128
+ .. admonition:: equality comparison
129
+
130
+ Efficiently compare two ``SplitEnds``.
131
+
132
+ :returns: ``True`` only if ``other`` is also a ``Splitend``
133
+ whose corresponding data to ``self`` compares as
134
+ equal and both share the same root node.
135
+ Otherwise ``False``.
136
+
137
+ """
99
138
  if not isinstance(other, type(self)):
100
139
  return False
101
140
 
@@ -116,11 +155,55 @@ class SplitEnd[D]:
116
155
  right = right.prev()
117
156
  return True
118
157
 
158
+ def __repr__(self) -> str:
159
+ """
160
+ .. admonition:: repr string
161
+
162
+ Construct string to reproduce the ``SplitEnd``.
163
+ TODO: Fix, does not include root node.
164
+
165
+ :returns: String to reproduce the ``SplitEnd``.
166
+
167
+ """
168
+ return 'SplitEend(' + ', '.join(map(repr, reversed(self))) + ')'
169
+
170
+ def __str__(self) -> str:
171
+ """
172
+ .. admonition:: user string
173
+
174
+ Construct string meaningful to an end user.
175
+ Does not give root node info.
176
+
177
+ :returns: String to reproduce the ``SplitEnd``.
178
+
179
+ """
180
+ return '>< ' + ' -> '.join(map(str, self)) + ' ||'
181
+
182
+ def snip(self) -> D:
183
+ """
184
+ .. admonition:: cut just tip
185
+
186
+ :returns: Data from snipped tip,
187
+ just return root data if at root.
188
+
189
+ """
190
+ if self._count > 1:
191
+ data, self._end, self._count = self._end.both() + (self._count - 1,)
192
+ else:
193
+ data = self._end.data()
194
+
195
+ return data
196
+
119
197
  def cut(self, num: int | None = None) -> tuple[D, ...]:
120
- """Cut data off end of ``SplitEnd``.
198
+ """
199
+ .. admonition:: Cut data off end of SplitEnd
200
+
201
+ Pop "cut" data off Split, just copy root data.
202
+
203
+ :param num: Optional number of nodes to cut,
204
+ default is entire stack.
205
+ :returns: Tuple of data cut off from end towards root.
121
206
 
122
- :param num: Optional number of nodes to cut, default is entire stack.
123
- :returns: Tuple of data cut off from end.
124
207
  """
125
208
  if num is None or num > self._count:
126
209
  num = self._count
@@ -142,42 +225,63 @@ class SplitEnd[D]:
142
225
  return data
143
226
 
144
227
  def extend(self, *ds: D) -> None:
145
- """Add data onto the tip of the SplitEnd. Like adding a hair
146
- extension.
228
+ """
229
+ .. admonition:: extend SplitEnd with data
230
+
231
+ Add data onto the tip of the SplitEnd. Like adding
232
+ a hair extension.
233
+
234
+ :param ds: data to extend the splitend
147
235
 
148
- :param ds: data to extend the splitend
149
236
  """
150
237
  for d in ds:
151
238
  node = SENode(d, self._end)
152
239
  self._end, self._count = node, self._count + 1
153
240
 
154
241
  def peak(self) -> D:
155
- """Return the data at end (top) of SplitEnd without consuming it.
242
+ """
243
+ .. admonition:: peak at end
244
+
245
+ Return the data at end (top) of the SplitEnd
246
+ without consuming it.
247
+
248
+ :returns: The data at the end (tip) of the SplitEnd.
156
249
 
157
- :returns: The data at the end of the SplitEnd.
158
250
  """
159
251
  return self._end.data()
160
252
 
161
253
  def root(self) -> SENode[D]:
162
254
  """
163
- :returns: The root SENode node of the SplitEnd.
255
+ .. admonition:: get root
256
+
257
+ :returns: The root SENode node of the SplitEnd.
258
+
164
259
  """
165
260
  return self._root
166
261
 
167
262
  def reroot(self, root: SENode[D]) -> 'SplitEnd[D]':
168
- """Create a brand new SplitEnd with the same data but different root.
263
+ """
264
+ .. admonition:: re-root SplitEnd
265
+
266
+ Create a brand new SplitEnd with the same data but different root.
267
+
268
+ :returns: New SplitEnd with the same data
269
+ and the new ``root``.
270
+ :raises ValueError: If new and original root nodes
271
+ are not compatible.
272
+
273
+ .. note::
169
274
 
170
- .. note::
275
+ Two nodes are compatible root nodes if and only if
171
276
 
172
- Two nodes are compatible root nodes if and only if
277
+ - they are both actually root nodes
173
278
 
174
- - they are both actually root nodes
175
- - that is their previous nodes are themselves
176
- - their data compare as equal
177
- - comparing by identity is too strong for some use cases
279
+ - which implies that their previous nodes are themselves
280
+
281
+ - their data compare as equal
282
+
283
+ - comparing by identity is too strong
178
284
 
179
- :returns: New SplitEnd with the same data and the new ``root``.
180
- :raises ValueError: If new and original root nodes are not compatible.
181
285
  """
182
286
  if not root:
183
287
  msg = 'New root node is not a root node.'
@@ -193,22 +297,15 @@ class SplitEnd[D]:
193
297
 
194
298
  return SplitEnd(*lifo, root = root)
195
299
 
196
- def snip(self) -> D:
197
- """Snip data off tip of SplitEnd. Just return data if tip is root.
198
-
199
- :returns: Data snipped off tip, just return root data if at root.
300
+ def split(self, *ds: D) -> 'SplitEnd[D]':
200
301
  """
201
- if self._count > 1:
202
- data, self._end, self._count = self._end.both() + (self._count - 1,)
203
- else:
204
- data = self._end.data()
302
+ .. admonition:: split
205
303
 
206
- return data
304
+ Split the end and add more data.
207
305
 
208
- def split(self, *ds: D) -> 'SplitEnd[D]':
209
- """Split the end and add more data.
306
+ :returns: New instance, same data nodes plus
307
+ additional ones on end. Same root node.
210
308
 
211
- :returns: New instance, same data nodes plus additional ones on end.
212
309
  """
213
310
  se: SplitEnd[D] = SplitEnd(self._root.data())
214
311
  se._count, se._end, se._root = self._count, self._end, self._root
@@ -221,11 +318,17 @@ class SplitEnd[D]:
221
318
  def fold[T](self, f: Callable[[T, D], T], init: T) -> T: ...
222
319
 
223
320
  def fold[T](self, f: Callable[[T, D], T], init: T | None = None) -> T:
224
- """Reduce with a function, folding from tip to root.
321
+ """
322
+ .. admonition:: fold
323
+
324
+ Reduce with a function, folding from tip to root.
325
+
326
+ :param f: Folding function, first argument
327
+ is for the accumulator.
328
+ :param init: Optional initial starting value for the fold.
329
+ :returns: Reduced value folding from tip to root
330
+ in natural LIFO order.
225
331
 
226
- :param f: Folding function, first argument is for the accumulator.
227
- :param init: Optional initial starting value for the fold.
228
- :returns: Reduced value folding from tip to root in natural LIFO order.
229
332
  """
230
333
  if init is None:
231
334
  return self._end.fold(f) # type: ignore
@@ -237,11 +340,16 @@ class SplitEnd[D]:
237
340
  def rev_fold[T](self, f: Callable[[T, D], T], init: T) -> T: ...
238
341
 
239
342
  def rev_fold[T](self, f: Callable[[T, D], T], init: T | None = None) -> T:
240
- """Reduce with a function, fold from root to tip.
343
+ """
344
+ .. admonition:: reverse fold
345
+
346
+ Reduce with a function, fold from root to tip.
347
+
348
+ :param f: Folding function, first argument
349
+ is for the accumulator.
350
+ :param init: Optional initial starting value for the fold.
351
+ :returns: Reduced value folding from root to tip.
241
352
 
242
- :param f: Folding function, first argument is for the accumulator.
243
- :param init: Optional initial starting value for the fold.
244
- :returns: Reduced value folding from root to tip.
245
353
  """
246
354
  if init is None:
247
355
  return cast(T, reduce_left(reversed(self), cast(Callable[[D, D], D], f)))
@@ -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.
@@ -13,21 +13,25 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """
16
- Class SENode
17
- ============
18
-
19
- **Used to make inwardly directed bush-like graphs.**
20
-
21
- - designed so multiple splitends can safely share the same data
22
- - nodes always contain data
23
- - data node ``SENode[D]`` make up end-to-root singularly linked lists
24
- - two nodes compare as equal if
25
- - both their previous Nodes are the same
26
- - their data compare as equal
27
- - a root node is a node whose previous node is itself
28
- - root nodes mark the bottom of splitend stacks
29
- - more than one node can point to the same proceeding node
30
- - forming bush like graphs
16
+ .. admonition:: SplitEnd node
17
+
18
+ Used to make inwardly directed bush-like graphs.
19
+
20
+ - designed so multiple splitends can safely share the same data
21
+ - nodes always contain data
22
+ - data node ``SENode[D]`` make up end-to-root singularly linked lists
23
+ - two nodes compare as equal if
24
+
25
+ - both their previous Nodes are the same
26
+ - their data compare as equal
27
+
28
+ - a root node is a node whose previous node is itself
29
+
30
+ - root nodes mark the bottom of splitend stacks
31
+
32
+ - more than one node can point to the same proceeding node
33
+
34
+ - forming bush like graphs
31
35
 
32
36
  """
33
37
 
@@ -46,8 +50,12 @@ class SENode[D]:
46
50
 
47
51
  def __init__(self, data: D, prev: Self | _Sentinel = _sentinel) -> None:
48
52
  """
49
- :param data: Nodes always contain data of type ``D``.
50
- :param prev: Link to previous node. Points to ``self`` if a root node.
53
+ .. admonition:: init
54
+
55
+ :param data: Nodes always contain data of type ``D``.
56
+ :param prev: Link to previous node, points to ``self``
57
+ if a root node.
58
+
51
59
  """
52
60
  self._data = data
53
61
  if prev is not _sentinel:
@@ -57,11 +65,20 @@ class SENode[D]:
57
65
 
58
66
  def __bool__(self) -> bool:
59
67
  """
60
- :returns: ``True`` if ``SENode`` is not a root node.
68
+ .. admonition:: bool
69
+
70
+ :returns: ``True`` only if ``SENode`` is not a root node.
71
+
61
72
  """
62
73
  return self._prev is not self
63
74
 
64
75
  def __iter__(self) -> Iterator[D]:
76
+ """
77
+ .. admonition:: iter
78
+
79
+ :yields: Node date until and including root node.
80
+
81
+ """
65
82
  node = self
66
83
  while node:
67
84
  yield node._data
@@ -70,8 +87,19 @@ class SENode[D]:
70
87
 
71
88
  def __eq__(self, other: object) -> bool:
72
89
  """
73
- Two ``SENodes`` nodes are equal if their previous nodes are the
74
- same object and their data compare as equal.
90
+ .. admonition:: equality comparison
91
+
92
+ Two ``SENodes`` nodes are equal if their previous nodes
93
+ are the same object and their data compare as equal.
94
+
95
+ :param other:
96
+ :returns: ``True`` if ``other`` is a SplitEnd which compares
97
+ as equal to ``self`` as described above.
98
+
99
+ .. note::
100
+
101
+ Will be useful when consolidating SplitEnds.
102
+
75
103
  """
76
104
  if not isinstance(other, type(self)):
77
105
  return False
@@ -82,32 +110,44 @@ class SENode[D]:
82
110
  return True
83
111
  return False
84
112
 
85
- def both(self) -> tuple[D, Self]:
86
- """Peak at data and previous node, if a root then data and self.
87
-
88
- :returns: tuple of type tuple[D, SENode[D]]
113
+ def data(self) -> D:
89
114
  """
90
- return self._data, self._prev
115
+ .. admonition:: peak at data in SENode
91
116
 
92
- def data(self) -> D:
93
- """Peak at data.
117
+ :returns: The data stored in the ``SENode``.
94
118
 
95
- :returns: The data stored in the ``SENode``.
96
119
  """
97
120
  return self._data
98
121
 
99
122
  def prev(self) -> Self:
100
- """Peak at previous node.
123
+ """
124
+ .. admonition:: peak at previous node
125
+
126
+ :returns: The previous node stored in the ``SENode``.
101
127
 
102
- :returns: The previous node stored in the ``SENode``.
103
128
  """
104
129
  return self._prev
105
130
 
131
+ def both(self) -> tuple[D, Self]:
132
+ """
133
+ .. admonition:: both data and previous node
134
+
135
+ Peak at data and previous node,
136
+ if a root then data and ``self``.
137
+
138
+ :returns: Tuple of type ``tuple[D, SENode[D]]``
139
+
140
+ """
141
+ return self._data, self._prev
142
+
106
143
  def push(self, data: D) -> Self:
107
- """Create a new ``SENode[D]``.
144
+ """
145
+ .. admonition:: push date to create new ``SENode[D]``
146
+
147
+ :param data: Data for new node to contain.
148
+ :returns: New ``SENode`` whose previous node is
149
+ the current node.
108
150
 
109
- :param data: Data for new node to contain.
110
- :returns: New ``SENode`` whose previous node is the current node.
111
151
  """
112
152
  return cast(Self, SENode(data, self))
113
153
 
@@ -117,11 +157,17 @@ class SENode[D]:
117
157
  def fold[T](self, f: Callable[[T, D], T], init: T) -> T: ...
118
158
 
119
159
  def fold[T](self, f: Callable[[T, D], T], init: T | _Sentinel = _sentinel) -> T:
120
- """Fold data across linked nodes with a function..
160
+ """
161
+ .. admonition:: fold
162
+
163
+ Fold data across linked nodes with a function.
164
+
165
+ :param f: Folding function, first argument
166
+ is for accumulated value.`
167
+ :param init: Optional initial starting value for the fold.
168
+ :returns: Reduced value folded from end to root
169
+ in natural LIFO order.
121
170
 
122
- :param f: Folding function, first argument is for accumulated value.`
123
- :param init: Optional initial starting value for the fold.
124
- :returns: Reduced value folded from end to root in natural LIFO order.
125
171
  """
126
172
  if init is not _sentinel:
127
173
  acc = cast(T, init)
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-splitends
3
- Version: 2.0.0
4
- Summary: Mutable stack objects that can safely share data.
3
+ Version: 2.0.3
4
+ Summary: .. admonition:: Mutable stack objects that can safely share data
5
5
  Keywords: SplitEnd,lifo,stack
6
6
  Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
7
7
  Requires-Python: >=3.13
@@ -11,16 +11,16 @@ 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-fptools>=5.1.2
18
- Requires-Dist: pythonic-fp-iterables>=5.1.2
19
- Requires-Dist: pythonic-fp-queues>=5.1.0
17
+ Requires-Dist: pythonic-fp-fptools>=5.2.0
18
+ Requires-Dist: pythonic-fp-iterables>=5.1.3
19
+ Requires-Dist: pythonic-fp-queues>=5.1.1
20
20
  Requires-Dist: pytest>=8.4.1 ; extra == "test"
21
21
  Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-splitends/blob/main/CHANGELOG.rst
22
- Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/splitends/development/build/html/
23
- Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/homepage/build/html/
22
+ Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/projects/splitends.html
23
+ Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/
24
24
  Project-URL: Source, https://github.com/grscheller/pythonic-fp-splitends
25
25
  Provides-Extra: test
26
26
 
@@ -28,7 +28,8 @@ Pythonic FP - SplitEnds
28
28
  =======================
29
29
 
30
30
  PyPI project
31
- `pythonic-fp.splitends <https://pypi.org/project/pythonic-fp.splitends/>`_.
31
+ `pythonic-fp.splitends
32
+ <https://pypi.org/project/pythonic-fp-splitends/>`_.
32
33
 
33
34
  Python package Implementing a singularly linked LIFO queue called
34
35
  a ``SplitEnd``. These data structures can safely share data nodes
@@ -45,19 +46,23 @@ between themselves.
45
46
 
46
47
  Part of the
47
48
  `pythonic-fp
48
- <https://grscheller.github.io/pythonic-fp/homepage/build/html/index.html>`_
49
+ <https://grscheller.github.io/pythonic-fp/>`_
49
50
  PyPI projects.
50
51
 
51
52
  Documentation
52
53
  -------------
53
54
 
55
+ Documentation and other links for this project are hosted on
56
+ `GitHub Pages
57
+ <https://grscheller.github.io/pythonic-fp/projects/splitends.html>`_.
58
+
54
59
  Documentation for this project is hosted on
55
60
  `GitHub Pages
56
- <https://grscheller.github.io/pythonic-fp/splitends/development/build/html>`_.
61
+ <https://grscheller.github.io/pythonic-fp-splitends/development/html/>`_.
57
62
 
58
63
  Copyright and License
59
64
  ---------------------
60
65
 
61
- Copyright (c) 2023-2025 Geoffrey R. Scheller. Licensed under the Apache
66
+ Copyright (c) 2023-2026 Geoffrey R. Scheller. Licensed under the Apache
62
67
  License, Version 2.0. See the LICENSE file for details.
63
68
 
@@ -0,0 +1,11 @@
1
+ pythonic_fp/splitends/__init__.py,sha256=4em0AExIcd7slGzjUD5iUDiYVSHyrgQdqce0UosgBno,1893
2
+ pythonic_fp/splitends/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ pythonic_fp/splitends/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ pythonic_fp/splitends/splitend.py,sha256=RFBsJcEh-NGRAtOizbYShNznseutIRoeOJbCeEJBxCM,10334
5
+ pythonic_fp/splitends/splitend.pyi,sha256=OdTRATFXX5smbpwc8wm3gt4yyeTd_kN8VbMeNYl2Cho,1193
6
+ pythonic_fp/splitends/splitend_node.py,sha256=E8MIZEDg6ZRY_0JfQnZyTD2Xek2JAg_epEu8sCzLadY,5139
7
+ pythonic_fp/splitends/splitend_node.pyi,sha256=TozeGg4lmjMf0UPfZRTxRJR2kRpq0053VjbjIBUeosk,705
8
+ pythonic_fp_splitends-2.0.3.dist-info/licenses/LICENSE,sha256=IJMkVWQUVy-SonK6SMaMotDQ6Zb-lVi2bUTiGp1GUO8,10774
9
+ pythonic_fp_splitends-2.0.3.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
10
+ pythonic_fp_splitends-2.0.3.dist-info/METADATA,sha256=PzPaGNd0cHqu3Ey8QRlUlC__RhQL3LRDLxT6mlKgzH8,2531
11
+ pythonic_fp_splitends-2.0.3.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- pythonic_fp/splitends/__init__.py,sha256=mydkUVuGD_Ns3G4LYgOQvPfTxMCkCkFwC3oZFDHnRmM,1775
2
- pythonic_fp/splitends/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- pythonic_fp/splitends/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- pythonic_fp/splitends/splitend.py,sha256=XQ4-1x8lW5i480YHjBcwAhh4ddxtPF7KsIrMnbaM8Ks,8242
5
- pythonic_fp/splitends/splitend.pyi,sha256=OdTRATFXX5smbpwc8wm3gt4yyeTd_kN8VbMeNYl2Cho,1193
6
- pythonic_fp/splitends/splitend_node.py,sha256=rNjGU8VqhOo6AFa-R6zcOrrAtfIpzkzI9ulsa8iRg2w,4252
7
- pythonic_fp/splitends/splitend_node.pyi,sha256=TozeGg4lmjMf0UPfZRTxRJR2kRpq0053VjbjIBUeosk,705
8
- pythonic_fp_splitends-2.0.0.dist-info/licenses/LICENSE,sha256=IJMkVWQUVy-SonK6SMaMotDQ6Zb-lVi2bUTiGp1GUO8,10774
9
- pythonic_fp_splitends-2.0.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
10
- pythonic_fp_splitends-2.0.0.dist-info/METADATA,sha256=LMjr3oM6p1DbZhL9f6mAvd8gDDa5klTdA8IiJiFdn_w,2435
11
- pythonic_fp_splitends-2.0.0.dist-info/RECORD,,