pythonic-fp-gadgets 4.0.3__py3-none-any.whl → 4.0.4__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.
@@ -14,14 +14,15 @@
14
14
 
15
15
  """
16
16
  Gadgets
17
- -------
17
+ =======
18
18
 
19
19
  .. admonition:: Collection of mostly self-contained functions and classes
20
20
 
21
21
  - Functions and classes which could go multiple places or have
22
22
  no good place to go.
23
23
  - Self-contained with minimal dependencies.
24
- - No pythonic_fp dependencies at all.
24
+
25
+ - No pythonic_fp dependencies at all.
25
26
 
26
27
  """
27
28
 
@@ -42,23 +43,22 @@ def first_common_ancestor(cls1: type, cls2: type) -> type:
42
43
  Find the least upper bound in the inheritance graph
43
44
  of two classes.
44
45
 
45
- .. warning::
46
-
47
- This function can fail with a TypeError. Some error messages
48
- seen are
46
+ :param cls1: A class in the inheritance hierarchy.
47
+ :param cls2: A class in the inheritance hierarchy.
48
+ :returns: First common ancestor based on ``getmro`` order.
49
+ :raises TypeError: Raised when no common ancestor exists, or when
50
+ not caught when raised by ``inspect.getmro``.
49
51
 
50
- - multiple bases have instance lay-out conflict
51
- - type 'bool' is not an acceptable base type
52
+ .. warning::
52
53
 
53
- This happens frequently when the function is given
54
- Python builtin types or in multiple inheritance situations.
54
+ This function can fail with a TypeError. Some error messages
55
+ seen are
55
56
 
56
- :param cls1: A class in the inheritance hierarchy.
57
- :param cls2: A class in the inheritance hierarchy.
58
- :returns: First common ancestor based on ``getmro`` order.
59
- :raises TypeError: Raised when no common ancestor exists, or when
60
- not caught when raised by ``inspect.getmro``.
57
+ - multiple bases have instance lay-out conflict
58
+ - type 'bool' is not an acceptable base type
61
59
 
60
+ This happens frequently when the function is given
61
+ Python builtin types or in multiple inheritance situations.
62
62
  """
63
63
  if issubclass(cls1, cls2):
64
64
  return cls2
@@ -77,12 +77,12 @@ def iterate_over_arguments[A](*args: A) -> Iterator[A]:
77
77
 
78
78
  Function returning an iterator over its arguments.
79
79
 
80
- .. note::
80
+ :param args: Objects to iterate over.
81
+ :returns: An iterator of the function's arguments.
81
82
 
82
- Does not create a Python object to iterate over.
83
+ .. note::
83
84
 
84
- :param args: Objects to iterate over.
85
- :returns: An iterator of the functions arguments.
85
+ Does not create a Python object to iterate over.
86
86
 
87
87
  """
88
88
  yield from args
@@ -1,6 +1,6 @@
1
1
  from collections.abc import Iterator
2
2
 
3
- __all__ = ['iterate_over_arguments', 'first_common_ancestor']
3
+ __all__ = ['first_common_ancestor', 'iterate_over_arguments']
4
4
 
5
- def iterate_over_arguments[A](*args: A) -> Iterator[A]: ...
6
5
  def first_common_ancestor(cls1: type, cls2: type) -> type: ...
6
+ def iterate_over_arguments[A](*args: A) -> Iterator[A]: ...
@@ -11,28 +11,12 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- """
15
- .. admonition:: Module box
16
-
17
- Containers holding at most one item of a given type.
18
-
19
- .. tip::
20
-
21
- Objects of the ``Box`` type
22
-
23
- - Are truthy if not empty.
24
- - Can be combined with other iterators before being filled.
25
- - Can be used like a promise.
26
- - Threadsafe
27
- - Can be used in Python match statements.
28
-
29
- """
30
-
31
- __all__ = ['Box']
32
14
 
33
15
  from collections.abc import Callable, Iterator
34
16
  from typing import cast, Final, overload
35
17
 
18
+ __all__ = ['Box']
19
+
36
20
  type _Sentinel = object
37
21
  _sentinel: Final[_Sentinel] = object()
38
22
 
@@ -43,6 +27,16 @@ class Box[T]:
43
27
 
44
28
  Container holding at most one item of a given type.
45
29
 
30
+ .. tip::
31
+
32
+ Objects of the ``Box`` type
33
+
34
+ - Are truthy if not empty.
35
+ - Can be combined with other iterators before being filled.
36
+ - Can be used like a promise.
37
+ - Can be used in Python match statements.
38
+ - Threadsafe
39
+
46
40
  """
47
41
  __slots__ = ('_item',)
48
42
  __match_args__ = ('_item',)
@@ -54,24 +48,44 @@ class Box[T]:
54
48
 
55
49
  def __init__(self, item: T | _Sentinel = _sentinel) -> None:
56
50
  """
51
+ .. admonition:: Initializer
52
+
53
+ Initialize ``Box`` with 0 or 1 items.
54
+
57
55
  :param item: An optional initial ``item`` for the ``Box``.
58
56
 
59
57
  """
60
58
  self._item = item
61
59
 
62
60
  def __bool__(self) -> bool:
61
+ """
62
+ .. admonition:: Bool
63
+
64
+ Truthy if not empty.
65
+
66
+ """
63
67
  return self._item is not _sentinel
64
68
 
65
69
  def __iter__(self) -> Iterator[T]:
66
- if self:
67
- yield cast(T, self._item)
70
+ """
71
+ .. admonition:: Iterability
68
72
 
69
- def __repr__(self) -> str:
73
+ Iterates boxed item.
74
+
75
+ """
70
76
  if self:
71
- return 'Box(' + repr(self._item) + ')'
72
- return 'Box()'
77
+ yield cast(T, self._item)
73
78
 
74
79
  def __len__(self) -> int:
80
+ """
81
+ .. admonition:: Length
82
+
83
+ - 1 if ``Box`` contains an item
84
+ - 0 if ``Box`` is empty
85
+
86
+ :returns: The number of items currently in the ``Box``.
87
+
88
+ """
75
89
  return 1 if self else 0
76
90
 
77
91
  def __eq__(self, other: object) -> bool:
@@ -80,8 +94,8 @@ class Box[T]:
80
94
 
81
95
  Efficiently compare ``Box`` to another object.
82
96
 
83
- :param other: The object to be compared with,
84
- :returns: ``True`` if ``other`` is of type Box and contains
97
+ :param other: The object to be compared.
98
+ :returns: ``True`` if ``other`` is another ``Box`` and contains
85
99
  an object which compares as equal to the object
86
100
  contained in the ``Box``, otherwise ``False``.
87
101
 
@@ -95,6 +109,21 @@ class Box[T]:
95
109
  return True
96
110
  return False
97
111
 
112
+ def __repr__(self) -> str:
113
+ """
114
+ .. admonition:: Representation string
115
+
116
+ Construct string 'Box()' if empty, otherwise 'Box(item_repr)'
117
+ where ``item_repr = repr(item)`` for the currently contained
118
+ item.
119
+
120
+ :returns: A string to reproduce the current state of the ``Box``.
121
+
122
+ """
123
+ if self:
124
+ return 'Box(' + repr(self._item) + ')'
125
+ return 'Box()'
126
+
98
127
  @overload
99
128
  def get(self) -> T: ...
100
129
  @overload
@@ -12,6 +12,17 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- __author__ = 'Geoffrey R. Scheller'
16
- __copyright__ = 'Copyright (c) 2023-2026 Geoffrey R. Scheller'
17
- __license__ = 'Apache License 2.0'
15
+ """
16
+ sentinels
17
+ ---------
18
+
19
+ .. admonition:: Sentinel values
20
+
21
+ - Singletons
22
+ - Threadsafe
23
+ - Useful for both
24
+
25
+ - referenced objects
26
+ - hidden implementation details
27
+
28
+ """
@@ -12,30 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- """
16
- .. admonition:: When different flavors of the truth are needed.
17
-
18
- Sentinel values labeled by different (hashable) flavors.
19
- Threadsafe.
20
-
21
- .. tip::
22
-
23
- Can be compared using ``==`` and ``!=``. A flavored sentinel
24
- value always equals itself and never equals anything else,
25
- especially other flavored sentinel values.
26
-
27
- .. tip::
28
-
29
- Useful for union types where ``Sentinel[H]`` is one of the
30
- types making up the union.
31
-
32
- .. tip::
33
-
34
- To ensure that reference equality is used, put the known
35
- sentinel value first in the comparison.
36
-
37
- """
38
-
39
15
  import threading
40
16
  from typing import ClassVar, final, Hashable
41
17
 
@@ -44,12 +20,34 @@ __all__ = ['Sentinel']
44
20
 
45
21
  @final
46
22
  class Sentinel[H: Hashable]:
23
+ """
24
+ .. admonition:: Sentinel
25
+
26
+ Sentinel values labeled by different (hashable) flavors.
27
+
28
+ .. note::
29
+
30
+ - Useful for union types.
31
+ - A flavored ``Sentinel`` value always equals itself
32
+ and never equals anything else, especially other
33
+ flavored sentinel values.
34
+
35
+ """
36
+
47
37
  __slots__ = ('_flavor',)
48
38
 
49
39
  _flavors: 'dict[H, Sentinel[H]]' = {}
50
40
  _lock: ClassVar[threading.Lock] = threading.Lock()
51
41
 
52
42
  def __new__(cls, flavor: H) -> 'Sentinel[H]':
43
+ """
44
+ .. admonition:: new
45
+
46
+ :param flavor: Hashable value determining which
47
+ flavored ``Sentinel`` to return.
48
+ :returns: The ``Sentinel(flavor)`` singleton instance.
49
+
50
+ """
53
51
  if flavor not in cls._flavors:
54
52
  with cls._lock:
55
53
  if flavor not in cls._flavors:
@@ -58,25 +56,44 @@ class Sentinel[H: Hashable]:
58
56
 
59
57
  def __init__(self, flavor: H) -> None:
60
58
  """
61
- :param flavor: Some Hashable value of generic type ``H``.
62
- :returns: The ``Sentinel`` singleton instance with flavor ``flavor``.
63
- :rtype: ``Sentinel[H]`` where ``H`` is a subtype of Hashable.
59
+ .. admonition:: init
60
+
61
+ :param flavor: Hashable value to initially cache the flavor
62
+ :type flavor: ``H: Hashable``
64
63
 
65
64
  """
66
65
  if not hasattr(self, '_flavor'):
67
66
  self._flavor = flavor
68
67
 
69
68
  def __repr__(self) -> str:
69
+ """
70
+ .. admonition:: repr string
71
+
72
+ Construct string 'Sentinel(flavor)' where the flavor
73
+ is displayed with ``repr()``.
74
+
75
+ :returns: A string to reproduce the flavored sentinel.
76
+
77
+ """
70
78
  return "Sentinel('" + repr(self._flavor) + "')"
71
79
 
72
- def flavor(self) -> H:
80
+ def __str__(self) -> str:
73
81
  """
74
- .. admonition:: Get flavor
82
+ .. admonition:: user string
83
+
84
+ Construct string 'Sentinel(flavor)' where the flavor
85
+ is displayed with ``str()``.
75
86
 
76
- Get the sentinel's flavor, a hashable
77
- value of type ``H``.
87
+ :returns: A string meaningful to an end user.
88
+
89
+ """
90
+ return "Sentinel('" + str(self._flavor) + "')"
91
+
92
+ def flavor(self) -> H:
93
+ """
94
+ .. admonition:: get flavor
78
95
 
79
- :returns: The sentinel's flavor.
96
+ :returns: The sentinel's flavor.
80
97
 
81
98
  """
82
99
  return self._flavor
@@ -12,117 +12,176 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- """
16
- .. admonition:: Missing value.
15
+ import threading
16
+ from typing import ClassVar, final
17
17
 
18
- Singleton class representing an actually,
19
- not potentially, missing value.
18
+ __all__ = ['NoValue']
20
19
 
21
- ``NoValue()`` is a singleton object representing a missing value.
22
20
 
23
- While ``None`` and ``()`` are frequently used as sentinel values,
24
- I prefer to think of them as
21
+ @final
22
+ class NoValue:
23
+ """
24
+ .. admonition:: missing value
25
25
 
26
- - ``None``: Returns, or returned, no values.
27
- - ``()``: An empty, possibly typed, iterable collection.
26
+ Singleton class representing an actual, not
27
+ potential, missing value.
28
28
 
29
- .. important::
29
+ While ``None`` and ``()`` are frequently used as sentinel values,
30
+ I prefer to think of them as
30
31
 
31
- Given variables
32
+ - ``None`` as returns, or returned, no values.
33
+ - ``()`` as an empty, possibly typed, iterable collection.
32
34
 
33
- .. code:: python
35
+ .. important::
34
36
 
35
- x: int | NoValue
36
- y: int | NoValue
37
+ Given variables
37
38
 
38
- Equality between ``x`` and ``y`` means both values exist and compare
39
- as equal. If one or both of theses values are missing, then what is
40
- there to compare?
39
+ .. code:: python
41
40
 
42
- .. table:: ``x == y``
41
+ x: int | NoValue
42
+ y: int | NoValue
43
43
 
44
- +-----------+-----------+--------+--------+
45
- | x∖y | NoValue() | 42 | 57 |
46
- +===========+===========+========+========+
47
- | NoValue() | false | false | false |
48
- +-----------+-----------+--------+--------+
49
- | 42 | false | true | false |
50
- +-----------+-----------+--------+--------+
51
- | 57 | false | false | true |
52
- +-----------+-----------+--------+--------+
44
+ Equality between ``x`` and ``y`` means both values exist
45
+ and compare as equal.
53
46
 
54
- Similarly for not equals.
47
+ .. table:: ``x == y``
55
48
 
56
- .. table:: ``x != y``:wq
49
+ +-------------------+-------------------+------------+------------+
50
+ | | | | |
51
+ +===================+===================+============+============+
52
+ | | ``y = NoValue()`` | ``y = 42`` | ``y = 57`` |
53
+ +-------------------+-------------------+------------+------------+
54
+ | ``x = NoValue()`` | ``False`` | ``False`` | ``False`` |
55
+ +-------------------+-------------------+------------+------------+
56
+ | ``x = 42`` | ``False`` | ``True`` | ``False`` |
57
+ +-------------------+-------------------+------------+------------+
58
+ | ``x = 57`` | ``False`` | ``False`` | ``True`` |
59
+ +-------------------+-------------------+------------+------------+
57
60
 
58
- +-----------+-----------+--------+--------+
59
- | x∖y | NoValue() | 42 | 57 |
60
- +===========+===========+========+========+
61
- | NoValue() | false | false | false |
62
- +-----------+-----------+--------+--------+
63
- | 42 | false | false | true |
64
- +-----------+-----------+--------+--------+
65
- | 57 | false | true | false |
66
- +-----------+-----------+--------+--------+
61
+ .. table:: ``x != y``
67
62
 
68
- .. warning::
63
+ +-------------------+-------------------+------------+------------+
64
+ | | | | |
65
+ +===================+===================+============+============+
66
+ | | ``y = NoValue()`` | ``y = 42`` | ``y = 57`` |
67
+ +-------------------+-------------------+------------+------------+
68
+ | ``x = NoValue()`` | ``False`` | ``False`` | ``False`` |
69
+ +-------------------+-------------------+------------+------------+
70
+ | ``x = 42`` | ``False`` | ``False`` | ``True`` |
71
+ +-------------------+-------------------+------------+------------+
72
+ | ``x = 57`` | ``False`` | ``True`` | ``False`` |
73
+ +-------------------+-------------------+------------+------------+
69
74
 
70
- Only use ``==`` or ``!=`` in value comparisons. To directly
71
- identity the ``NoValue`` singleton, use ``is`` and ``is not``
72
- instead.
75
+ .. warning::
73
76
 
74
- .. note::
77
+ - use ``==`` or ``!=`` only in value comparisons
78
+ - use ``is`` and ``is not`` to identity the ``NoValue()``
79
+ singleton itself
75
80
 
76
- Threadsafe.
81
+ .. tip::
77
82
 
78
- .. tip::
83
+ Use in a union type when creating "optional" arguments
84
+ to functions and methods.
79
85
 
80
- Use as a hidden implementation detail when creating "optional"
81
- arguments to functions and methods.
86
+ To help ensure the abstraction stays a hidden implementation
87
+ detail and does not leak out into user code,
82
88
 
83
- To help ensure the abstraction does not leak,
89
+ - Do not export the sentinel value.
84
90
 
85
- - Do not export the sentinel value.
86
- - Use ``@overload`` to keep the NoValue type out of documentation and IDEs.
87
-
88
- """
89
- import threading
90
- from typing import ClassVar, final
91
+ - A new reference can always be generated via ``NoValue()``.
91
92
 
92
- __all__ = ['NoValue']
93
+ - Use ``@overload`` to keep the ``NoValue`` type out of
94
+ documentation and IDEs.
93
95
 
96
+ """
94
97
 
95
- @final
96
- class NoValue():
97
98
  __slots__ = ()
98
99
 
99
100
  _instance: 'ClassVar[NoValue | None]' = None
100
101
  _lock: ClassVar[threading.Lock] = threading.Lock()
102
+ _hash: ClassVar[int] = 0
101
103
 
102
104
  def __new__(cls) -> 'NoValue':
103
105
  """
104
- :returns: The ``NoValue`` singleton instance.
106
+ .. admonition:: new
107
+
108
+ :returns: The ``NoValue()`` singleton instance.
105
109
 
106
110
  """
107
111
  if cls._instance is None:
108
112
  with cls._lock:
109
113
  if cls._instance is None:
114
+ cls._hash = id(cls)
110
115
  cls._instance = super().__new__(cls)
111
116
  return cls._instance
112
117
 
118
+ def __hash__(self) -> int:
119
+ """
120
+ .. admonition:: hash
121
+
122
+ :returns: The singleton's unique integer hash value.
123
+ """
124
+ return type(self)._hash
125
+
113
126
  def __repr__(self) -> str:
127
+ """
128
+ .. admonition:: repr string
129
+
130
+ :returns: The string 'NoValue()'.
131
+
132
+ """
114
133
  return 'NoValue()'
115
134
 
135
+ def __bool__(self) -> bool:
136
+ """
137
+ .. admonition:: bool
138
+
139
+ Always falsy.
140
+
141
+ :returns: False
142
+
143
+ .. tip
144
+
145
+ Can be used to provide a fallback value when used
146
+ with Python shortcut logic.
147
+
148
+ .. code:: python
149
+
150
+ result: str | NoValue = NoValue()
151
+ if predicate(x):
152
+ result = 'some non-empty string'
153
+ value = result or 'fallback string'
154
+
155
+ """
156
+ return False
157
+
116
158
  def __eq__(self, other: object) -> bool:
117
159
  """
118
- :returns: ``False``
160
+ .. admonition:: Equality comparison
161
+
162
+ :param other: The object to be compared.
163
+ :returns: ``False`` even if compared to itself.
164
+
165
+ .. warning::
166
+
167
+ - non-standard comparison semantics
168
+ - always returns ``False``
169
+ - if one or both values are missing,
170
+ then what is there to compare?
119
171
 
120
172
  """
121
173
  return False
122
174
 
123
175
  def __ne__(self, other: object) -> bool:
124
176
  """
125
- :returns: ``False``
177
+ .. admonition:: not equal
178
+
179
+ :returns: ``False``
180
+
181
+ .. warning::
182
+
183
+ - non-standard comparison semantics
184
+ - always returns ``False``
126
185
 
127
186
  """
128
187
  return False
@@ -2,5 +2,7 @@ __all__ = ['NoValue']
2
2
 
3
3
  class NoValue:
4
4
  def __new__(cls) -> NoValue: ...
5
+ def __hash__(self) -> int: ...
6
+ def __bool__(self) -> bool: ...
5
7
  def __eq__(self, other: object) -> bool: ...
6
8
  def __ne__(self, other: object) -> bool: ...
@@ -30,7 +30,9 @@ class Wrap[T]():
30
30
  """
31
31
  .. admonition:: Wrap object
32
32
 
33
- Immutablely wrap exactly one value of a given type.
33
+ Immutablely wrap exactly one value of a
34
+ given type. ``Wrap`` objects can be used
35
+ in Python match statements.
34
36
 
35
37
  """
36
38
  __slots__ = ('_item',)
@@ -38,6 +40,10 @@ class Wrap[T]():
38
40
 
39
41
  def __init__(self, item: T) -> None:
40
42
  """
43
+ .. admonition:: Initializer
44
+
45
+ Initialize ``Wrap`` with 1 required item.
46
+
41
47
  :param item: Item to be wrapped.
42
48
 
43
49
  """
@@ -62,8 +68,18 @@ class Wrap[T]():
62
68
  if self:
63
69
  yield self._item
64
70
 
65
- def __repr__(self) -> str:
66
- return 'Wrap(' + repr(self._item) + ')'
71
+ def __str__(self) -> str:
72
+ """
73
+ .. admonition:: User string
74
+
75
+ Construct string 'Box(item_str)'
76
+ where ``item_str = str(item)`` for the currently contained
77
+ item.
78
+
79
+ :returns: A string to reproduce the current state of the ``Box``.
80
+
81
+ """
82
+ return 'Wrap(' + str(self._item) + ')'
67
83
 
68
84
  def __eq__(self, other: object) -> bool:
69
85
  """
@@ -115,17 +131,16 @@ class HWrap[T: Hashable](Hashable):
115
131
  """
116
132
  .. admonition:: Wrap hashable object
117
133
 
118
- Immutablely wrap exactly one value of a given hashable type.
134
+ Immutablely wrap exactly one value of a
135
+ given hashable type. ``HWrap`` objects can
136
+ be used in Python match statements.
119
137
 
120
- .. tip::
138
+ .. tip::
121
139
 
122
- ``HWrap`` objects can be used in Python match statements.
123
-
124
- .. tip::
125
-
126
- ``HWrap`` objects are hashable.
140
+ ``HWrap`` objects are hashable.
127
141
 
128
142
  """
143
+
129
144
  __slots__ = ('_item', '_hash')
130
145
  __match_args__ = ('_item',)
131
146
 
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-gadgets
3
- Version: 4.0.3
3
+ Version: 4.0.4
4
4
  Summary: Gadgets
5
5
  Keywords: gadgets
6
6
  Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
7
7
  Requires-Python: >=3.13
8
8
  Description-Content-Type: text/x-rst
9
- Classifier: Development Status :: 4 - Beta
9
+ Classifier: Development Status :: 3 - Alpha
10
10
  Classifier: Framework :: Pytest
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: License :: OSI Approved :: Apache Software License
@@ -17,8 +17,8 @@ License-File: LICENSE
17
17
  Requires-Dist: pytest>=8.4.1 ; extra == "test"
18
18
  Requires-Dist: pythonic-fp-circulararray>=6.0.4 ; extra == "test"
19
19
  Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-gadgets/blob/main/CHANGELOG.rst
20
- Project-URL: Documentation, https://grscheller.github.io/pythonic-fp-gadgets/
21
- Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/homepage/html/
20
+ Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/projects/gadgets.html
21
+ Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/
22
22
  Project-URL: Source, https://github.com/grscheller/pythonic-fp-gadgets
23
23
  Provides-Extra: test
24
24
 
@@ -35,22 +35,22 @@ outside the Python Standard Library.
35
35
  - Gadgets
36
36
 
37
37
  - single item box
38
- - wrapped (hashable) references
38
+ - immutable wrapped (hashable) references
39
39
  - function returning iterator of its arguments
40
40
  - function to find the latest common ancestor of two classes
41
41
  - sentinel values
42
42
 
43
43
  Part of the
44
44
  `pythonic-fp
45
- <https://grscheller.github.io/pythonic-fp/homepage/html/>`_
45
+ <https://grscheller.github.io/pythonic-fp/>`_
46
46
  PyPI projects.
47
47
 
48
48
  Documentation
49
49
  -------------
50
50
 
51
- Documentation for this project is hosted on
51
+ Documentation and other links for this project are hosted on
52
52
  `GitHub Pages
53
- <https://grscheller.github.io/pythonic-fp-gadgets>`_.
53
+ <https://grscheller.github.io/pythonic-fp/projects/gadgets.html>`_.
54
54
 
55
55
  Copyright and License
56
56
  ---------------------
@@ -0,0 +1,17 @@
1
+ pythonic_fp/gadgets/__init__.py,sha256=-pgzuWq-DTORXvy8JDQpnNPhQou85oiySH2-gArNeWc,2806
2
+ pythonic_fp/gadgets/__init__.pyi,sha256=-O921ioE28UPnDm_EL928vl6dDxhrfXHBQenusBo1_o,224
3
+ pythonic_fp/gadgets/box.py,sha256=Dx5wF3x9LyUs5MHjvHP6yTM05f4ojHPqqzfjuXJOo8I,6580
4
+ pythonic_fp/gadgets/box.pyi,sha256=UkJBY8Xiv4oe70Q3bhJL1jGHwYmFWwkTIdxvf2zR3v4,837
5
+ pythonic_fp/gadgets/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ pythonic_fp/gadgets/wrap.py,sha256=tAnG7P3EYl_1-CH2cs7IfY-0h4LET1LEIjmMo26OzCg,5388
7
+ pythonic_fp/gadgets/wrap.pyi,sha256=TRbBph_517VNCKchwU-pdtPCn73c09gq8EchDFM7Uyo,868
8
+ pythonic_fp/gadgets/sentinels/__init__.py,sha256=Xh63-GTwiqqcBqs5OEYBSiLXuWtq_CVHfUz0mKO_2H0,775
9
+ pythonic_fp/gadgets/sentinels/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ pythonic_fp/gadgets/sentinels/flavored.py,sha256=LPmA-XOadcN5gJgxxo2prSnwRvq8bJ7o0Ae2_Y70Au0,2774
11
+ pythonic_fp/gadgets/sentinels/flavored.pyi,sha256=K3YSyXLyylPII2ahRP0olhzLJruOeR73TFJDC6rCUwk,212
12
+ pythonic_fp/gadgets/sentinels/novalue.py,sha256=gaQNm1TRtphbmWgDV8O0sblH7eU2M-Zymu_B67mwsJ8,6097
13
+ pythonic_fp/gadgets/sentinels/novalue.pyi,sha256=1_iUI6FEwYma8P4XXVCb6CKhSYmfq53S8dLmiwNtJw4,244
14
+ pythonic_fp_gadgets-4.0.4.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
15
+ pythonic_fp_gadgets-4.0.4.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
16
+ pythonic_fp_gadgets-4.0.4.dist-info/METADATA,sha256=SbxLXeCZA7LOtg3Q_mpBPlux1FR6-shkI9S2tutdVgk,1895
17
+ pythonic_fp_gadgets-4.0.4.dist-info/RECORD,,
@@ -1,17 +0,0 @@
1
- pythonic_fp/gadgets/__init__.py,sha256=29fNYn8LLhCUfvZ_vcofSoGhs9_Hw95cPF3sd0G1z9M,2739
2
- pythonic_fp/gadgets/__init__.pyi,sha256=cAf10WX2ZHMs-Tf93mImmDdZw7lNEmwjorkiVF04s_E,224
3
- pythonic_fp/gadgets/box.py,sha256=2PL0wkimRwgsL15aTkB2QTo4B40IY6G0lCo0Esa0CTU,5860
4
- pythonic_fp/gadgets/box.pyi,sha256=UkJBY8Xiv4oe70Q3bhJL1jGHwYmFWwkTIdxvf2zR3v4,837
5
- pythonic_fp/gadgets/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- pythonic_fp/gadgets/wrap.py,sha256=EVhp115DcokaBa-0xN3CN3Qlr4vkHvEZQIPuMYYxHas,4950
7
- pythonic_fp/gadgets/wrap.pyi,sha256=TRbBph_517VNCKchwU-pdtPCn73c09gq8EchDFM7Uyo,868
8
- pythonic_fp/gadgets/sentinels/__init__.py,sha256=WsGXds578j1y7FsLEGer59P1c8EItUBTp60cuA0T56E,724
9
- pythonic_fp/gadgets/sentinels/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- pythonic_fp/gadgets/sentinels/flavored.py,sha256=W33020r3U8jxIDdJDaa-xE7o4cI1NY0bLZi8puIUBqA,2353
11
- pythonic_fp/gadgets/sentinels/flavored.pyi,sha256=K3YSyXLyylPII2ahRP0olhzLJruOeR73TFJDC6rCUwk,212
12
- pythonic_fp/gadgets/sentinels/novalue.py,sha256=9wya9NBDQzfr2rxwrCd7uh74Trm4iVsK53UAUZo5Iyk,3613
13
- pythonic_fp/gadgets/sentinels/novalue.pyi,sha256=zhZdePpWoQ3ZXOq7xQWGR0A4W_XzasdBQKcoywXZEZI,173
14
- pythonic_fp_gadgets-4.0.3.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
15
- pythonic_fp_gadgets-4.0.3.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
16
- pythonic_fp_gadgets-4.0.3.dist-info/METADATA,sha256=z6LP-dUh7AgGHq-TTbn3qS0QyIDc-5GNohGM23QXMzU,1868
17
- pythonic_fp_gadgets-4.0.3.dist-info/RECORD,,