hunterMakesPy 0.7.0__tar.gz → 0.7.2__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.7.0 → huntermakespy-0.7.2}/PKG-INFO +3 -4
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/dataStructures.py +33 -50
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/filesystemToolkit.py +72 -76
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/parseParameters.py +9 -11
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/tests/test_dataStructures.py +0 -1
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/theTypesCallableFunction.py +3 -2
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy.egg-info/PKG-INFO +3 -4
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy.egg-info/requires.txt +1 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/pyproject.toml +4 -11
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/LICENSE +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/README.md +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/__init__.py +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/_theSSOT.py +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/coping.py +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/py.typed +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/semiotics.py +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/tests/__init__.py +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/tests/conftest.py +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/tests/test_coping.py +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/tests/test_filesystemToolkit.py +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/tests/test_parseParameters.py +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/tests/test_theTypes.py +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy/theTypes.py +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy.egg-info/SOURCES.txt +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy.egg-info/dependency_links.txt +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/hunterMakesPy.egg-info/top_level.txt +0 -0
- {huntermakespy-0.7.0 → huntermakespy-0.7.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hunterMakesPy
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
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,13 +9,11 @@ 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:
|
|
12
|
+
Keywords: 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
|
|
16
16
|
Classifier: Intended Audience :: Developers
|
|
17
|
-
Classifier: Intended Audience :: End Users/Desktop
|
|
18
|
-
Classifier: Intended Audience :: Other Audience
|
|
19
17
|
Classifier: Natural Language :: English
|
|
20
18
|
Classifier: Operating System :: OS Independent
|
|
21
19
|
Classifier: Programming Language :: Python
|
|
@@ -27,6 +25,7 @@ Classifier: Typing :: Typed
|
|
|
27
25
|
Requires-Python: >=3.10
|
|
28
26
|
Description-Content-Type: text/markdown
|
|
29
27
|
License-File: LICENSE
|
|
28
|
+
Requires-Dist: Z0Z_tools>=2.2.1
|
|
30
29
|
Requires-Dist: autoflake
|
|
31
30
|
Requires-Dist: charset_normalizer
|
|
32
31
|
Requires-Dist: isort
|
|
@@ -1,38 +1,27 @@
|
|
|
1
1
|
"""Manipulate data structures with encoding, extraction, and merging utilities.
|
|
2
2
|
|
|
3
|
-
(
|
|
4
|
-
|
|
5
|
-
You can use this module to transform NumPy arrays [1] into compact run-length encoded
|
|
6
|
-
strings, extract strings from arbitrarily nested data structures, and merge multiple
|
|
7
|
-
dictionaries with list values. The module provides specialized utilities for working with
|
|
8
|
-
Cartesian mappings, heterogeneous nested data, and dictionary consolidation operations.
|
|
9
|
-
|
|
10
|
-
The run-length encoding function produces self-decoding string representations optimized for
|
|
11
|
-
large arrays with repetitive patterns. The string extraction function recursively traverses
|
|
12
|
-
nested structures to collect all convertible string values. The dictionary merging function
|
|
13
|
-
consolidates multiple dictionaries while offering optional deduplication and sorting.
|
|
3
|
+
You can use this module to transform arrays (in the general sense) into compact run-length encoded
|
|
4
|
+
strings, extract strings from arbitrarily nested data structures, or merge dictionaries of lists.
|
|
14
5
|
|
|
15
6
|
Contents
|
|
16
7
|
--------
|
|
17
8
|
Functions
|
|
18
9
|
autoDecodingRLE
|
|
19
|
-
Transform a NumPy array into a compact, self-decoding run-length encoded string
|
|
10
|
+
Transform a NumPy array into a compact, self-decoding run-length encoded string
|
|
11
|
+
representation.
|
|
20
12
|
stringItUp
|
|
21
13
|
Convert every element in input data structures to strings.
|
|
22
14
|
updateExtendPolishDictionaryLists
|
|
23
15
|
Merge multiple dictionaries with list values into a single dictionary.
|
|
24
|
-
|
|
25
|
-
References
|
|
26
|
-
----------
|
|
27
|
-
[1] NumPy - Context7
|
|
28
|
-
https://numpy.org/doc/stable/reference/index.html
|
|
29
|
-
|
|
30
16
|
"""
|
|
31
17
|
from __future__ import annotations
|
|
32
18
|
|
|
33
19
|
from charset_normalizer import CharsetMatch
|
|
20
|
+
from collections.abc import Hashable
|
|
21
|
+
from humpy_cytoolz.dicttoolz import valmap
|
|
22
|
+
from humpy_cytoolz.functoolz import compose
|
|
34
23
|
from types import FunctionType
|
|
35
|
-
from typing import
|
|
24
|
+
from typing import cast, TYPE_CHECKING, TypeVar
|
|
36
25
|
import charset_normalizer
|
|
37
26
|
import more_itertools
|
|
38
27
|
import re as regex
|
|
@@ -43,24 +32,23 @@ if TYPE_CHECKING:
|
|
|
43
32
|
from hunterMakesPy import 小于
|
|
44
33
|
from numpy import integer
|
|
45
34
|
from numpy.typing import NDArray
|
|
35
|
+
from typing import Any
|
|
46
36
|
|
|
47
37
|
def removeExtraWhitespace(string: str) -> str:
|
|
48
38
|
"""Remove extra whitespace from string representation of Python data structures.""" # noqa: DOC201
|
|
49
39
|
commas: str = regex.sub(r',\s+', ',', string)
|
|
50
40
|
bracketsOpening: str = regex.sub(r'([\[\(])\s+', r'\1', commas)
|
|
51
|
-
# Remove spaces before closing brackets/parentheses.
|
|
52
41
|
return regex.sub(r'\s+([\]\)])', r'\1', bracketsOpening)
|
|
53
42
|
|
|
54
43
|
def autoDecodingRLE(arrayTarget: NDArray[integer[Any]], *, assumeAddSpaces: bool = False) -> str:
|
|
55
44
|
"""Transform a NumPy array into a compact, self-decoding run-length encoded string representation.
|
|
56
45
|
|
|
57
46
|
Use this function to convert a NumPy array into a string that, when evaluated as Python code,
|
|
58
|
-
creates a list or nested lists representing the original array structure
|
|
59
|
-
|
|
60
|
-
Encoding) string does _not_ need a
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
2. Multiplication syntax for repeated elements.
|
|
47
|
+
creates a list or nested lists representing the original array structure. You can create a NumPy
|
|
48
|
+
array, torch Tensor, or other array-like object with the auto-decoded list of lists. The RLE
|
|
49
|
+
(Run-Length Encoding) string does _not_ need a decoder function: it is native Python syntax. The
|
|
50
|
+
function employs two encoding strategies: 1. Python `range` syntax for consecutive integer
|
|
51
|
+
sequences. 2. Multiplication syntax for repeated elements.
|
|
64
52
|
|
|
65
53
|
The resulting string representation is merely minified Python code, so it is space-efficient and,
|
|
66
54
|
hypothetically, human-readable.
|
|
@@ -71,9 +59,8 @@ def autoDecodingRLE(arrayTarget: NDArray[integer[Any]], *, assumeAddSpaces: bool
|
|
|
71
59
|
The NumPy array to be encoded.
|
|
72
60
|
assumeAddSpaces : bool = False
|
|
73
61
|
Affects internal length comparison during compression decisions. This parameter doesn't
|
|
74
|
-
directly change output
|
|
75
|
-
|
|
76
|
-
Tree) inserts spaces in the RLE string.
|
|
62
|
+
directly change the output: instead, use it to assume that something else will add spaces,
|
|
63
|
+
such as `ast.unparse()` (Abstract Syntax Tree) or a Python formatter.
|
|
77
64
|
|
|
78
65
|
Returns
|
|
79
66
|
-------
|
|
@@ -189,7 +176,7 @@ def autoDecodingRLE(arrayTarget: NDArray[integer[Any]], *, assumeAddSpaces: bool
|
|
|
189
176
|
arrayAsStr = patternRegex.sub(replacementByContext, arrayAsStr)
|
|
190
177
|
arrayAsStr = patternRegex.sub(replacementByContext, arrayAsStr)
|
|
191
178
|
|
|
192
|
-
#
|
|
179
|
+
# .replace `range(0,stop)` syntax with `range(stop)` syntax.
|
|
193
180
|
# Add unpack operator `*` for automatic decoding when evaluated.
|
|
194
181
|
return arrayAsStr.replace('range(0,', 'range(').replace('range', '*range')
|
|
195
182
|
|
|
@@ -207,7 +194,6 @@ def stringItUp(*scrapPile: Any) -> list[str]:
|
|
|
207
194
|
-------
|
|
208
195
|
listStrungUp : list[str]
|
|
209
196
|
(list2strung2up) A `list` of string versions of all convertible elements.
|
|
210
|
-
|
|
211
197
|
"""
|
|
212
198
|
scrap: Any = None
|
|
213
199
|
listStrungUp: list[str] = []
|
|
@@ -256,14 +242,17 @@ def stringItUp(*scrapPile: Any) -> list[str]:
|
|
|
256
242
|
listStrungUp.append(repr(scrap))
|
|
257
243
|
return listStrungUp
|
|
258
244
|
|
|
259
|
-
|
|
245
|
+
文件 = TypeVar('文件', bound=Hashable)
|
|
246
|
+
|
|
247
|
+
# TODO if `reorderLists: bool = False`, the elements do not need to be ordinals, and they should be covariant.
|
|
248
|
+
def updateExtendPolishDictionaryLists(*dictionaryLists: Mapping[文件, list[小于] | set[小于] | tuple[小于, ...]], destroyDuplicates: bool = False, reorderLists: bool = False, killErroneousDataTypes: bool = False) -> dict[文件, list[小于]]:
|
|
260
249
|
"""Merge multiple dictionaries with `list` values into a single dictionary with the `list` values merged.
|
|
261
250
|
|
|
262
251
|
Plus options to destroy duplicates, sort `list` values, and handle erroneous data types.
|
|
263
252
|
|
|
264
253
|
Parameters
|
|
265
254
|
----------
|
|
266
|
-
*dictionaryLists :
|
|
255
|
+
*dictionaryLists : MutableMapping[文件, list[Any] | set[Any] | tuple[Any, ...]]
|
|
267
256
|
Variable number of dictionaries to be merged. If only one dictionary is passed, it will be
|
|
268
257
|
"polished".
|
|
269
258
|
destroyDuplicates : bool = False
|
|
@@ -277,37 +266,31 @@ def updateExtendPolishDictionaryLists(*dictionaryLists: Mapping[str, list[小于
|
|
|
277
266
|
|
|
278
267
|
Returns
|
|
279
268
|
-------
|
|
280
|
-
ePluribusUnum : dict[
|
|
269
|
+
ePluribusUnum : dict[文件, list[Any]]
|
|
281
270
|
A single dictionary with merged and optionally "polished" `list` values.
|
|
282
271
|
|
|
283
272
|
Notes
|
|
284
273
|
-----
|
|
285
|
-
The returned value, `ePluribusUnum`, is a
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
original data type to a `list`, for example, may not preserve the order even if you want the
|
|
290
|
-
order to be preserved.
|
|
274
|
+
The returned value, `ePluribusUnum`, is a dictionary (`dict`). Furthermore, every dictionary value
|
|
275
|
+
is a `list`. If `dictionaryLists` has values that are not data type `list`, the data type will not
|
|
276
|
+
be preserved. That could have unexpected consequences. Conversion from the original data type to a
|
|
277
|
+
`list`, for example, may not preserve the order even if you want the order to be preserved.
|
|
291
278
|
""" # noqa: DOC501
|
|
292
|
-
ePluribusUnum: dict[
|
|
279
|
+
ePluribusUnum: dict[文件, list[小于]] = {}
|
|
293
280
|
|
|
294
281
|
for dictionaryListTarget in dictionaryLists:
|
|
295
282
|
for keyName, keyValue in dictionaryListTarget.items():
|
|
296
283
|
try:
|
|
297
|
-
ImaStr = str(keyName)
|
|
298
284
|
ImaList: list[小于] = list(keyValue)
|
|
299
|
-
ePluribusUnum.setdefault(
|
|
300
|
-
except TypeError: # noqa: PERF203
|
|
285
|
+
ePluribusUnum.setdefault(keyName, []).extend(ImaList)
|
|
286
|
+
except TypeError as error: # noqa: PERF203
|
|
301
287
|
if killErroneousDataTypes:
|
|
302
288
|
continue
|
|
303
|
-
|
|
304
|
-
raise
|
|
289
|
+
raise TypeError from error
|
|
305
290
|
|
|
306
291
|
if destroyDuplicates:
|
|
307
|
-
|
|
308
|
-
ePluribusUnum[ImaStr] = list(dict.fromkeys(ImaList))
|
|
292
|
+
ePluribusUnum = valmap(compose(list, dict.fromkeys), ePluribusUnum)
|
|
309
293
|
if reorderLists:
|
|
310
|
-
|
|
311
|
-
ePluribusUnum[ImaStr] = sorted(ImaRichComparisonSupporter)
|
|
294
|
+
ePluribusUnum = valmap(sorted, ePluribusUnum)
|
|
312
295
|
|
|
313
296
|
return ePluribusUnum
|
|
@@ -2,64 +2,65 @@
|
|
|
2
2
|
|
|
3
3
|
(AI generated docstring)
|
|
4
4
|
|
|
5
|
-
You can use this module to import `identifier` values from logical module paths or Python
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
You can use this module to import `identifier` values from logical module paths or Python files,
|
|
6
|
+
create parent directories for output paths, and write text or formatted Python source to files and
|
|
7
|
+
text streams. The writing functions can normalize Python imports with `autoflake` [1] and `isort` [2]
|
|
8
|
+
before the destination receives the final text.
|
|
9
9
|
|
|
10
10
|
Contents
|
|
11
11
|
--------
|
|
12
12
|
Functions
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
13
|
+
importLogicalPath2Identifier
|
|
14
|
+
Import `identifier` from the module named by `logicalPathModule`.
|
|
15
|
+
importPathFilename2Identifier
|
|
16
|
+
Import `identifier` from the Python file at `pathFilename`.
|
|
17
|
+
makeDirectorySafely
|
|
18
|
+
Create parent directories for `pathFilename` when `pathFilename` is a filesystem path.
|
|
19
|
+
makeDirsSafely
|
|
20
|
+
Temporary alias for `makeDirectorySafely`.
|
|
21
|
+
writePython
|
|
22
|
+
Format `pythonSource` and write `pythonSource` to `pathFilename`.
|
|
23
|
+
writeStringToHere
|
|
24
|
+
Write `this` to `pathFilename`.
|
|
25
25
|
|
|
26
26
|
Variables
|
|
27
27
|
---------
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
settings_autoflakeDEFAULT
|
|
29
|
+
Default settings dictionary for Python source cleanup.
|
|
30
|
+
settings_isortDEFAULT
|
|
31
|
+
Default settings dictionary for Python import sorting.
|
|
32
32
|
|
|
33
33
|
References
|
|
34
34
|
----------
|
|
35
35
|
[1] autoflake
|
|
36
|
-
|
|
36
|
+
https://github.com/PyCQA/autoflake
|
|
37
37
|
[2] isort
|
|
38
|
-
|
|
38
|
+
https://pycqa.github.io/isort/
|
|
39
39
|
"""
|
|
40
40
|
from __future__ import annotations
|
|
41
41
|
|
|
42
42
|
from autoflake import fix_code as autoflake_fix_code
|
|
43
|
+
from io import IOBase, TextIOBase
|
|
43
44
|
from isort import code as isort_code
|
|
44
45
|
from pathlib import Path, PurePath
|
|
45
|
-
from typing import
|
|
46
|
+
from typing import overload, TYPE_CHECKING
|
|
46
47
|
import contextlib
|
|
47
48
|
import importlib
|
|
48
49
|
import importlib.util
|
|
49
|
-
import io
|
|
50
50
|
|
|
51
51
|
if TYPE_CHECKING:
|
|
52
52
|
from hunterMakesPy import identifierDotAttribute
|
|
53
53
|
from importlib.machinery import ModuleSpec
|
|
54
54
|
from os import PathLike
|
|
55
55
|
from types import ModuleType
|
|
56
|
+
from typing import Any
|
|
56
57
|
|
|
57
58
|
def importLogicalPath2Identifier(logicalPathModule: identifierDotAttribute, identifier: str, packageIdentifierIfRelative: str | None = None) -> Any:
|
|
58
59
|
"""Import `identifier` from the module named by `logicalPathModule`.
|
|
59
60
|
|
|
60
|
-
You can use this function to resolve a function, class, or other attribute from a module
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
You can use this function to resolve a function, class, or other attribute from a module path
|
|
62
|
+
string. This function imports `logicalPathModule` with `importlib.import_module` [1] and returns
|
|
63
|
+
the attribute selected by `identifier`.
|
|
63
64
|
|
|
64
65
|
Parameters
|
|
65
66
|
----------
|
|
@@ -83,8 +84,8 @@ def importLogicalPath2Identifier(logicalPathModule: identifierDotAttribute, iden
|
|
|
83
84
|
def importPathFilename2Identifier(pathFilename: PathLike[Any] | PurePath, identifier: str, moduleIdentifier: str | None = None) -> Any:
|
|
84
85
|
"""Import `identifier` from the Python file at `pathFilename`.
|
|
85
86
|
|
|
86
|
-
You can use this function to load a Python source file as a module and retrieve a named
|
|
87
|
-
|
|
87
|
+
You can use this function to load a Python source file as a module and retrieve a named attribute
|
|
88
|
+
from that module. This function builds a module specification with
|
|
88
89
|
`importlib.util.spec_from_file_location` [1], executes the loaded module with
|
|
89
90
|
`importlib.util.module_from_spec` [2], and returns the attribute selected by `identifier`.
|
|
90
91
|
|
|
@@ -134,79 +135,78 @@ def makeDirectorySafely(pathFilename: Any) -> None:
|
|
|
134
135
|
|
|
135
136
|
You can use this function to prepare an output location before a later write operation. This
|
|
136
137
|
function ignores `OSError` from `Path.mkdir` [1] and does nothing when `pathFilename` is an
|
|
137
|
-
`
|
|
138
|
+
`IOBase` [2] stream.
|
|
138
139
|
|
|
139
140
|
Parameters
|
|
140
141
|
----------
|
|
141
142
|
pathFilename : Any
|
|
142
|
-
The target path or open stream. When `pathFilename` is not an `
|
|
143
|
+
The target path or open stream. When `pathFilename` is not an `IOBase` instance, the
|
|
143
144
|
function creates the parent directory of `pathFilename`.
|
|
144
145
|
|
|
145
146
|
References
|
|
146
147
|
----------
|
|
147
148
|
[1] `pathlib.Path.mkdir`
|
|
148
149
|
https://docs.python.org/3/library/pathlib.html#pathlib.Path.mkdir
|
|
149
|
-
[2] `
|
|
150
|
+
[2] `IOBase`
|
|
150
151
|
https://docs.python.org/3/library/io.html#io.IOBase
|
|
151
152
|
"""
|
|
152
|
-
if not isinstance(pathFilename,
|
|
153
|
+
if not isinstance(pathFilename, IOBase):
|
|
153
154
|
with contextlib.suppress(OSError):
|
|
154
155
|
Path(pathFilename).parent.mkdir(parents=True, exist_ok=True)
|
|
155
156
|
makeDirsSafely = makeDirectorySafely
|
|
156
157
|
"""Alias for `makeDirectorySafely`."""
|
|
157
158
|
|
|
158
159
|
settings_autoflakeDEFAULT: dict[str, list[str] | bool] = {
|
|
159
|
-
'additional_imports': []
|
|
160
|
-
'expand_star_imports': True
|
|
161
|
-
'remove_all_unused_imports': True
|
|
162
|
-
'remove_duplicate_keys': False
|
|
163
|
-
'remove_unused_variables': False
|
|
160
|
+
'additional_imports': []
|
|
161
|
+
, 'expand_star_imports': True
|
|
162
|
+
, 'remove_all_unused_imports': True
|
|
163
|
+
, 'remove_duplicate_keys': False
|
|
164
|
+
, 'remove_unused_variables': False
|
|
164
165
|
}
|
|
165
166
|
"""Default settings dictionary for Python source cleanup."""
|
|
166
167
|
|
|
167
168
|
settings_isortDEFAULT: dict[str, bool | int | str | list[str]] = {
|
|
168
|
-
"combine_as_imports": True
|
|
169
|
-
"force_alphabetical_sort_within_sections": True
|
|
170
|
-
"from_first": True
|
|
171
|
-
"honor_noqa": True
|
|
172
|
-
"indent": "\t"
|
|
173
|
-
"line_length": 140
|
|
174
|
-
"lines_after_imports": 1
|
|
175
|
-
"lines_between_types": 0
|
|
176
|
-
"multi_line_output": 4
|
|
177
|
-
"no_sections": True
|
|
178
|
-
"use_parentheses": True
|
|
169
|
+
"combine_as_imports": True
|
|
170
|
+
, "force_alphabetical_sort_within_sections": True
|
|
171
|
+
, "from_first": True
|
|
172
|
+
, "honor_noqa": True
|
|
173
|
+
, "indent": "\t"
|
|
174
|
+
, "line_length": 140
|
|
175
|
+
, "lines_after_imports": 1
|
|
176
|
+
, "lines_between_types": 0
|
|
177
|
+
, "multi_line_output": 4
|
|
178
|
+
, "no_sections": True
|
|
179
|
+
, "use_parentheses": True
|
|
179
180
|
}
|
|
180
181
|
"""Default settings dictionary for Python import sorting."""
|
|
181
182
|
|
|
182
183
|
@overload
|
|
183
184
|
def writePython(pythonSource: str, pathFilename: PathLike[Any] | PurePath, settings: dict[str, dict[str, Any]] | None = None) -> Path: ...
|
|
184
185
|
@overload
|
|
185
|
-
def writePython(pythonSource: str, pathFilename:
|
|
186
|
-
def writePython(pythonSource: str, pathFilename: PathLike[Any] | PurePath |
|
|
186
|
+
def writePython(pythonSource: str, pathFilename: TextIOBase, settings: dict[str, dict[str, Any]] | None = None) -> TextIOBase: ...
|
|
187
|
+
def writePython(pythonSource: str, pathFilename: PathLike[Any] | PurePath | TextIOBase, settings: dict[str, dict[str, Any]] | None = None) -> Path | TextIOBase:
|
|
187
188
|
"""Format and write Python source code to a file or text stream.
|
|
188
189
|
|
|
189
190
|
(AI generated docstring)
|
|
190
191
|
|
|
191
|
-
You can use this function to normalize Python imports and then send the resulting source
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
`pathFilename`.
|
|
192
|
+
You can use this function to normalize Python imports and then send the resulting source code to a
|
|
193
|
+
file path or open text stream. This function applies `autoflake` [1] first, applies `isort` [2]
|
|
194
|
+
second, appends a trailing newline, and writes the final text to `pathFilename`.
|
|
195
195
|
|
|
196
196
|
Parameters
|
|
197
197
|
----------
|
|
198
198
|
pythonSource : str
|
|
199
199
|
The Python source code to format and write.
|
|
200
|
-
pathFilename : PathLike[Any] | PurePath |
|
|
200
|
+
pathFilename : PathLike[Any] | PurePath | TextIOBase
|
|
201
201
|
The target destination. `pathFilename` can be a filesystem path or an open text stream.
|
|
202
202
|
settings : dict[str, dict[str, Any]] | None = None
|
|
203
|
-
Formatter configuration. The `'autoflake'` key overrides `settings_autoflakeDEFAULT`.
|
|
204
|
-
|
|
205
|
-
|
|
203
|
+
Formatter configuration. The `'autoflake'` key overrides `settings_autoflakeDEFAULT`. The
|
|
204
|
+
`'isort'` key overrides `settings_isortDEFAULT`. `None` uses the default settings for each
|
|
205
|
+
formatter.
|
|
206
206
|
|
|
207
207
|
Returns
|
|
208
208
|
-------
|
|
209
|
-
destinationWritten : Path |
|
|
209
|
+
destinationWritten : Path | TextIOBase
|
|
210
210
|
The file path or text stream that received the formatted source code.
|
|
211
211
|
|
|
212
212
|
See Also
|
|
@@ -235,26 +235,24 @@ def writePython(pythonSource: str, pathFilename: PathLike[Any] | PurePath | io.T
|
|
|
235
235
|
@overload
|
|
236
236
|
def writeStringToHere(this: str, pathFilename: PathLike[Any] | PurePath) -> Path: ...
|
|
237
237
|
@overload
|
|
238
|
-
def writeStringToHere(this: str, pathFilename:
|
|
239
|
-
def writeStringToHere(this: str, pathFilename: PathLike[Any] | PurePath |
|
|
238
|
+
def writeStringToHere(this: str, pathFilename: TextIOBase) -> TextIOBase: ...
|
|
239
|
+
def writeStringToHere(this: str, pathFilename: PathLike[Any] | PurePath | TextIOBase) -> Path | TextIOBase:
|
|
240
240
|
"""Write `this` to `pathFilename`.
|
|
241
241
|
|
|
242
|
-
You can use this function to send text to a filesystem path or an open text stream. This
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
package-assimilation code in `hunterMakesPy.assimilate.chopShop.transformPackages` [3] uses
|
|
246
|
-
this function to persist transformed source files.
|
|
242
|
+
You can use this function to send text to a filesystem path or an open text stream. This function
|
|
243
|
+
creates the parent directory when `pathFilename` is path-like, writes UTF-8 text with
|
|
244
|
+
`Path.write_text` [1], or writes and flushes a `TextIOBase` [2] stream.
|
|
247
245
|
|
|
248
246
|
Parameters
|
|
249
247
|
----------
|
|
250
248
|
this : str
|
|
251
249
|
The string content to write.
|
|
252
|
-
pathFilename : PathLike[Any] | PurePath |
|
|
250
|
+
pathFilename : PathLike[Any] | PurePath | TextIOBase
|
|
253
251
|
The target destination. `pathFilename` can be a filesystem path or an open text stream.
|
|
254
252
|
|
|
255
253
|
Returns
|
|
256
254
|
-------
|
|
257
|
-
destinationWritten : Path |
|
|
255
|
+
destinationWritten : Path | TextIOBase
|
|
258
256
|
The file path or text stream that received `this`.
|
|
259
257
|
|
|
260
258
|
See Also
|
|
@@ -266,12 +264,11 @@ def writeStringToHere(this: str, pathFilename: PathLike[Any] | PurePath | io.Tex
|
|
|
266
264
|
--------
|
|
267
265
|
The package-assimilation code writes transformed source text to a destination package path.
|
|
268
266
|
|
|
269
|
-
```python
|
|
270
|
-
from hunterMakesPy.filesystemToolkit import writeStringToHere
|
|
267
|
+
```python from hunterMakesPy.filesystemToolkit import writeStringToHere
|
|
271
268
|
|
|
272
269
|
writeStringToHere(
|
|
273
|
-
regexChangeImports(pathFilename.read_text()),
|
|
274
|
-
|
|
270
|
+
regexChangeImports(pathFilename.read_text()), settingsFor[humpyPackage].pathPackage /
|
|
271
|
+
pathFilename.relative_to(pathTransformee)
|
|
275
272
|
)
|
|
276
273
|
```
|
|
277
274
|
|
|
@@ -279,11 +276,10 @@ def writeStringToHere(this: str, pathFilename: PathLike[Any] | PurePath | io.Tex
|
|
|
279
276
|
----------
|
|
280
277
|
[1] `pathlib.Path.write_text`
|
|
281
278
|
https://docs.python.org/3/library/pathlib.html#pathlib.Path.write_text
|
|
282
|
-
[2] `
|
|
279
|
+
[2] `TextIOBase`
|
|
283
280
|
https://docs.python.org/3/library/io.html#io.TextIOBase
|
|
284
|
-
[3] `hunterMakesPy.assimilate.chopShop.transformPackages`
|
|
285
281
|
"""
|
|
286
|
-
if isinstance(pathFilename,
|
|
282
|
+
if isinstance(pathFilename, TextIOBase):
|
|
287
283
|
pathFilename.write(str(this))
|
|
288
284
|
pathFilename.flush()
|
|
289
285
|
else:
|
|
@@ -37,12 +37,14 @@ from __future__ import annotations
|
|
|
37
37
|
|
|
38
38
|
from collections.abc import Iterable, Sized
|
|
39
39
|
from dataclasses import dataclass
|
|
40
|
-
from typing import
|
|
40
|
+
from typing import TYPE_CHECKING
|
|
41
41
|
import charset_normalizer
|
|
42
42
|
import multiprocessing
|
|
43
|
+
import sys
|
|
43
44
|
|
|
44
45
|
if TYPE_CHECKING:
|
|
45
46
|
from charset_normalizer.models import CharsetMatch
|
|
47
|
+
from typing import Any
|
|
46
48
|
|
|
47
49
|
@dataclass
|
|
48
50
|
class ErrorMessageContext:
|
|
@@ -114,13 +116,6 @@ def _constructErrorMessage(context: ErrorMessageContext, parameterName: str, par
|
|
|
114
116
|
|
|
115
117
|
return "".join(messageParts)
|
|
116
118
|
|
|
117
|
-
# TODO Should I change the function because "On Windows, max_workers must be less than or equal to 61."?
|
|
118
|
-
# https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor
|
|
119
|
-
# autoflake
|
|
120
|
-
# if sys.platform == "win32":
|
|
121
|
-
# # Work around https://bugs.python.org/issue26903
|
|
122
|
-
# worker_count = min(worker_count, 60) # noqa: ERA001
|
|
123
|
-
|
|
124
119
|
def defineConcurrencyLimit(*, limit: bool | float | int | None, cpuTotal: int = multiprocessing.cpu_count()) -> int:
|
|
125
120
|
"""Determine the concurrency limit based on the provided parameter.
|
|
126
121
|
|
|
@@ -177,8 +172,6 @@ def defineConcurrencyLimit(*, limit: bool | float | int | None, cpuTotal: int =
|
|
|
177
172
|
```
|
|
178
173
|
|
|
179
174
|
""" # noqa: DOC501
|
|
180
|
-
concurrencyLimit: int = cpuTotal
|
|
181
|
-
|
|
182
175
|
if isinstance(limit, str):
|
|
183
176
|
limitFromString: bool | str | None = oopsieKwargsie(limit)
|
|
184
177
|
if isinstance(limitFromString, str):
|
|
@@ -191,7 +184,9 @@ def defineConcurrencyLimit(*, limit: bool | float | int | None, cpuTotal: int =
|
|
|
191
184
|
limit = limitFromString
|
|
192
185
|
if isinstance(limit, float) and 1 <= abs(limit):
|
|
193
186
|
limit = round(limit)
|
|
194
|
-
|
|
187
|
+
|
|
188
|
+
concurrencyLimit: int = cpuTotal
|
|
189
|
+
if (limit is None) or (limit is False) or (limit == 0):
|
|
195
190
|
pass
|
|
196
191
|
elif limit is True:
|
|
197
192
|
concurrencyLimit = 1
|
|
@@ -204,6 +199,9 @@ def defineConcurrencyLimit(*, limit: bool | float | int | None, cpuTotal: int =
|
|
|
204
199
|
elif limit <= -1:
|
|
205
200
|
concurrencyLimit = cpuTotal - abs(int(limit))
|
|
206
201
|
|
|
202
|
+
# https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor
|
|
203
|
+
if sys.platform == "win32":
|
|
204
|
+
concurrencyLimit = min(concurrencyLimit, 61)
|
|
207
205
|
return max(int(concurrencyLimit), 1)
|
|
208
206
|
|
|
209
207
|
# ruff: noqa: TRY301
|
|
@@ -108,7 +108,6 @@ def test_stringItUp(description: str, value_scrapPile: list[Any], expected: list
|
|
|
108
108
|
("Set values", ({'ne': {11, 13}, 'sw': {17}}, {'ne': {19, 23, 13, 29, 11}, 'sw': {31, 17, 37}}), {'destroyDuplicates': True, 'reorderLists': True}, {'ne': [11, 13, 19, 23, 29], 'sw': [17, 31, 37]}),
|
|
109
109
|
("NumPy arrays", ({'ne': numpy.array([11, 13]), 'sw': numpy.array([17])}, {'ne': numpy.array([19, 23, 13, 29, 11]), 'sw': numpy.array([31, 17, 37])}), {'destroyDuplicates': False, 'reorderLists': False}, {'ne': [11, 13, 19, 23, 13, 29, 11], 'sw': [17, 31, 17, 37]}),
|
|
110
110
|
("Destroy duplicates", ({'fr': [11, 13], 'jp': [17]}, {'fr': [19, 23, 13, 29, 11], 'jp': [31, 17, 37]}), {'destroyDuplicates': True, 'reorderLists': False}, {'fr': [11, 13, 19, 23, 29], 'jp': [17, 31, 37]}),
|
|
111
|
-
("Non-string keys", ({None: [13], True: [17]}, {19: [23], (29, 31): [37]}), {'destroyDuplicates': False, 'reorderLists': False}, {'None': [13], 'True': [17], '19': [23], '(29, 31)': [37]}),
|
|
112
111
|
("Reorder lists", ({'fr': [11, 13], 'jp': [17]}, {'fr': [19, 23, 13, 29, 11], 'jp': [31, 17, 37]}), {'destroyDuplicates': False, 'reorderLists': True}, {'fr': [11, 11, 13, 13, 19, 23, 29], 'jp': [17, 17, 31, 37]}),
|
|
113
112
|
("Non-iterable values", ({'ne': 13, 'sw': 17}, {'ne': 19, 'nw': 23}), {'destroyDuplicates': False, 'reorderLists': False}, TypeError),
|
|
114
113
|
("Skip erroneous types", ({'ne': [11, 13], 'sw': [17, 19]}, {'ne': 23, 'nw': 29}), {'killErroneousDataTypes': True}, {'ne': [11, 13], 'sw': [17, 19]}),
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
from collections.abc import Callable
|
|
5
|
-
from typing import Any, overload, ParamSpec, Protocol, runtime_checkable, TYPE_CHECKING,
|
|
6
|
-
from typing_extensions import Self, TypeVarTuple
|
|
5
|
+
from typing import Any, overload, ParamSpec, Protocol, runtime_checkable, TYPE_CHECKING, TypeVar
|
|
7
6
|
import sys
|
|
8
7
|
|
|
9
8
|
if TYPE_CHECKING:
|
|
10
9
|
from types import CodeType, MethodType
|
|
10
|
+
from typing import TypeAlias
|
|
11
|
+
from typing_extensions import Self, TypeVarTuple
|
|
11
12
|
|
|
12
13
|
# TODO explore the following
|
|
13
14
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hunterMakesPy
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
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,13 +9,11 @@ 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:
|
|
12
|
+
Keywords: 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
|
|
16
16
|
Classifier: Intended Audience :: Developers
|
|
17
|
-
Classifier: Intended Audience :: End Users/Desktop
|
|
18
|
-
Classifier: Intended Audience :: Other Audience
|
|
19
17
|
Classifier: Natural Language :: English
|
|
20
18
|
Classifier: Operating System :: OS Independent
|
|
21
19
|
Classifier: Programming Language :: Python
|
|
@@ -27,6 +25,7 @@ Classifier: Typing :: Typed
|
|
|
27
25
|
Requires-Python: >=3.10
|
|
28
26
|
Description-Content-Type: text/markdown
|
|
29
27
|
License-File: LICENSE
|
|
28
|
+
Requires-Dist: Z0Z_tools>=2.2.1
|
|
30
29
|
Requires-Dist: autoflake
|
|
31
30
|
Requires-Dist: charset_normalizer
|
|
32
31
|
Requires-Dist: isort
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "hunterMakesPy"
|
|
3
|
-
version = "0.7.
|
|
3
|
+
version = "0.7.2"
|
|
4
4
|
description = "Easy Python functions making making functional Python functions easier."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
7
7
|
license = "CC-BY-NC-4.0"
|
|
8
8
|
authors = [{ name = "Hunter Hogan", email = "HunterHogan@pm.me" }]
|
|
9
9
|
keywords = [
|
|
10
|
-
"attribute loading",
|
|
11
|
-
"configuration",
|
|
12
|
-
"defensive programming",
|
|
13
|
-
"dictionary merging",
|
|
14
|
-
"dynamic import",
|
|
15
|
-
"file system utilities",
|
|
16
10
|
"input validation",
|
|
17
11
|
"module loading",
|
|
18
12
|
"package settings",
|
|
@@ -23,8 +17,6 @@ classifiers = [
|
|
|
23
17
|
"Environment :: Console",
|
|
24
18
|
"Framework :: Pytest",
|
|
25
19
|
"Intended Audience :: Developers",
|
|
26
|
-
"Intended Audience :: End Users/Desktop",
|
|
27
|
-
"Intended Audience :: Other Audience",
|
|
28
20
|
"Natural Language :: English",
|
|
29
21
|
"Operating System :: OS Independent",
|
|
30
22
|
"Programming Language :: Python",
|
|
@@ -35,6 +27,7 @@ classifiers = [
|
|
|
35
27
|
"Typing :: Typed",
|
|
36
28
|
]
|
|
37
29
|
dependencies = [
|
|
30
|
+
"Z0Z_tools>=2.2.1",
|
|
38
31
|
"autoflake",
|
|
39
32
|
"charset_normalizer",
|
|
40
33
|
"isort",
|
|
@@ -45,7 +38,7 @@ dependencies = [
|
|
|
45
38
|
]
|
|
46
39
|
optional-dependencies = { development = ["pytest-cov"], testing = [
|
|
47
40
|
"librosa",
|
|
48
|
-
"pytest"
|
|
41
|
+
"pytest"
|
|
49
42
|
] }
|
|
50
43
|
|
|
51
44
|
[project.urls]
|
|
@@ -66,7 +59,7 @@ run = { branch = true, data_file = "hunterMakesPy/tests/coverage/.coverage", omi
|
|
|
66
59
|
], source = ["."] }
|
|
67
60
|
|
|
68
61
|
[tool.pytest]
|
|
69
|
-
addopts = ["--color=
|
|
62
|
+
addopts = ["--color=yes"]
|
|
70
63
|
log_auto_indent = "On"
|
|
71
64
|
testpaths = ["hunterMakesPy/tests"]
|
|
72
65
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|