pythonic-fp.splitends 2.0.0__py3-none-any.whl → 2.0.2__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.
@@ -26,12 +26,13 @@ node is at the bottom of the stack and can not be "snipped" or "cut" off.
26
26
  A ``SplitEnd`` can be duplicated onto a compatible root node. By compatible, the
27
27
  new root must contain data that compares as equal to the old root node.
28
28
 
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
29
+ **TODO:** A ``scalp`` is a container of root nodes all of whose contained data must
30
+ be hashable. The ``scalp.add(d)`` method will return the unique root node with data
31
31
  that compares as equal to ``d``, or create a new root node if such a contained node
32
32
  does not exist.
33
+
33
34
  """
34
35
 
35
36
  __author__ = 'Geoffrey R. Scheller'
36
- __copyright__ = 'Copyright (c) 2023-2025 Geoffrey R. Scheller'
37
+ __copyright__ = 'Copyright (c) 2023-2026 Geoffrey R. Scheller'
37
38
  __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,29 @@
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
+ - the "root" of a ``SplitEnd``
24
+
25
+ - it is fixed and cannot be removed from the ``SplitEnd``
26
+
27
+ - different mutable split ends can safely share the same "tail"
28
+ - each ``SplitEnd`` sees itself as a singularly linked list
29
+ - bush-like datastructures can be formed using multiple ``SplitEnds``
30
+ - the ``SplitEnd.split`` and ``len`` methods are O(1)
31
+ - in boolean context returns true if the ``SplitEnd`` is not just its "root"
30
32
 
31
33
  """
32
34
 
33
35
  from collections.abc import Callable, Iterator
34
- from pythonic_fp.iterables.folding import reduce_left, fold_left
35
36
  from typing import cast, Final, overload
36
- from pythonic_fp.queues.lifo import LIFOQueue
37
37
  from pythonic_fp.gadgets.sentinels.flavored import Sentinel
38
+ from pythonic_fp.iterables.folding import reduce_left, fold_left
39
+ from pythonic_fp.queues.lifo import LIFOQueue
38
40
  from .splitend_node import SENode
39
41
 
40
42
  __all__ = ['SplitEnd']
@@ -52,6 +54,7 @@ class SplitEnd[D]:
52
54
  """
53
55
  :param root_data: Irremovable initial data at bottom of stack.
54
56
  :param data: Removable data to be pushed onto splitend stack.
57
+
55
58
  """
56
59
  if root is _sentinel:
57
60
  if ds:
@@ -83,6 +86,7 @@ class SplitEnd[D]:
83
86
  def __bool__(self) -> bool:
84
87
  """
85
88
  :returns: ``True`` is ``SplitEnd`` is not just its root node.
89
+
86
90
  """
87
91
  return bool(self._end)
88
92
 
@@ -121,6 +125,7 @@ class SplitEnd[D]:
121
125
 
122
126
  :param num: Optional number of nodes to cut, default is entire stack.
123
127
  :returns: Tuple of data cut off from end.
128
+
124
129
  """
125
130
  if num is None or num > self._count:
126
131
  num = self._count
@@ -146,6 +151,7 @@ class SplitEnd[D]:
146
151
  extension.
147
152
 
148
153
  :param ds: data to extend the splitend
154
+
149
155
  """
150
156
  for d in ds:
151
157
  node = SENode(d, self._end)
@@ -155,12 +161,14 @@ class SplitEnd[D]:
155
161
  """Return the data at end (top) of SplitEnd without consuming it.
156
162
 
157
163
  :returns: The data at the end of the SplitEnd.
164
+
158
165
  """
159
166
  return self._end.data()
160
167
 
161
168
  def root(self) -> SENode[D]:
162
169
  """
163
170
  :returns: The root SENode node of the SplitEnd.
171
+
164
172
  """
165
173
  return self._root
166
174
 
@@ -172,12 +180,16 @@ class SplitEnd[D]:
172
180
  Two nodes are compatible root nodes if and only if
173
181
 
174
182
  - they are both actually root nodes
175
- - that is their previous nodes are themselves
183
+
184
+ - which implies that their previous nodes are themselves
185
+
176
186
  - their data compare as equal
187
+
177
188
  - comparing by identity is too strong for some use cases
178
189
 
179
190
  :returns: New SplitEnd with the same data and the new ``root``.
180
191
  :raises ValueError: If new and original root nodes are not compatible.
192
+
181
193
  """
182
194
  if not root:
183
195
  msg = 'New root node is not a root node.'
@@ -197,6 +209,7 @@ class SplitEnd[D]:
197
209
  """Snip data off tip of SplitEnd. Just return data if tip is root.
198
210
 
199
211
  :returns: Data snipped off tip, just return root data if at root.
212
+
200
213
  """
201
214
  if self._count > 1:
202
215
  data, self._end, self._count = self._end.both() + (self._count - 1,)
@@ -209,6 +222,7 @@ class SplitEnd[D]:
209
222
  """Split the end and add more data.
210
223
 
211
224
  :returns: New instance, same data nodes plus additional ones on end.
225
+
212
226
  """
213
227
  se: SplitEnd[D] = SplitEnd(self._root.data())
214
228
  se._count, se._end, se._root = self._count, self._end, self._root
@@ -226,6 +240,7 @@ class SplitEnd[D]:
226
240
  :param f: Folding function, first argument is for the accumulator.
227
241
  :param init: Optional initial starting value for the fold.
228
242
  :returns: Reduced value folding from tip to root in natural LIFO order.
243
+
229
244
  """
230
245
  if init is None:
231
246
  return self._end.fold(f) # type: ignore
@@ -242,6 +257,7 @@ class SplitEnd[D]:
242
257
  :param f: Folding function, first argument is for the accumulator.
243
258
  :param init: Optional initial starting value for the fold.
244
259
  :returns: Reduced value folding from root to tip.
260
+
245
261
  """
246
262
  if init is None:
247
263
  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.
@@ -14,20 +14,25 @@
14
14
 
15
15
  """
16
16
  Class SENode
17
- ============
17
+ ------------
18
18
 
19
- **Used to make inwardly directed bush-like graphs.**
19
+ .. admonition:: Used to make inwardly directed bush-like graphs
20
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
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
+
26
+ - both their previous Nodes are the same
27
+ - their data compare as equal
28
+
29
+ - a root node is a node whose previous node is itself
30
+
31
+ - root nodes mark the bottom of splitend stacks
32
+
33
+ - more than one node can point to the same proceeding node
34
+
35
+ - forming bush like graphs
31
36
 
32
37
  """
33
38
 
@@ -72,6 +77,7 @@ class SENode[D]:
72
77
  """
73
78
  Two ``SENodes`` nodes are equal if their previous nodes are the
74
79
  same object and their data compare as equal.
80
+
75
81
  """
76
82
  if not isinstance(other, type(self)):
77
83
  return False
@@ -86,6 +92,7 @@ class SENode[D]:
86
92
  """Peak at data and previous node, if a root then data and self.
87
93
 
88
94
  :returns: tuple of type tuple[D, SENode[D]]
95
+
89
96
  """
90
97
  return self._data, self._prev
91
98
 
@@ -93,6 +100,7 @@ class SENode[D]:
93
100
  """Peak at data.
94
101
 
95
102
  :returns: The data stored in the ``SENode``.
103
+
96
104
  """
97
105
  return self._data
98
106
 
@@ -100,6 +108,7 @@ class SENode[D]:
100
108
  """Peak at previous node.
101
109
 
102
110
  :returns: The previous node stored in the ``SENode``.
111
+
103
112
  """
104
113
  return self._prev
105
114
 
@@ -108,6 +117,7 @@ class SENode[D]:
108
117
 
109
118
  :param data: Data for new node to contain.
110
119
  :returns: New ``SENode`` whose previous node is the current node.
120
+
111
121
  """
112
122
  return cast(Self, SENode(data, self))
113
123
 
@@ -122,6 +132,7 @@ class SENode[D]:
122
132
  :param f: Folding function, first argument is for accumulated value.`
123
133
  :param init: Optional initial starting value for the fold.
124
134
  :returns: Reduced value folded from end to root in natural LIFO order.
135
+
125
136
  """
126
137
  if init is not _sentinel:
127
138
  acc = cast(T, init)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-splitends
3
- Version: 2.0.0
3
+ Version: 2.0.2
4
4
  Summary: Mutable stack objects that can safely share data.
5
5
  Keywords: SplitEnd,lifo,stack
6
6
  Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
@@ -14,9 +14,9 @@ Classifier: Operating System :: OS Independent
14
14
  Classifier: Programming Language :: Python :: 3.13
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
22
  Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/splitends/development/build/html/
@@ -45,7 +45,7 @@ between themselves.
45
45
 
46
46
  Part of the
47
47
  `pythonic-fp
48
- <https://grscheller.github.io/pythonic-fp/homepage/build/html/index.html>`_
48
+ <https://grscheller.github.io/pythonic-fp>`_
49
49
  PyPI projects.
50
50
 
51
51
  Documentation
@@ -53,7 +53,7 @@ Documentation
53
53
 
54
54
  Documentation for this project is hosted on
55
55
  `GitHub Pages
56
- <https://grscheller.github.io/pythonic-fp/splitends/development/build/html>`_.
56
+ <https://grscheller.github.io/pythonic-fp/splitends>`_.
57
57
 
58
58
  Copyright and License
59
59
  ---------------------
@@ -0,0 +1,11 @@
1
+ pythonic_fp/splitends/__init__.py,sha256=T3FgFehJkrlKx2OKHJJETDcEJ_2nKfyl96wTb4Nw6Fw,1780
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=TkLQ5o4-SCnnC_HTpda6cSotaxyQ6aNbc8DB81qNqSI,8317
5
+ pythonic_fp/splitends/splitend.pyi,sha256=OdTRATFXX5smbpwc8wm3gt4yyeTd_kN8VbMeNYl2Cho,1193
6
+ pythonic_fp/splitends/splitend_node.py,sha256=0Qz_oIvwbvtlYZOD-tZ0lD4PxMRysFPkBNPTBkGdkQk,4306
7
+ pythonic_fp/splitends/splitend_node.pyi,sha256=TozeGg4lmjMf0UPfZRTxRJR2kRpq0053VjbjIBUeosk,705
8
+ pythonic_fp_splitends-2.0.2.dist-info/licenses/LICENSE,sha256=IJMkVWQUVy-SonK6SMaMotDQ6Zb-lVi2bUTiGp1GUO8,10774
9
+ pythonic_fp_splitends-2.0.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
10
+ pythonic_fp_splitends-2.0.2.dist-info/METADATA,sha256=l9gYIuYaAd9pIQwLAe_6AHnSjowRzx6JKsV4uxtI6dQ,2381
11
+ pythonic_fp_splitends-2.0.2.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,,