hunterMakesPy 0.5.5__tar.gz → 0.7.0__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.
- {huntermakespy-0.5.5/hunterMakesPy.egg-info → huntermakespy-0.7.0}/PKG-INFO +7 -107
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/README.md +2 -96
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/__init__.py +1 -1
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/coping.py +8 -5
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/dataStructures.py +20 -20
- huntermakespy-0.7.0/hunterMakesPy/filesystemToolkit.py +293 -0
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/parseParameters.py +14 -7
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/semiotics.py +0 -1
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/tests/conftest.py +4 -4
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/tests/test_coping.py +1 -1
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/tests/test_dataStructures.py +17 -23
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/tests/test_filesystemToolkit.py +11 -12
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/tests/test_parseParameters.py +5 -4
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/tests/test_theTypes.py +21 -94
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/theTypes.py +5 -2
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/theTypesCallableFunction.py +13 -19
- {huntermakespy-0.5.5 → huntermakespy-0.7.0/hunterMakesPy.egg-info}/PKG-INFO +7 -107
- huntermakespy-0.7.0/hunterMakesPy.egg-info/SOURCES.txt +25 -0
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy.egg-info/requires.txt +1 -4
- huntermakespy-0.7.0/hunterMakesPy.egg-info/top_level.txt +1 -0
- huntermakespy-0.7.0/pyproject.toml +79 -0
- huntermakespy-0.5.5/humpy_cytoolz/Notice_of_Copyright.txt +0 -32
- huntermakespy-0.5.5/humpy_cytoolz/__init__.pxd +0 -19
- huntermakespy-0.5.5/humpy_cytoolz/__init__.py +0 -25
- huntermakespy-0.5.5/humpy_cytoolz/__init__.pyi +0 -24
- huntermakespy-0.5.5/humpy_cytoolz/_signatures.py +0 -12
- huntermakespy-0.5.5/humpy_cytoolz/_signatures.pyi +0 -27
- huntermakespy-0.5.5/humpy_cytoolz/cpython.pxd +0 -11
- huntermakespy-0.5.5/humpy_cytoolz/curried/__init__.py +0 -78
- huntermakespy-0.5.5/humpy_cytoolz/curried/exceptions.py +0 -13
- huntermakespy-0.5.5/humpy_cytoolz/curried/exceptions.pyi +0 -30
- huntermakespy-0.5.5/humpy_cytoolz/curried/operator.py +0 -7
- huntermakespy-0.5.5/humpy_cytoolz/dicttoolz.c +0 -17659
- huntermakespy-0.5.5/humpy_cytoolz/dicttoolz.pxd +0 -51
- huntermakespy-0.5.5/humpy_cytoolz/dicttoolz.pyi +0 -126
- huntermakespy-0.5.5/humpy_cytoolz/dicttoolz.pyx +0 -974
- huntermakespy-0.5.5/humpy_cytoolz/functoolz.c +0 -29204
- huntermakespy-0.5.5/humpy_cytoolz/functoolz.pxd +0 -67
- huntermakespy-0.5.5/humpy_cytoolz/functoolz.pyi +0 -402
- huntermakespy-0.5.5/humpy_cytoolz/functoolz.pyx +0 -919
- huntermakespy-0.5.5/humpy_cytoolz/itertoolz.c +0 -53819
- huntermakespy-0.5.5/humpy_cytoolz/itertoolz.pxd +0 -282
- huntermakespy-0.5.5/humpy_cytoolz/itertoolz.pyi +0 -298
- huntermakespy-0.5.5/humpy_cytoolz/itertoolz.pyx +0 -1864
- huntermakespy-0.5.5/humpy_cytoolz/recipes.c +0 -11453
- huntermakespy-0.5.5/humpy_cytoolz/recipes.pxd +0 -5
- huntermakespy-0.5.5/humpy_cytoolz/recipes.pyi +0 -35
- huntermakespy-0.5.5/humpy_cytoolz/recipes.pyx +0 -67
- huntermakespy-0.5.5/humpy_cytoolz/tests/__init__.py +0 -1
- huntermakespy-0.5.5/humpy_cytoolz/tests/dev_skip_test.py +0 -29
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_curried.py +0 -89
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_curried_toolzlike.py +0 -30
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_dev_skip_test.py +0 -18
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_dicttoolz.py +0 -436
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_docstrings.py +0 -52
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_doctests.py +0 -16
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_embedded_sigs.py +0 -67
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_functoolz.py +0 -627
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_inspect_args.py +0 -439
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_itertoolz.py +0 -415
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_none_safe.py +0 -243
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_recipes.py +0 -16
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_serialization.py +0 -138
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_signatures.py +0 -74
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_stubs.py +0 -0
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_tlz.py +0 -48
- huntermakespy-0.5.5/humpy_cytoolz/tests/test_utils.py +0 -13
- huntermakespy-0.5.5/humpy_cytoolz/utils.c +0 -9069
- huntermakespy-0.5.5/humpy_cytoolz/utils.pxd +0 -1
- huntermakespy-0.5.5/humpy_cytoolz/utils.pyi +0 -11
- huntermakespy-0.5.5/humpy_cytoolz/utils.pyx +0 -60
- huntermakespy-0.5.5/humpy_tlz/__init__.py +0 -9
- huntermakespy-0.5.5/humpy_tlz/_build_tlz.py +0 -82
- huntermakespy-0.5.5/humpy_toolz/Notice_of_Copyright.txt +0 -32
- huntermakespy-0.5.5/humpy_toolz/__init__.py +0 -22
- huntermakespy-0.5.5/humpy_toolz/__init__.pyi +0 -29
- huntermakespy-0.5.5/humpy_toolz/_signatures.py +0 -199
- huntermakespy-0.5.5/humpy_toolz/curried/__init__.py +0 -78
- huntermakespy-0.5.5/humpy_toolz/curried/__init__.pyi +0 -1478
- huntermakespy-0.5.5/humpy_toolz/curried/exceptions.py +0 -13
- huntermakespy-0.5.5/humpy_toolz/curried/exceptions.pyi +0 -91
- huntermakespy-0.5.5/humpy_toolz/curried/operator.py +0 -8
- huntermakespy-0.5.5/humpy_toolz/curried/operator.pyi +0 -248
- huntermakespy-0.5.5/humpy_toolz/dicttoolz.py +0 -866
- huntermakespy-0.5.5/humpy_toolz/functoolz.py +0 -834
- huntermakespy-0.5.5/humpy_toolz/functoolz.pyi +0 -370
- huntermakespy-0.5.5/humpy_toolz/itertoolz.py +0 -1173
- huntermakespy-0.5.5/humpy_toolz/py.typed +0 -0
- huntermakespy-0.5.5/humpy_toolz/recipes.py +0 -43
- huntermakespy-0.5.5/humpy_toolz/recipes.pyi +0 -14
- huntermakespy-0.5.5/humpy_toolz/sandbox/__init__.py +0 -3
- huntermakespy-0.5.5/humpy_toolz/sandbox/__init__.pyi +0 -4
- huntermakespy-0.5.5/humpy_toolz/sandbox/core.py +0 -121
- huntermakespy-0.5.5/humpy_toolz/sandbox/core.pyi +0 -54
- huntermakespy-0.5.5/humpy_toolz/sandbox/parallel.py +0 -70
- huntermakespy-0.5.5/humpy_toolz/sandbox/parallel.pyi +0 -20
- huntermakespy-0.5.5/humpy_toolz/sandbox/tests/__init__.py +0 -1
- huntermakespy-0.5.5/humpy_toolz/sandbox/tests/test_core.py +0 -82
- huntermakespy-0.5.5/humpy_toolz/sandbox/tests/test_parallel.py +0 -22
- huntermakespy-0.5.5/humpy_toolz/tests/__init__.py +0 -1
- huntermakespy-0.5.5/humpy_toolz/tests/test_curried.py +0 -89
- huntermakespy-0.5.5/humpy_toolz/tests/test_curried_doctests.py +0 -10
- huntermakespy-0.5.5/humpy_toolz/tests/test_dicttoolz.py +0 -1077
- huntermakespy-0.5.5/humpy_toolz/tests/test_functoolz.py +0 -620
- huntermakespy-0.5.5/humpy_toolz/tests/test_inspect_args.py +0 -441
- huntermakespy-0.5.5/humpy_toolz/tests/test_itertoolz.py +0 -417
- huntermakespy-0.5.5/humpy_toolz/tests/test_package.py +0 -6
- huntermakespy-0.5.5/humpy_toolz/tests/test_recipes.py +0 -16
- huntermakespy-0.5.5/humpy_toolz/tests/test_serialization.py +0 -139
- huntermakespy-0.5.5/humpy_toolz/tests/test_signatures.py +0 -74
- huntermakespy-0.5.5/humpy_toolz/tests/test_tlz.py +0 -53
- huntermakespy-0.5.5/humpy_toolz/tests/test_utils.py +0 -5
- huntermakespy-0.5.5/humpy_toolz/utils.py +0 -190
- huntermakespy-0.5.5/hunterMakesPy/filesystemToolkit.py +0 -222
- huntermakespy-0.5.5/hunterMakesPy/py.typed +0 -0
- huntermakespy-0.5.5/hunterMakesPy.egg-info/SOURCES.txt +0 -118
- huntermakespy-0.5.5/hunterMakesPy.egg-info/top_level.txt +0 -4
- huntermakespy-0.5.5/pyproject.toml +0 -143
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/LICENSE +0 -0
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/_theSSOT.py +0 -0
- {huntermakespy-0.5.5/humpy_cytoolz → huntermakespy-0.7.0/hunterMakesPy}/py.typed +0 -0
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy/tests/__init__.py +0 -0
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/hunterMakesPy.egg-info/dependency_links.txt +0 -0
- {huntermakespy-0.5.5 → huntermakespy-0.7.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hunterMakesPy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Easy Python functions making making functional Python functions easier.
|
|
5
5
|
Author-email: Hunter Hogan <HunterHogan@pm.me>
|
|
6
6
|
License-Expression: CC-BY-NC-4.0
|
|
@@ -9,7 +9,7 @@ Project-URL: Donate, https://www.patreon.com/integrated
|
|
|
9
9
|
Project-URL: Homepage, https://github.com/hunterhogan/hunterMakesPy
|
|
10
10
|
Project-URL: Issues, https://github.com/hunterhogan/hunterMakesPy/issues
|
|
11
11
|
Project-URL: Repository, https://github.com/hunterhogan/hunterMakesPy
|
|
12
|
-
Keywords: attribute loading,
|
|
12
|
+
Keywords: attribute loading,configuration,defensive programming,dictionary merging,dynamic import,file system utilities,input validation,module loading,package settings,parameter validation
|
|
13
13
|
Classifier: Development Status :: 5 - Production/Stable
|
|
14
14
|
Classifier: Environment :: Console
|
|
15
15
|
Classifier: Framework :: Pytest
|
|
@@ -19,15 +19,12 @@ Classifier: Intended Audience :: Other Audience
|
|
|
19
19
|
Classifier: Natural Language :: English
|
|
20
20
|
Classifier: Operating System :: OS Independent
|
|
21
21
|
Classifier: Programming Language :: Python
|
|
22
|
-
Classifier: Programming Language :: Python :: 3
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
25
23
|
Classifier: Programming Language :: Python :: 3.14
|
|
26
|
-
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
27
24
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
28
25
|
Classifier: Topic :: Utilities
|
|
29
26
|
Classifier: Typing :: Typed
|
|
30
|
-
Requires-Python: >=3.
|
|
27
|
+
Requires-Python: >=3.10
|
|
31
28
|
Description-Content-Type: text/markdown
|
|
32
29
|
License-File: LICENSE
|
|
33
30
|
Requires-Dist: autoflake
|
|
@@ -35,21 +32,18 @@ Requires-Dist: charset_normalizer
|
|
|
35
32
|
Requires-Dist: isort
|
|
36
33
|
Requires-Dist: more_itertools
|
|
37
34
|
Requires-Dist: numpy
|
|
35
|
+
Requires-Dist: tomli
|
|
38
36
|
Requires-Dist: typing_extensions>=4.10.0
|
|
39
37
|
Provides-Extra: development
|
|
40
|
-
Requires-Dist: astToolkit; extra == "development"
|
|
41
|
-
Requires-Dist: setuptools>=62.3; extra == "development"
|
|
42
38
|
Requires-Dist: pytest-cov; extra == "development"
|
|
43
39
|
Provides-Extra: testing
|
|
44
|
-
Requires-Dist: cython; extra == "testing"
|
|
45
40
|
Requires-Dist: librosa; extra == "testing"
|
|
46
41
|
Requires-Dist: pytest; extra == "testing"
|
|
47
|
-
Requires-Dist: pytest-xdist; extra == "testing"
|
|
48
42
|
Dynamic: license-file
|
|
49
43
|
|
|
50
44
|
# hunterMakesPy
|
|
51
45
|
|
|
52
|
-
Utilities for converting mixed input to integers, calculating CPU limits, handling None values, importing code dynamically, and manipulating nested data.
|
|
46
|
+
Utilities for converting mixed input to integers, calculating CPU limits, handling None values, importing code dynamically, and manipulating nested data.
|
|
53
47
|
|
|
54
48
|
[](https://pypi.org/project/hunterMakesPy/)
|
|
55
49
|
|
|
@@ -128,7 +122,7 @@ Write to `"deep/nested/path/file.txt"` and parent directories are created automa
|
|
|
128
122
|
from hunterMakesPy.filesystemToolkit import writeStringToHere, writePython
|
|
129
123
|
|
|
130
124
|
writeStringToHere("content", "nested/dirs/file.txt") # Creates dirs
|
|
131
|
-
writePython(sourceCode, "output/module.py")
|
|
125
|
+
writePython(sourceCode, "output/module.py") # Formats, then writes
|
|
132
126
|
```
|
|
133
127
|
|
|
134
128
|
## Extract Strings from Arbitrarily Nested Data
|
|
@@ -189,100 +183,6 @@ def test_my_integer_validator(test_name, test_func):
|
|
|
189
183
|
test_func()
|
|
190
184
|
```
|
|
191
185
|
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
## `humpy_toolz`: Typed Pure-Python Functional Utilities
|
|
195
|
-
|
|
196
|
-
`humpy_toolz` is a typed fork of [`toolz`](https://github.com/pytoolz/toolz). It provides composable functions for iterators, dictionaries, and function composition with full type stubs and docstrings.
|
|
197
|
-
|
|
198
|
-
### Dictionary Transformations without Mutation
|
|
199
|
-
|
|
200
|
-
Create new mappings by associating, dissociating, filtering, and mapping over keys or values. Nested access is supported through key-path sequences.
|
|
201
|
-
|
|
202
|
-
```python
|
|
203
|
-
from humpy_toolz import merge, valmap, keyfilter, assoc
|
|
204
|
-
|
|
205
|
-
merged = merge({"a": 1}, {"b": 2}) # {"a": 1, "b": 2}
|
|
206
|
-
doubled = valmap(lambda x: x * 2, {"a": 1}) # {"a": 2}
|
|
207
|
-
evens = keyfilter(lambda k: k > 1, {1: "a", 2: "b"}) # {2: "b"}
|
|
208
|
-
updated = assoc({"x": 10}, "y", 20) # {"x": 10, "y": 20}
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### Compose, Curry, and Thread Functions
|
|
212
|
-
|
|
213
|
-
Build transformation sequences from left or right, partially apply arguments with `curry`, and thread a value through a series of functions.
|
|
214
|
-
|
|
215
|
-
```python
|
|
216
|
-
from humpy_toolz import compose_left, curry, pipe
|
|
217
|
-
|
|
218
|
-
increment = lambda x: x + 1
|
|
219
|
-
double = lambda x: x * 2
|
|
220
|
-
transform = compose_left(increment, double)
|
|
221
|
-
transform(3) # 8
|
|
222
|
-
|
|
223
|
-
pipe(3, increment, double) # 8
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### Slice, Group, and Deduplicate Iterators
|
|
227
|
-
|
|
228
|
-
Lazy operations over iterables: `take`, `drop`, `partition`, `sliding_window`, `unique`, `interleave`, `groupby`, `frequencies`, and more.
|
|
229
|
-
|
|
230
|
-
```python
|
|
231
|
-
from humpy_toolz import take, frequencies, groupby, unique
|
|
232
|
-
|
|
233
|
-
list(take(3, range(100))) # [0, 1, 2]
|
|
234
|
-
frequencies(["a", "b", "a", "c"]) # {"a": 2, "b": 1, "c": 1}
|
|
235
|
-
groupby(len, ["cat", "mouse", "dog"]) # {3: ["cat", "dog"], 5: ["mouse"]}
|
|
236
|
-
list(unique([1, 2, 1, 3])) # [1, 2, 3]
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### Curried Namespace for Partial Application
|
|
240
|
-
|
|
241
|
-
Every function in `humpy_toolz.curried` accepts partial arguments and returns a new callable waiting for the rest.
|
|
242
|
-
|
|
243
|
-
```python
|
|
244
|
-
from humpy_toolz.curried import map, filter, get
|
|
245
|
-
|
|
246
|
-
list(map(str.upper, ["hello", "world"])) # ["HELLO", "WORLD"]
|
|
247
|
-
list(filter(lambda x: x > 2, [1, 2, 3, 4])) # [3, 4]
|
|
248
|
-
list(map(get(0), [(1, 2), (3, 4)])) # [1, 3]
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
### Sandbox: Parallel Fold and Equality-Based Hashing
|
|
252
|
-
|
|
253
|
-
`humpy_toolz.sandbox` provides `fold` for unordered parallel reductions and `EqualityHashKey` for hashing otherwise-unhashable types.
|
|
254
|
-
|
|
255
|
-
```python
|
|
256
|
-
from humpy_toolz.sandbox import fold, EqualityHashKey
|
|
257
|
-
from operator import add
|
|
258
|
-
|
|
259
|
-
fold(add, range(100), default=0) # 4950
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
---
|
|
263
|
-
|
|
264
|
-
## `humpy_cytoolz`: Cython-Accelerated Functional Utilities
|
|
265
|
-
|
|
266
|
-
`humpy_cytoolz` is a typed fork of [`cytoolz`](https://github.com/pytoolz/cytoolz). It exposes the same API as `humpy_toolz` but the core modules (`dicttoolz`, `functoolz`, `itertoolz`, `recipes`, `utils`) are compiled as Cython extension modules for lower overhead on hot paths.
|
|
267
|
-
|
|
268
|
-
```python
|
|
269
|
-
from humpy_cytoolz import groupby, curry, merge
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
Install with the `cython` build dependency to compile the extensions. If compilation is unavailable, use `humpy_toolz` directly.
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## `humpy_tlz`: Automatic Cython-or-Pure Dispatch
|
|
277
|
-
|
|
278
|
-
`humpy_tlz` mirrors the `humpy_toolz` API and imports from `humpy_cytoolz` when available, falling back to `humpy_toolz` otherwise. Use `humpy_tlz` in library code so callers benefit from Cython acceleration without requiring it.
|
|
279
|
-
|
|
280
|
-
```python
|
|
281
|
-
from humpy_tlz import pipe, curry, groupby
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
---
|
|
285
|
-
|
|
286
186
|
## My recovery
|
|
287
187
|
|
|
288
188
|
[](https://HunterThinks.com/support)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# hunterMakesPy
|
|
2
2
|
|
|
3
|
-
Utilities for converting mixed input to integers, calculating CPU limits, handling None values, importing code dynamically, and manipulating nested data.
|
|
3
|
+
Utilities for converting mixed input to integers, calculating CPU limits, handling None values, importing code dynamically, and manipulating nested data.
|
|
4
4
|
|
|
5
5
|
[](https://pypi.org/project/hunterMakesPy/)
|
|
6
6
|
|
|
@@ -79,7 +79,7 @@ Write to `"deep/nested/path/file.txt"` and parent directories are created automa
|
|
|
79
79
|
from hunterMakesPy.filesystemToolkit import writeStringToHere, writePython
|
|
80
80
|
|
|
81
81
|
writeStringToHere("content", "nested/dirs/file.txt") # Creates dirs
|
|
82
|
-
writePython(sourceCode, "output/module.py")
|
|
82
|
+
writePython(sourceCode, "output/module.py") # Formats, then writes
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
## Extract Strings from Arbitrarily Nested Data
|
|
@@ -140,100 +140,6 @@ def test_my_integer_validator(test_name, test_func):
|
|
|
140
140
|
test_func()
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
## `humpy_toolz`: Typed Pure-Python Functional Utilities
|
|
146
|
-
|
|
147
|
-
`humpy_toolz` is a typed fork of [`toolz`](https://github.com/pytoolz/toolz). It provides composable functions for iterators, dictionaries, and function composition with full type stubs and docstrings.
|
|
148
|
-
|
|
149
|
-
### Dictionary Transformations without Mutation
|
|
150
|
-
|
|
151
|
-
Create new mappings by associating, dissociating, filtering, and mapping over keys or values. Nested access is supported through key-path sequences.
|
|
152
|
-
|
|
153
|
-
```python
|
|
154
|
-
from humpy_toolz import merge, valmap, keyfilter, assoc
|
|
155
|
-
|
|
156
|
-
merged = merge({"a": 1}, {"b": 2}) # {"a": 1, "b": 2}
|
|
157
|
-
doubled = valmap(lambda x: x * 2, {"a": 1}) # {"a": 2}
|
|
158
|
-
evens = keyfilter(lambda k: k > 1, {1: "a", 2: "b"}) # {2: "b"}
|
|
159
|
-
updated = assoc({"x": 10}, "y", 20) # {"x": 10, "y": 20}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Compose, Curry, and Thread Functions
|
|
163
|
-
|
|
164
|
-
Build transformation sequences from left or right, partially apply arguments with `curry`, and thread a value through a series of functions.
|
|
165
|
-
|
|
166
|
-
```python
|
|
167
|
-
from humpy_toolz import compose_left, curry, pipe
|
|
168
|
-
|
|
169
|
-
increment = lambda x: x + 1
|
|
170
|
-
double = lambda x: x * 2
|
|
171
|
-
transform = compose_left(increment, double)
|
|
172
|
-
transform(3) # 8
|
|
173
|
-
|
|
174
|
-
pipe(3, increment, double) # 8
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### Slice, Group, and Deduplicate Iterators
|
|
178
|
-
|
|
179
|
-
Lazy operations over iterables: `take`, `drop`, `partition`, `sliding_window`, `unique`, `interleave`, `groupby`, `frequencies`, and more.
|
|
180
|
-
|
|
181
|
-
```python
|
|
182
|
-
from humpy_toolz import take, frequencies, groupby, unique
|
|
183
|
-
|
|
184
|
-
list(take(3, range(100))) # [0, 1, 2]
|
|
185
|
-
frequencies(["a", "b", "a", "c"]) # {"a": 2, "b": 1, "c": 1}
|
|
186
|
-
groupby(len, ["cat", "mouse", "dog"]) # {3: ["cat", "dog"], 5: ["mouse"]}
|
|
187
|
-
list(unique([1, 2, 1, 3])) # [1, 2, 3]
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Curried Namespace for Partial Application
|
|
191
|
-
|
|
192
|
-
Every function in `humpy_toolz.curried` accepts partial arguments and returns a new callable waiting for the rest.
|
|
193
|
-
|
|
194
|
-
```python
|
|
195
|
-
from humpy_toolz.curried import map, filter, get
|
|
196
|
-
|
|
197
|
-
list(map(str.upper, ["hello", "world"])) # ["HELLO", "WORLD"]
|
|
198
|
-
list(filter(lambda x: x > 2, [1, 2, 3, 4])) # [3, 4]
|
|
199
|
-
list(map(get(0), [(1, 2), (3, 4)])) # [1, 3]
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Sandbox: Parallel Fold and Equality-Based Hashing
|
|
203
|
-
|
|
204
|
-
`humpy_toolz.sandbox` provides `fold` for unordered parallel reductions and `EqualityHashKey` for hashing otherwise-unhashable types.
|
|
205
|
-
|
|
206
|
-
```python
|
|
207
|
-
from humpy_toolz.sandbox import fold, EqualityHashKey
|
|
208
|
-
from operator import add
|
|
209
|
-
|
|
210
|
-
fold(add, range(100), default=0) # 4950
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
## `humpy_cytoolz`: Cython-Accelerated Functional Utilities
|
|
216
|
-
|
|
217
|
-
`humpy_cytoolz` is a typed fork of [`cytoolz`](https://github.com/pytoolz/cytoolz). It exposes the same API as `humpy_toolz` but the core modules (`dicttoolz`, `functoolz`, `itertoolz`, `recipes`, `utils`) are compiled as Cython extension modules for lower overhead on hot paths.
|
|
218
|
-
|
|
219
|
-
```python
|
|
220
|
-
from humpy_cytoolz import groupby, curry, merge
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
Install with the `cython` build dependency to compile the extensions. If compilation is unavailable, use `humpy_toolz` directly.
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
## `humpy_tlz`: Automatic Cython-or-Pure Dispatch
|
|
228
|
-
|
|
229
|
-
`humpy_tlz` mirrors the `humpy_toolz` API and imports from `humpy_cytoolz` when available, falling back to `humpy_toolz` otherwise. Use `humpy_tlz` in library code so callers benefit from Cython acceleration without requiring it.
|
|
230
|
-
|
|
231
|
-
```python
|
|
232
|
-
from humpy_tlz import pipe, curry, groupby
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
---
|
|
236
|
-
|
|
237
143
|
## My recovery
|
|
238
144
|
|
|
239
145
|
[](https://HunterThinks.com/support)
|
|
@@ -72,7 +72,7 @@ from hunterMakesPy.semiotics import decreasing as decreasing, errorL33T as error
|
|
|
72
72
|
|
|
73
73
|
# isort: split
|
|
74
74
|
from hunterMakesPy.theTypes import (
|
|
75
|
-
CallableFunction as CallableFunction, identifierDotAttribute as identifierDotAttribute, Ordinals as Ordinals)
|
|
75
|
+
CallableFunction as CallableFunction, identifierDotAttribute as identifierDotAttribute, Ordinals as Ordinals, 小于 as 小于)
|
|
76
76
|
|
|
77
77
|
# isort: split
|
|
78
78
|
from hunterMakesPy.coping import PackageSettings as PackageSettings, raiseIfNone as raiseIfNone
|
|
@@ -3,22 +3,23 @@ from __future__ import annotations
|
|
|
3
3
|
|
|
4
4
|
from importlib.util import find_spec
|
|
5
5
|
from pathlib import Path
|
|
6
|
-
from
|
|
6
|
+
from tomli import loads as tomli_loads
|
|
7
7
|
from typing import TYPE_CHECKING
|
|
8
|
+
from typing_extensions import TypeVar
|
|
8
9
|
import dataclasses
|
|
9
10
|
|
|
10
11
|
if TYPE_CHECKING:
|
|
11
12
|
from importlib.machinery import ModuleSpec
|
|
12
13
|
|
|
13
14
|
def getIdentifierPackagePACKAGING(identifierPackageFALLBACK: str) -> str:
|
|
14
|
-
"""Get package name from pyproject.toml or fallback to provided value."""
|
|
15
|
+
"""Get package name from pyproject.toml or fallback to provided value.""" # noqa: DOC201
|
|
15
16
|
try:
|
|
16
|
-
return
|
|
17
|
+
return tomli_loads(Path('pyproject.toml').read_text(encoding='utf-8'))['project']['name']
|
|
17
18
|
except Exception: # noqa: BLE001
|
|
18
19
|
return identifierPackageFALLBACK
|
|
19
20
|
|
|
20
21
|
def getPathPackageINSTALLING(identifierPackage: str) -> Path:
|
|
21
|
-
"""Return the root directory of the installed package."""
|
|
22
|
+
"""Return the root directory of the installed package.""" # noqa: DOC201
|
|
22
23
|
try:
|
|
23
24
|
moduleSpecification: ModuleSpec | None = find_spec(identifierPackage)
|
|
24
25
|
if moduleSpecification and moduleSpecification.origin:
|
|
@@ -85,7 +86,9 @@ class PackageSettings:
|
|
|
85
86
|
if self.pathPackage == Path() and self.identifierPackage:
|
|
86
87
|
self.pathPackage = getPathPackageINSTALLING(self.identifierPackage)
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
TypeSansNone = TypeVar('TypeSansNone')
|
|
90
|
+
|
|
91
|
+
def raiseIfNone(expression: TypeSansNone | None, errorMessage: str | None = None) -> TypeSansNone:
|
|
89
92
|
"""Convert the `expression` return annotation from '`cerPytainty | None`' to '`cerPytainty`' because `expression` cannot be `None`; `raise` an `Exception` if you're wrong.
|
|
90
93
|
|
|
91
94
|
The Python interpreter evaluates `expression` to a value: think of a function call or an attribute access. You can use
|
|
@@ -31,7 +31,6 @@ References
|
|
|
31
31
|
from __future__ import annotations
|
|
32
32
|
|
|
33
33
|
from charset_normalizer import CharsetMatch
|
|
34
|
-
from hunterMakesPy import Ordinals
|
|
35
34
|
from types import FunctionType
|
|
36
35
|
from typing import Any, cast, TYPE_CHECKING
|
|
37
36
|
import charset_normalizer
|
|
@@ -41,11 +40,12 @@ import sys
|
|
|
41
40
|
|
|
42
41
|
if TYPE_CHECKING:
|
|
43
42
|
from collections.abc import Iterator, Mapping
|
|
43
|
+
from hunterMakesPy import 小于
|
|
44
44
|
from numpy import integer
|
|
45
45
|
from numpy.typing import NDArray
|
|
46
46
|
|
|
47
47
|
def removeExtraWhitespace(string: str) -> str:
|
|
48
|
-
"""Remove extra whitespace from string representation of Python data structures."""
|
|
48
|
+
"""Remove extra whitespace from string representation of Python data structures.""" # noqa: DOC201
|
|
49
49
|
commas: str = regex.sub(r',\s+', ',', string)
|
|
50
50
|
bracketsOpening: str = regex.sub(r'([\[\(])\s+', r'\1', commas)
|
|
51
51
|
# Remove spaces before closing brackets/parentheses.
|
|
@@ -83,7 +83,7 @@ def autoDecodingRLE(arrayTarget: NDArray[integer[Any]], *, assumeAddSpaces: bool
|
|
|
83
83
|
"""
|
|
84
84
|
def sliceNDArrayToNestedLists(arraySlice: NDArray[integer[Any]]) -> Any:
|
|
85
85
|
def getLengthOption(optionAsStr: str) -> int:
|
|
86
|
-
"""`assumeAddSpaces` characters: `,` 1 space; `]*` 2 spaces."""
|
|
86
|
+
"""`assumeAddSpaces` characters: `,` 1 space; `]*` 2 spaces.""" # noqa: DOC201
|
|
87
87
|
return assumeAddSpaces * (optionAsStr.count(',') + optionAsStr.count(']*') * 2) + len(optionAsStr)
|
|
88
88
|
|
|
89
89
|
if 1 < arraySlice.ndim:
|
|
@@ -160,20 +160,20 @@ def autoDecodingRLE(arrayTarget: NDArray[integer[Any]], *, assumeAddSpaces: bool
|
|
|
160
160
|
arrayAsStr: str = removeExtraWhitespace(str(arrayAsNestedLists))
|
|
161
161
|
|
|
162
162
|
patternRegex: regex.Pattern[str] = regex.compile(
|
|
163
|
-
"(?<!rang)(?:"
|
|
164
|
-
# Pattern 1: Comma ahead, bracket behind
|
|
165
|
-
"(?P<joinAhead>,)
|
|
166
|
-
# Pattern 2: Bracket or start ahead, comma behind
|
|
167
|
-
"(?P<bracketOrStartAhead
|
|
168
|
-
# Pattern 3: Bracket ahead, bracket behind
|
|
169
|
-
"(?P<bracketAhead
|
|
170
|
-
# Pattern 4: Comma ahead, comma behind
|
|
171
|
-
"(?P<joinAheadJoinAhead>,)
|
|
172
|
-
")"
|
|
163
|
+
r"(?<!rang)(?:"
|
|
164
|
+
# Pattern 1: Comma ahead, bracket behind
|
|
165
|
+
r"(?P<joinAhead>,)\((?P<malkovich>\d+),(?P<multiply>\d+)\)(?P<bracketBehind>])|"
|
|
166
|
+
# Pattern 2: Bracket or start ahead, comma behind
|
|
167
|
+
r"(?P<bracketOrStartAhead>\[|^.)\((?P<malkovichMalkovich>\d+),(?P<multiplyIDK>\d+)\)(?P<joinBehind>,)|"
|
|
168
|
+
# Pattern 3: Bracket ahead, bracket behind
|
|
169
|
+
r"(?P<bracketAhead>\[)\((?P<malkovichMalkovichMalkovich>\d+),(?P<multiply_whatever>\d+)\)(?P<bracketBehindBracketBehind>])|"
|
|
170
|
+
# Pattern 4: Comma ahead, comma behind
|
|
171
|
+
r"(?P<joinAheadJoinAhead>,)\((?P<malkovichMalkovichMalkovichMalkovich>\d+),(?P<multiplyOrSomething>\d+)\)(?P<joinBehindJoinBehind>,)"
|
|
172
|
+
r")"
|
|
173
173
|
)
|
|
174
174
|
|
|
175
175
|
def replacementByContext(match: regex.Match[str]) -> str:
|
|
176
|
-
"""Generate replacement string based on context patterns."""
|
|
176
|
+
"""Generate replacement string based on context patterns.""" # noqa: DOC201
|
|
177
177
|
elephino: dict[str, str | None] = match.groupdict()
|
|
178
178
|
joinAhead: str | None = elephino.get('joinAhead') or elephino.get('joinAheadJoinAhead')
|
|
179
179
|
malkovich: str | None = elephino.get('malkovich') or elephino.get('malkovichMalkovich') or elephino.get('malkovichMalkovichMalkovich') or elephino.get('malkovichMalkovichMalkovichMalkovich')
|
|
@@ -189,7 +189,7 @@ def autoDecodingRLE(arrayTarget: NDArray[integer[Any]], *, assumeAddSpaces: bool
|
|
|
189
189
|
arrayAsStr = patternRegex.sub(replacementByContext, arrayAsStr)
|
|
190
190
|
arrayAsStr = patternRegex.sub(replacementByContext, arrayAsStr)
|
|
191
191
|
|
|
192
|
-
# Replace `range(0,stop)` syntax with `range(stop)` syntax.
|
|
192
|
+
# Replace `range(0,stop)` syntax with `range(stop)` syntax.
|
|
193
193
|
# Add unpack operator `*` for automatic decoding when evaluated.
|
|
194
194
|
return arrayAsStr.replace('range(0,', 'range(').replace('range', '*range')
|
|
195
195
|
|
|
@@ -232,14 +232,14 @@ def stringItUp(*scrapPile: Any) -> list[str]:
|
|
|
232
232
|
drill(broken)
|
|
233
233
|
drill(piece)
|
|
234
234
|
elif isinstance(KitKat, (list, tuple, set, frozenset, range)):
|
|
235
|
-
for kit in KitKat:
|
|
235
|
+
for kit in KitKat: # pyright: ignore[reportUnknownVariableType]
|
|
236
236
|
drill(kit)
|
|
237
237
|
elif hasattr(KitKat, '__iter__'): # Unpack other iterables
|
|
238
238
|
for kat in KitKat:
|
|
239
239
|
drill(kat)
|
|
240
240
|
else:
|
|
241
241
|
try:
|
|
242
|
-
sharingIsCaring: str = KitKat.__str__()
|
|
242
|
+
sharingIsCaring: str = KitKat.__str__() # noqa: PLC2801
|
|
243
243
|
listStrungUp.append(sharingIsCaring)
|
|
244
244
|
except AttributeError:
|
|
245
245
|
pass
|
|
@@ -256,7 +256,7 @@ def stringItUp(*scrapPile: Any) -> list[str]:
|
|
|
256
256
|
listStrungUp.append(repr(scrap))
|
|
257
257
|
return listStrungUp
|
|
258
258
|
|
|
259
|
-
def updateExtendPolishDictionaryLists
|
|
259
|
+
def updateExtendPolishDictionaryLists(*dictionaryLists: Mapping[str, list[小于] | set[小于] | tuple[小于, ...]], destroyDuplicates: bool = False, reorderLists: bool = False, killErroneousDataTypes: bool = False) -> dict[str, list[小于]]:
|
|
260
260
|
"""Merge multiple dictionaries with `list` values into a single dictionary with the `list` values merged.
|
|
261
261
|
|
|
262
262
|
Plus options to destroy duplicates, sort `list` values, and handle erroneous data types.
|
|
@@ -288,7 +288,7 @@ def updateExtendPolishDictionaryLists[小于: Ordinals](*dictionaryLists: Mappin
|
|
|
288
288
|
types will not be preserved. That could have unexpected consequences. Conversion from the
|
|
289
289
|
original data type to a `list`, for example, may not preserve the order even if you want the
|
|
290
290
|
order to be preserved.
|
|
291
|
-
"""
|
|
291
|
+
""" # noqa: DOC501
|
|
292
292
|
ePluribusUnum: dict[str, list[小于]] = {}
|
|
293
293
|
|
|
294
294
|
for dictionaryListTarget in dictionaryLists:
|
|
@@ -297,7 +297,7 @@ def updateExtendPolishDictionaryLists[小于: Ordinals](*dictionaryLists: Mappin
|
|
|
297
297
|
ImaStr = str(keyName)
|
|
298
298
|
ImaList: list[小于] = list(keyValue)
|
|
299
299
|
ePluribusUnum.setdefault(ImaStr, []).extend(ImaList)
|
|
300
|
-
except TypeError:
|
|
300
|
+
except TypeError: # noqa: PERF203
|
|
301
301
|
if killErroneousDataTypes:
|
|
302
302
|
continue
|
|
303
303
|
else:
|