pythonic-fp-gadgets 4.0.0__py3-none-any.whl → 4.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.
@@ -13,44 +13,28 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """
16
- **Module level function names.**
16
+ Gadgets
17
+ -------
17
18
 
18
- ========================== ================================================
19
- Function Description
20
- ========================== ================================================
21
- ``first_common_ancestor`` Find least common base class in a type hierarchy
22
- ``iterate_over_arguments`` Return an iterator over the function's arguments
23
- ========================== ================================================
19
+ .. admonition:: Collection of mostly self-contained functions and classes
20
+
21
+ - Functions and classes which could go multiple places or have
22
+ no good place to go.
23
+ - Self-contained with minimal dependencies.
24
+ - No pythonic_fp dependencies.
24
25
 
25
26
  """
26
27
 
27
28
  from collections.abc import Iterator
28
29
  from inspect import getmro
29
30
 
30
- __all__ = ['iterate_over_arguments', 'first_common_ancestor']
31
+ __all__ = ['first_common_ancestor', 'iterate_over_arguments']
31
32
 
32
33
  __author__ = 'Geoffrey R. Scheller'
33
34
  __copyright__ = 'Copyright (c) 2023-2025 Geoffrey R. Scheller'
34
35
  __license__ = 'Apache License 2.0'
35
36
 
36
37
 
37
- def iterate_over_arguments[A](*args: A) -> Iterator[A]:
38
- """Function returning an iterator of its arguments.
39
-
40
- .. note::
41
-
42
- Does not create an object to iterate over.
43
-
44
- - well, not in the Python world
45
- - maybe in the C world
46
-
47
- :param args: Objects to iterate over.
48
- :returns: An iterator of the arguments.
49
-
50
- """
51
- yield from args
52
-
53
-
54
38
  def first_common_ancestor(cls1: type, cls2: type) -> type:
55
39
  """Find the least upper bound in the inheritance graph
56
40
  of two classes.
@@ -69,7 +53,8 @@ def first_common_ancestor(cls1: type, cls2: type) -> type:
69
53
  :param cls1: A class in the inheritance hierarchy.
70
54
  :param cls2: A class in the inheritance hierarchy.
71
55
  :returns: First common ancestor based on getmro order.
72
- :raises TypeError: Raised by ``inspect.getmro``.
56
+ :raises TypeError: Raised when no common ancestor or not
57
+ caught when raised by ``inspect.getmro``.
73
58
 
74
59
  """
75
60
  if issubclass(cls1, cls2):
@@ -81,3 +66,20 @@ def first_common_ancestor(cls1: type, cls2: type) -> type:
81
66
  if issubclass(cls1, common_ancestor) and issubclass(cls2, common_ancestor):
82
67
  return common_ancestor
83
68
  raise TypeError("latest_common_ancestor: no common ancestor found!!!")
69
+
70
+
71
+ def iterate_over_arguments[A](*args: A) -> Iterator[A]:
72
+ """Function returning an iterator of its arguments.
73
+
74
+ .. note::
75
+
76
+ Does not create an object to iterate over.
77
+
78
+ - well, not in the Python world
79
+ - maybe in the C world
80
+
81
+ :param args: Objects to iterate over.
82
+ :returns: An iterator of the functions arguments.
83
+
84
+ """
85
+ yield from args
@@ -47,7 +47,8 @@ class Box[T]:
47
47
 
48
48
  def __init__(self, item: T | _Sentinel = _sentinel) -> None:
49
49
  """
50
- :param item: An "optional" initial contained ``item`` for the ``Box``.
50
+ :param item: An optional initial contained ``item``
51
+ for the ``Box``.
51
52
  """
52
53
  self._item = item
53
54
 
@@ -67,6 +68,14 @@ class Box[T]:
67
68
  return 1 if self else 0
68
69
 
69
70
  def __eq__(self, other: object) -> bool:
71
+ """
72
+ Efficiently compare to another object.
73
+
74
+ :param other: The object to be compared with,
75
+ :returns: ``True`` if ``other`` is of type Box and contains
76
+ an object which compares as equal to the object
77
+ contained in the ``Box``, otherwise ``False``.
78
+ """
70
79
  if not isinstance(other, type(self)):
71
80
  return False
72
81
 
@@ -82,11 +91,15 @@ class Box[T]:
82
91
  def get(self, alt: T) -> T: ...
83
92
 
84
93
  def get(self, alt: T | _Sentinel = _sentinel) -> T:
85
- """Return the contained item if it exists, otherwise an alternate item.
94
+ """Return the contained item, if it exists, otherwise
95
+ an alternate item, if given.
86
96
 
87
- :param alt: an "optional" item of type ``T`` to return if ``Box`` is empty
88
- :returns: contents of ``Box``, or an alternate item if given and ``Box`` empty
89
- :raises ValueError: when an ``alt`` item is not provided but needed
97
+ :param alt: An optional item of type ``T`` to return
98
+ if the ``Box`` is empty.
99
+ :returns: Contents of ``Box`` or an alternate item, if given,
100
+ when the ``Box`` is empty.
101
+ :raises ValueError: When the ``alt`` item is not provided
102
+ but needed.
90
103
 
91
104
  """
92
105
  if self._item is not _sentinel:
@@ -146,8 +159,8 @@ class Box[T]:
146
159
  """Map function ``f`` over contents. We need to return a new
147
160
  instance since the type of Box can change.
148
161
 
149
- :param f: mapping function
150
- :returns: a new instance
162
+ :param f: Mapping function.
163
+ :returns: A new instance.
151
164
 
152
165
  """
153
166
  if self._item is _sentinel:
@@ -157,8 +170,8 @@ class Box[T]:
157
170
  def bind[U](self, f: Callable[[T], 'Box[U]']) -> 'Box[U]':
158
171
  """Flatmap ``Box`` with function ``f``.
159
172
 
160
- :param f: binding function
161
- :returns: a new instance
173
+ :param f: Binding function.
174
+ :returns: A new instance.
162
175
 
163
176
  """
164
177
  if self._item is _sentinel:
@@ -13,7 +13,9 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """
16
- **Sentinel values labeled by different (hashable) flavors.**
16
+ .. admonition:: Sentinel values labeled by different (hashable) flavors.
17
+
18
+ When different flavors of the truth are needed.
17
19
 
18
20
  .. note::
19
21
 
@@ -13,9 +13,8 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """
16
- **Singleton class representing an actually, not potentially, missing value.**
17
-
18
- .. note:
16
+ .. admonition:: Singleton class representing an actually,
17
+ not potentially, missing value.
19
18
 
20
19
  ``NoValue()`` is a singleton object representing a missing value.
21
20
 
@@ -52,7 +51,7 @@
52
51
 
53
52
  Similarly for not equals.
54
53
 
55
- .. table:: ``x != y``
54
+ .. table:: ``x != y``:wq
56
55
 
57
56
  +-----------+-----------+--------+--------+
58
57
  | x∖y | NoValue() | 42 | 57 |
@@ -113,12 +112,12 @@ class NoValue():
113
112
 
114
113
  def __eq__(self, other: object) -> bool:
115
114
  """
116
- :returns: False
115
+ :returns: ``False``
117
116
  """
118
117
  return False
119
118
 
120
119
  def __ne__(self, other: object) -> bool:
121
120
  """
122
- :returns: False
121
+ :returns: ``False``
123
122
  """
124
123
  return False
@@ -42,6 +42,14 @@ class Wrap[T]():
42
42
  return 'Wrap(' + repr(self._item) + ')'
43
43
 
44
44
  def __eq__(self, other: object) -> bool:
45
+ """
46
+ Efficiently compare to another object.
47
+
48
+ :param other: The object to be compared with,
49
+ :returns: ``True`` if ``other`` is of type Wrap and wraps
50
+ an object which compares as equal to the wrapped
51
+ object, otherwise ``False``.
52
+ """
45
53
  if not isinstance(other, type(self)):
46
54
  return False
47
55
 
@@ -73,7 +81,11 @@ class HWrap[T: Hashable](Hashable):
73
81
 
74
82
  .. tip::
75
83
 
76
- ``Wrap`` objects can be used in Python match statements.
84
+ ``HWrap`` objects can be used in Python match statements.
85
+
86
+ .. tip::
87
+
88
+ ``HWrap`` objects are hashable..
77
89
 
78
90
  """
79
91
  __slots__ = ('_item', '_hash')
@@ -96,6 +108,14 @@ class HWrap[T: Hashable](Hashable):
96
108
  return 'Wrap(' + repr(self._item) + ')'
97
109
 
98
110
  def __eq__(self, other: object) -> bool:
111
+ """
112
+ Efficiently compare to another object.
113
+
114
+ :param other: The object to be compared with,
115
+ :returns: ``True`` if ``other`` is of type HWrap and wraps
116
+ an object which compares as equal to the wrapped
117
+ object, otherwise ``False``.
118
+ """
99
119
  if not isinstance(other, type(self)):
100
120
  return False
101
121
 
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-gadgets
3
- Version: 4.0.0
4
- Summary: **Module level function names.**
3
+ Version: 4.0.2
4
+ Summary: Gadgets
5
5
  Keywords: gadgets
6
6
  Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
7
7
  Requires-Python: >=3.13
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.13
15
15
  Classifier: Typing :: Typed
16
16
  License-File: LICENSE
17
17
  Requires-Dist: pytest>=8.4.1 ; extra == "test"
18
- Requires-Dist: pythonic-fp-circulararray>=6.0.0 ; extra == "test"
18
+ Requires-Dist: pythonic-fp-circulararray>=6.0.1 ; extra == "test"
19
19
  Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-gadgets/blob/main/CHANGELOG.rst
20
20
  Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/gadgets/development/build/html/
21
21
  Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/homepage/build/html/
@@ -33,9 +33,10 @@ Library of simple, but useful, classes and functions with no dependencies
33
33
  outside the Python Standard Library.
34
34
 
35
35
  - Gadgets
36
+
36
37
  - single item box
37
38
  - function returning iterator of its arguments
38
- - find the latest common ancestor of two classes
39
+ - function to find the latest common ancestor of two classes
39
40
 
40
41
  Part of the
41
42
  `pythonic-fp
@@ -1,17 +1,17 @@
1
- pythonic_fp/gadgets/__init__.py,sha256=PXZJRwsDkGrI2_B3nbwU4n3tzeSGONquV-_inWroxsg,2811
1
+ pythonic_fp/gadgets/__init__.py,sha256=iEm1j8DIchgQvH4Tom6IyMeYz8i3LSAXBBBtz_gPykE,2673
2
2
  pythonic_fp/gadgets/__init__.pyi,sha256=cAf10WX2ZHMs-Tf93mImmDdZw7lNEmwjorkiVF04s_E,224
3
- pythonic_fp/gadgets/box.py,sha256=aSR9V_PuAhjqQ8Vs7fj80zgirb8BWzkUFr1pWvSbBDc,4994
3
+ pythonic_fp/gadgets/box.py,sha256=cmHe2kZhEMNtH51xlpdyd68SV-bBXxC6gRH8N0W6TqE,5443
4
4
  pythonic_fp/gadgets/box.pyi,sha256=UkJBY8Xiv4oe70Q3bhJL1jGHwYmFWwkTIdxvf2zR3v4,837
5
5
  pythonic_fp/gadgets/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- pythonic_fp/gadgets/wrap.py,sha256=5FonuzJ6E3SeUoneUoUsjM6x9COZUnyzWQHPKN45cRo,3259
6
+ pythonic_fp/gadgets/wrap.py,sha256=x3mvawiRh9G3vMq3ub5Va6qBJgKcvkCKvWeR6pWrJBw,3929
7
7
  pythonic_fp/gadgets/wrap.pyi,sha256=TRbBph_517VNCKchwU-pdtPCn73c09gq8EchDFM7Uyo,868
8
8
  pythonic_fp/gadgets/sentinels/__init__.py,sha256=81T-HGQ9BgXj57PO_pduo8MpSQpRgZwT8LIXwODhHkI,724
9
9
  pythonic_fp/gadgets/sentinels/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- pythonic_fp/gadgets/sentinels/flavored.py,sha256=RMqDRmN_ImbRlf_Yaqj7jwnOc6YBeEdAfi8xGCyw1xs,2195
10
+ pythonic_fp/gadgets/sentinels/flavored.py,sha256=sXgjhBPHEulH9C3Yc09PwAPDscfRH2vKj5JldgS6Sak,2260
11
11
  pythonic_fp/gadgets/sentinels/flavored.pyi,sha256=K3YSyXLyylPII2ahRP0olhzLJruOeR73TFJDC6rCUwk,212
12
- pythonic_fp/gadgets/sentinels/novalue.py,sha256=RA5foyWFgSHCpaJPJ0N0Td7cldLEbwX_bzkTgs_ZW-o,3573
12
+ pythonic_fp/gadgets/sentinels/novalue.py,sha256=UbyQ4AVTdM2flLmF2WE0sh7_dErPQiTeM8U6GdWaHN4,3602
13
13
  pythonic_fp/gadgets/sentinels/novalue.pyi,sha256=zhZdePpWoQ3ZXOq7xQWGR0A4W_XzasdBQKcoywXZEZI,173
14
- pythonic_fp_gadgets-4.0.0.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
15
- pythonic_fp_gadgets-4.0.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
16
- pythonic_fp_gadgets-4.0.0.dist-info/METADATA,sha256=sbyH2GplSHaJ52be21JwZasacpNr5v2bG72MIvWQMVA,1827
17
- pythonic_fp_gadgets-4.0.0.dist-info/RECORD,,
14
+ pythonic_fp_gadgets-4.0.2.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
15
+ pythonic_fp_gadgets-4.0.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
16
+ pythonic_fp_gadgets-4.0.2.dist-info/METADATA,sha256=GsyqIcxiofODEI34GKxzySI-FBv-pkwxaEhnTfZzcOs,1815
17
+ pythonic_fp_gadgets-4.0.2.dist-info/RECORD,,