pythonic-fp-gadgets 2.2.0__tar.gz → 3.0.1__tar.gz

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.
Files changed (20) hide show
  1. {pythonic_fp_gadgets-2.2.0 → pythonic_fp_gadgets-3.0.1}/CHANGELOG.rst +19 -2
  2. {pythonic_fp_gadgets-2.2.0 → pythonic_fp_gadgets-3.0.1}/PKG-INFO +3 -3
  3. {pythonic_fp_gadgets-2.2.0 → pythonic_fp_gadgets-3.0.1}/README.rst +1 -1
  4. {pythonic_fp_gadgets-2.2.0 → pythonic_fp_gadgets-3.0.1}/pyproject.toml +1 -1
  5. pythonic_fp_gadgets-3.0.1/src/pythonic_fp/gadgets/__init__.py +35 -0
  6. {pythonic_fp_gadgets-2.2.0 → pythonic_fp_gadgets-3.0.1}/src/pythonic_fp/gadgets/box.py +6 -8
  7. {pythonic_fp_gadgets-2.2.0 → pythonic_fp_gadgets-3.0.1}/src/pythonic_fp/gadgets/box.pyi +5 -8
  8. pythonic_fp_gadgets-2.2.0/src/pythonic_fp/gadgets/it.py → pythonic_fp_gadgets-3.0.1/src/pythonic_fp/gadgets/iterate_arguments.py +2 -2
  9. pythonic_fp_gadgets-3.0.1/src/pythonic_fp/gadgets/iterate_arguments.pyi +5 -0
  10. pythonic_fp_gadgets-2.2.0/src/pythonic_fp/gadgets/lca.py → pythonic_fp_gadgets-3.0.1/src/pythonic_fp/gadgets/latest_common_ancestor.py +3 -4
  11. pythonic_fp_gadgets-3.0.1/src/pythonic_fp/gadgets/latest_common_ancestor.pyi +3 -0
  12. {pythonic_fp_gadgets-2.2.0 → pythonic_fp_gadgets-3.0.1}/tests/test_box.py +2 -1
  13. {pythonic_fp_gadgets-2.2.0 → pythonic_fp_gadgets-3.0.1}/tests/test_it.py +9 -9
  14. {pythonic_fp_gadgets-2.2.0 → pythonic_fp_gadgets-3.0.1}/tests/test_lca.py +1 -1
  15. pythonic_fp_gadgets-2.2.0/src/pythonic_fp/gadgets/__init__.py +0 -33
  16. pythonic_fp_gadgets-2.2.0/src/pythonic_fp/gadgets/it.pyi +0 -5
  17. pythonic_fp_gadgets-2.2.0/src/pythonic_fp/gadgets/lca.pyi +0 -5
  18. {pythonic_fp_gadgets-2.2.0 → pythonic_fp_gadgets-3.0.1}/.gitignore +0 -0
  19. {pythonic_fp_gadgets-2.2.0 → pythonic_fp_gadgets-3.0.1}/LICENSE +0 -0
  20. {pythonic_fp_gadgets-2.2.0 → pythonic_fp_gadgets-3.0.1}/src/pythonic_fp/gadgets/py.typed +0 -0
@@ -17,8 +17,22 @@ See `Semantic Versioning 2.0.0 <https://semver.org>`_.
17
17
  Releases and Important Milestones
18
18
  ---------------------------------
19
19
 
20
- Update - 2025-08-30
21
- ~~~~~~~~~~~~~~~~~~~
20
+ PyPI v3.0.0 - 2025-08-31
21
+ ~~~~~~~~~~~~~~~~~~~~~~~~
22
+
23
+ Discovered I was not quite compliant with Python typing 3.12+ conventions.
24
+
25
+ - No longer explicitly using TypeVar directly.
26
+ - Removed Unions with Never from .py files
27
+
28
+ - only "happy path" return types (pythonic convention)
29
+ - stubgen actually puts them back in .pyi files
30
+
31
+ - renamed it.it -> iterate_arguments.ita
32
+ - renamed lca.latest_common_ancestor -> latest_common_ancestor.lca
33
+
34
+ PyPI v2.2.0 - 2025-08-30
35
+ ~~~~~~~~~~~~~~~~~~~~~~~~
22
36
 
23
37
  Moved for pythonic_fp.gadgets package to a new GitHub repo, pythonic-fp-gadgets.
24
38
  Replaced it with the empty Python module ``pythonic_fp.name_claim``.
@@ -26,6 +40,9 @@ Replaced it with the empty Python module ``pythonic_fp.name_claim``.
26
40
  The gadgets package being different from the other namespace packages
27
41
  was throwing off my workflow.
28
42
 
43
+ - added function it.it
44
+ - added function lca.latest_common_ancestor
45
+
29
46
  Update - 2025-08-09
30
47
  ~~~~~~~~~~~~~~~~~~~
31
48
 
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-gadgets
3
- Version: 2.2.0
4
- Summary: Simple Gadgets.
3
+ Version: 3.0.1
4
+ Summary: Simple Gadgets
5
5
  Keywords: gadgets
6
6
  Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
7
7
  Requires-Python: >=3.13
@@ -26,7 +26,7 @@ Pythonic FP - Gadgets
26
26
  =====================
27
27
 
28
28
  PyPI project
29
- `pythonic-fp
29
+ `pythonic-fp-gadgets
30
30
  <https://pypi.org/project/pythonic-fp>`_.
31
31
 
32
32
  Library of simple, but useful, data structures with minimal dependencies.
@@ -2,7 +2,7 @@ Pythonic FP - Gadgets
2
2
  =====================
3
3
 
4
4
  PyPI project
5
- `pythonic-fp
5
+ `pythonic-fp-gadgets
6
6
  <https://pypi.org/project/pythonic-fp>`_.
7
7
 
8
8
  Library of simple, but useful, data structures with minimal dependencies.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pythonic-fp-gadgets"
3
- version = "2.2.0"
3
+ version = "3.0.1"
4
4
  readme = "README.rst"
5
5
  requires-python = ">=3.13"
6
6
  license = { file = "LICENSE" }
@@ -0,0 +1,35 @@
1
+ # Copyright 2023-2025 Geoffrey R. Scheller
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """
16
+ Simple Gadgets
17
+ ==============
18
+
19
+ Library of simple, but useful, functions and classes with minimal dependencies.
20
+
21
+ +------------------------------+------------------+------------------------------------------------+
22
+ | Description | Gadget | Module |
23
+ +==============================+==================+================================================+
24
+ | Single item box | class ``Box`` | ``pythonic_fp.gadgets.box`` |
25
+ +------------------------------+------------------+------------------------------------------------+
26
+ | Return Iterator of arguments | function ``ita`` | ``pythonic_fp.gadgets.iterate_arguments`` |
27
+ +------------------------------+------------------+------------------------------------------------+
28
+ | Find least common base class | function ``lca`` | ``pythonic_fp.gadgets.latest_common_ancestor`` |
29
+ +------------------------------+------------------+------------------------------------------------+
30
+
31
+ """
32
+
33
+ __author__ = 'Geoffrey R. Scheller'
34
+ __copyright__ = 'Copyright (c) 2023-2025 Geoffrey R. Scheller'
35
+ __license__ = 'Apache License 2.0'
@@ -17,11 +17,9 @@
17
17
  __all__ = ['Box']
18
18
 
19
19
  from collections.abc import Callable, Iterator
20
- from typing import ClassVar, cast, Final, Never, overload, TypeVar
20
+ from typing import ClassVar, cast, Final, overload
21
21
  from pythonic_fp.sentinels.flavored import Sentinel
22
22
 
23
- T = TypeVar('T')
24
-
25
23
 
26
24
  class Box[T]:
27
25
  """Container holding at most one item of a given type.
@@ -83,11 +81,11 @@ class Box[T]:
83
81
  return False
84
82
 
85
83
  @overload
86
- def get(self) -> T | Never: ...
84
+ def get(self) -> T: ...
87
85
  @overload
88
86
  def get(self, alt: T) -> T: ...
89
87
 
90
- def get(self, alt: T | Sentinel[str] = Sentinel('_Box')) -> T | Never:
88
+ def get(self, alt: T | Sentinel[str] = Sentinel('_Box')) -> T:
91
89
  """Return the contained item if it exists, otherwise an alternate item.
92
90
 
93
91
  :param alt: an "optional" item of type ``T`` to return if ``Box`` is empty
@@ -102,7 +100,7 @@ class Box[T]:
102
100
  raise ValueError(msg)
103
101
  return cast(T, alt)
104
102
 
105
- def pop(self) -> T | Never:
103
+ def pop(self) -> T:
106
104
  """Pop the contained item if ``Box`` is not empty.
107
105
 
108
106
  :returns: item contained in the ``Box``
@@ -116,7 +114,7 @@ class Box[T]:
116
114
  self._item = self._sentinel
117
115
  return popped
118
116
 
119
- def push(self, item: T) -> None | Never:
117
+ def push(self, item: T) -> None:
120
118
  """Push an item into an empty ``Box``.
121
119
 
122
120
  :param item: Item to push into the empty ``Box``.
@@ -134,7 +132,7 @@ class Box[T]:
134
132
  """Put an item in the Box. Discard any previous contents."""
135
133
  self._item = item
136
134
 
137
- def exchange(self, new_item: T) -> T | Never:
135
+ def exchange(self, new_item: T) -> T:
138
136
  """Exchange an item with what is in the Box.
139
137
 
140
138
  :param ``new_item``: New item to exchange for current item.
@@ -1,14 +1,11 @@
1
1
  from _typeshed import Incomplete
2
2
  from collections.abc import Callable, Iterator
3
- from typing import Never, TypeVar, overload
3
+ from typing import overload
4
4
 
5
5
  __all__ = ['Box']
6
6
 
7
- T = TypeVar('T')
8
-
9
7
  class Box[T]:
10
8
  __match_args__: Incomplete
11
- T = TypeVar('T')
12
9
  @overload
13
10
  def __init__(self) -> None: ...
14
11
  @overload
@@ -18,12 +15,12 @@ class Box[T]:
18
15
  def __len__(self) -> int: ...
19
16
  def __eq__(self, other: object) -> bool: ...
20
17
  @overload
21
- def get(self) -> T | Never: ...
18
+ def get(self) -> T: ...
22
19
  @overload
23
20
  def get(self, alt: T) -> T: ...
24
- def pop(self) -> T | Never: ...
25
- def push(self, item: T) -> None | Never: ...
21
+ def pop(self) -> T: ...
22
+ def push(self, item: T) -> None: ...
26
23
  def put(self, item: T) -> None: ...
27
- def exchange(self, new_item: T) -> T | Never: ...
24
+ def exchange(self, new_item: T) -> T: ...
28
25
  def map[U](self, f: Callable[[T], U]) -> Box[U]: ...
29
26
  def bind[U](self, f: Callable[[T], 'Box[U]']) -> Box[U]: ...
@@ -16,10 +16,10 @@
16
16
 
17
17
  from collections.abc import Iterator
18
18
 
19
- __all__ = ['it']
19
+ __all__ = ['ita']
20
20
 
21
21
 
22
- def it[A](*args: A) -> Iterator[A]:
22
+ def ita[A](*args: A) -> Iterator[A]:
23
23
  """Function returning an iterator of its arguments.
24
24
 
25
25
  .. note::
@@ -0,0 +1,5 @@
1
+ from collections.abc import Iterator
2
+
3
+ __all__ = ['ita']
4
+
5
+ def ita[A](*args: A) -> Iterator[A]: ...
@@ -12,15 +12,14 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- """Lastest Common Ancestor of Two Classes."""
15
+ """Last Common Ancestor of Two Classes."""
16
16
 
17
17
  from inspect import getmro
18
- from typing import Never
19
18
 
20
- __all__ = ['latest_common_ancestor']
19
+ __all__ = ['lca']
21
20
 
22
21
 
23
- def latest_common_ancestor(cls1: type, cls2: type) -> type | Never:
22
+ def lca(cls1: type, cls2: type) -> type:
24
23
  """Find the least upper bound in the inheritance graph
25
24
  of two classes.
26
25
 
@@ -0,0 +1,3 @@
1
+ __all__ = ['lca']
2
+
3
+ def lca(cls1: type, cls2: type) -> type: ...
@@ -20,11 +20,12 @@ class TestGadgetBox:
20
20
 
21
21
  def test_box_unchanged(self) -> None:
22
22
  box_init_empty: Box[int] = Box()
23
- box_init_full = Box(42)
23
+ box_init_full: Box[int] = Box(42)
24
24
 
25
25
  if box_init_empty or not box_init_full:
26
26
  assert False
27
27
 
28
+ ii: int
28
29
  for ii in box_init_empty:
29
30
  assert False
30
31
 
@@ -13,22 +13,22 @@
13
13
  # limitations under the License.
14
14
 
15
15
  from pythonic_fp.circulararray.auto import ca, CA
16
- from pythonic_fp.gadgets.it import it
16
+ from pythonic_fp.gadgets.iterate_arguments import ita
17
17
 
18
18
  class TestGadgetIt:
19
19
  """Functionality testing"""
20
20
 
21
- def test_it(self) -> None:
21
+ def test_ita(self) -> None:
22
22
  ref0: list[int] = []
23
- trg0: list[int] = list(it())
23
+ trg0: list[int] = list(ita())
24
24
  assert ref0 == trg0
25
25
 
26
26
  ref1 = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2046, 4092]
27
- trg1 = list(it(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2046, 4092))
27
+ trg1 = list(ita(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2046, 4092))
28
28
  assert ref1 == trg1
29
29
 
30
30
  ref2 = [1, 2, 3]
31
- trg2 = [*it(1,2,3)]
31
+ trg2 = [*ita(1,2,3)]
32
32
  assert ref2 == trg2
33
33
 
34
34
  ca_iter = CA((1, 2))
@@ -36,11 +36,11 @@ class TestGadgetIt:
36
36
  assert ca_iter == ca_args
37
37
 
38
38
  ca0_ref: CA[int] = ca()
39
- ca0_trg: CA[int] = CA[int](it())
39
+ ca0_trg: CA[int] = CA[int](ita())
40
40
  assert ca0_ref == ca0_trg
41
41
 
42
42
  ca1_ref: CA[int] = CA((42, 7, 11, 100))
43
- ca1_trg = CA(it(42, 7, 11, 100))
44
- ca1_splat1 = ca(*it(42, 7, 11, 100))
45
- ca1_splat2 = ca(*it(42, 7), *it(11, 100))
43
+ ca1_trg = CA(ita(42, 7, 11, 100))
44
+ ca1_splat1 = ca(*ita(42, 7, 11, 100))
45
+ ca1_splat2 = ca(*ita(42, 7), *ita(11, 100))
46
46
  assert ca1_ref == ca1_trg == ca1_splat1 == ca1_splat2
@@ -12,7 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from pythonic_fp.gadgets.lca import latest_common_ancestor as lca
15
+ from pythonic_fp.gadgets.latest_common_ancestor import lca
16
16
 
17
17
  class A1():
18
18
  pass
@@ -1,33 +0,0 @@
1
- # Copyright 2023-2025 Geoffrey R. Scheller
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- """Simple Gadgets.
16
-
17
- Library of simple, but useful, functions and classes with minimal dependencies.
18
-
19
- +-------------------------------------+-----------------------------------+------------------------------+
20
- | Gadget | Description | Module |
21
- +=====================================+===================================+==============================+
22
- | class ``Box`` | Single item box | ``pythonic_fp.gadgets.box`` |
23
- +-------------------------------------+-----------------------------------+------------------------------+
24
- | function ``it`` | Returns iterator of its arguments | ``pythonic_fp.gadgets.it`` |
25
- +-------------------------------------+-----------------------------------+------------------------------+
26
- | function ``latest_common_ancestor`` | Find least common base class | ``pythonic_fp.gadgets.lca`` |
27
- +-------------------------------------+-----------------------------------+------------------------------+
28
-
29
- """
30
-
31
- __author__ = 'Geoffrey R. Scheller'
32
- __copyright__ = 'Copyright (c) 2023-2025 Geoffrey R. Scheller'
33
- __license__ = 'Apache License 2.0'
@@ -1,5 +0,0 @@
1
- from collections.abc import Iterator
2
-
3
- __all__ = ['it']
4
-
5
- def it[A](*args: A) -> Iterator[A]: ...
@@ -1,5 +0,0 @@
1
- from typing import Never
2
-
3
- __all__ = ['latest_common_ancestor']
4
-
5
- def latest_common_ancestor(cls1: type, cls2: type) -> type | Never: ...