hunterMakesPy 0.1.0__tar.gz → 0.1.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.
- huntermakespy-0.1.1/PKG-INFO +181 -0
- huntermakespy-0.1.1/README.md +135 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy/__init__.py +12 -2
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy/_theSSOT.py +1 -1
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy/dataStructures.py +10 -10
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy/filesystemToolkit.py +1 -2
- huntermakespy-0.1.1/hunterMakesPy.egg-info/PKG-INFO +181 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy.egg-info/SOURCES.txt +1 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/pyproject.toml +29 -5
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/tests/test_filesystemToolkit.py +1 -1
- huntermakespy-0.1.0/PKG-INFO +0 -38
- huntermakespy-0.1.0/hunterMakesPy.egg-info/PKG-INFO +0 -38
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/LICENSE +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy/coping.py +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy/parseParameters.py +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy/py.typed +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy/pytestForYourUse.py +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy/theTypes.py +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy.egg-info/dependency_links.txt +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy.egg-info/requires.txt +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/hunterMakesPy.egg-info/top_level.txt +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/setup.cfg +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/tests/__init__.py +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/tests/conftest.py +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/tests/test_coping.py +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/tests/test_dataStructures.py +0 -0
- {huntermakespy-0.1.0 → huntermakespy-0.1.1}/tests/test_parseParameters.py +0 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hunterMakesPy
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A modular Python toolkit for defensive programming, parameter validation, file system utilities, and flexible data structure manipulation. Provides helpers for error propagation, input validation, concurrency limits, safe directory creation, dynamic module loading, string extraction from nested structures, and dictionary merging.
|
|
5
|
+
Author-email: Hunter Hogan <HunterHogan@pm.me>
|
|
6
|
+
License: CC-BY-NC-4.0
|
|
7
|
+
Project-URL: Donate, https://www.patreon.com/integrated
|
|
8
|
+
Project-URL: Homepage, https://github.com/hunterhogan/
|
|
9
|
+
Project-URL: Issues, https://github.com/hunterhogan/
|
|
10
|
+
Project-URL: Repository, https://github.com/hunterhogan/
|
|
11
|
+
Keywords: defensive programming,parameter validation,input validation,error propagation,concurrency limit,integer parsing,file system utilities,directory creation,dynamic import,module loading,attribute loading,string extraction,nested data structures,dictionary merging,package settings,configuration,pytest,test utilities
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Framework :: Pytest
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
17
|
+
Classifier: Intended Audience :: Other Audience
|
|
18
|
+
Classifier: Natural Language :: English
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3
|
|
25
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
|
+
Classifier: Programming Language :: Python
|
|
27
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
28
|
+
Classifier: Topic :: Utilities
|
|
29
|
+
Classifier: Typing :: Typed
|
|
30
|
+
Requires-Python: >=3.10
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Requires-Dist: charset_normalizer
|
|
34
|
+
Requires-Dist: more_itertools
|
|
35
|
+
Requires-Dist: numpy
|
|
36
|
+
Requires-Dist: python_minifier
|
|
37
|
+
Requires-Dist: tomli
|
|
38
|
+
Provides-Extra: testing
|
|
39
|
+
Requires-Dist: mypy; extra == "testing"
|
|
40
|
+
Requires-Dist: pytest; extra == "testing"
|
|
41
|
+
Requires-Dist: pytest-cov; extra == "testing"
|
|
42
|
+
Requires-Dist: pytest-xdist; extra == "testing"
|
|
43
|
+
Requires-Dist: pyupgrade; extra == "testing"
|
|
44
|
+
Requires-Dist: setuptools-scm; extra == "testing"
|
|
45
|
+
Dynamic: license-file
|
|
46
|
+
|
|
47
|
+
# hunterMakesPy
|
|
48
|
+
|
|
49
|
+
A modular Python toolkit for defensive programming, parameter validation, file system utilities, and flexible data structure manipulation.
|
|
50
|
+
|
|
51
|
+
[](https://pypi.org/project/hunterMakesPy/)
|
|
52
|
+
|
|
53
|
+
## Overview
|
|
54
|
+
|
|
55
|
+
hunterMakesPy provides utilities for safe error handling, flexible input validation, dynamic module and attribute importing, and merging or transforming complex data structures. The package emphasizes clear identifiers, robust type handling, and reusable components for building reliable Python applications.
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install hunterMakesPy
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Defensive Programming
|
|
64
|
+
|
|
65
|
+
Utilities for handling `None` values and defensive programming patterns.
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from hunterMakesPy import raiseIfNone
|
|
69
|
+
|
|
70
|
+
# Ensure a function result is not None
|
|
71
|
+
def findConfiguration(configName: str) -> dict[str, str] | None:
|
|
72
|
+
# ... search logic ...
|
|
73
|
+
return None
|
|
74
|
+
|
|
75
|
+
config = raiseIfNone(
|
|
76
|
+
findConfiguration("database"),
|
|
77
|
+
"Configuration 'database' is required but not found"
|
|
78
|
+
)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Parameter Validation
|
|
82
|
+
|
|
83
|
+
Parameter validation, integer parsing, and concurrency handling.
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from hunterMakesPy import defineConcurrencyLimit, intInnit, oopsieKwargsie
|
|
87
|
+
|
|
88
|
+
# Smart concurrency limit calculation
|
|
89
|
+
cpuLimit = defineConcurrencyLimit(limit=0.75) # Use 75% of available CPUs
|
|
90
|
+
cpuLimit = defineConcurrencyLimit(limit=True) # Use exactly 1 CPU
|
|
91
|
+
cpuLimit = defineConcurrencyLimit(limit=4) # Use exactly 4 CPUs
|
|
92
|
+
|
|
93
|
+
# Robust integer validation
|
|
94
|
+
validatedIntegers = intInnit([1, "2", 3.0, "4"], "port_numbers")
|
|
95
|
+
|
|
96
|
+
# String-to-boolean conversion for configuration
|
|
97
|
+
userInput = "True"
|
|
98
|
+
booleanValue = oopsieKwargsie(userInput) # Returns True
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## File System Utilities
|
|
102
|
+
|
|
103
|
+
Safe file operations and dynamic module importing.
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from hunterMakesPy import (
|
|
107
|
+
importLogicalPath2Identifier,
|
|
108
|
+
importPathFilename2Identifier,
|
|
109
|
+
makeDirsSafely,
|
|
110
|
+
writeStringToHere
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Dynamic imports
|
|
114
|
+
gcdFunction = importLogicalPath2Identifier("math", "gcd")
|
|
115
|
+
customFunction = importPathFilename2Identifier("path/to/module.py", "functionName")
|
|
116
|
+
|
|
117
|
+
# Safe file operations
|
|
118
|
+
pathFilename = Path("deep/nested/directory/file.txt")
|
|
119
|
+
writeStringToHere("content", pathFilename) # Creates directories automatically
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Data Structure Manipulation
|
|
123
|
+
|
|
124
|
+
Utilities for string extraction, data flattening, and array compression.
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from hunterMakesPy import stringItUp, updateExtendPolishDictionaryLists, autoDecodingRLE
|
|
128
|
+
import numpy
|
|
129
|
+
|
|
130
|
+
# Extract all strings from nested data structures
|
|
131
|
+
nestedData = {"config": [1, "host", {"port": 8080}], "users": ["alice", "bob"]}
|
|
132
|
+
allStrings = stringItUp(nestedData) # ['config', 'host', 'port', 'users', 'alice', 'bob']
|
|
133
|
+
|
|
134
|
+
# Merge dictionaries containing lists
|
|
135
|
+
dictionaryAlpha = {"servers": ["web1", "web2"], "databases": ["db1"]}
|
|
136
|
+
dictionaryBeta = {"servers": ["web3"], "databases": ["db2", "db3"]}
|
|
137
|
+
merged = updateExtendPolishDictionaryLists(dictionaryAlpha, dictionaryBeta, destroyDuplicates=True)
|
|
138
|
+
|
|
139
|
+
# Compress NumPy arrays with run-length encoding
|
|
140
|
+
arrayData = numpy.array([1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 9])
|
|
141
|
+
compressed = autoDecodingRLE(arrayData) # "[1,*range(2,6)]+[5]*2+[*range(6,10)]"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Testing
|
|
145
|
+
|
|
146
|
+
The package includes comprehensive test suites that you can import and run:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from hunterMakesPy.pytestForYourUse import (
|
|
150
|
+
PytestFor_defineConcurrencyLimit,
|
|
151
|
+
PytestFor_intInnit,
|
|
152
|
+
PytestFor_oopsieKwargsie
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Run tests on the built-in functions
|
|
156
|
+
listOfTests = PytestFor_defineConcurrencyLimit()
|
|
157
|
+
for nameOfTest, callablePytest in listOfTests:
|
|
158
|
+
callablePytest()
|
|
159
|
+
|
|
160
|
+
# Or test your own compatible functions
|
|
161
|
+
@pytest.mark.parametrize("nameOfTest,callablePytest",
|
|
162
|
+
PytestFor_intInnit(callableToTest=myFunction))
|
|
163
|
+
def test_myFunction(nameOfTest, callablePytest):
|
|
164
|
+
callablePytest()
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## My recovery
|
|
168
|
+
|
|
169
|
+
[](https://HunterThinks.com/support)
|
|
170
|
+
[](https://www.youtube.com/@HunterHogan)
|
|
171
|
+
|
|
172
|
+
## How to code
|
|
173
|
+
|
|
174
|
+
Coding One Step at a Time:
|
|
175
|
+
|
|
176
|
+
0. WRITE CODE.
|
|
177
|
+
1. Don't write stupid code that's hard to revise.
|
|
178
|
+
2. Write good code.
|
|
179
|
+
3. When revising, write better code.
|
|
180
|
+
|
|
181
|
+
[](https://creativecommons.org/licenses/by-nc/4.0/)
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# hunterMakesPy
|
|
2
|
+
|
|
3
|
+
A modular Python toolkit for defensive programming, parameter validation, file system utilities, and flexible data structure manipulation.
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/hunterMakesPy/)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
hunterMakesPy provides utilities for safe error handling, flexible input validation, dynamic module and attribute importing, and merging or transforming complex data structures. The package emphasizes clear identifiers, robust type handling, and reusable components for building reliable Python applications.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install hunterMakesPy
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Defensive Programming
|
|
18
|
+
|
|
19
|
+
Utilities for handling `None` values and defensive programming patterns.
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from hunterMakesPy import raiseIfNone
|
|
23
|
+
|
|
24
|
+
# Ensure a function result is not None
|
|
25
|
+
def findConfiguration(configName: str) -> dict[str, str] | None:
|
|
26
|
+
# ... search logic ...
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
config = raiseIfNone(
|
|
30
|
+
findConfiguration("database"),
|
|
31
|
+
"Configuration 'database' is required but not found"
|
|
32
|
+
)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Parameter Validation
|
|
36
|
+
|
|
37
|
+
Parameter validation, integer parsing, and concurrency handling.
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from hunterMakesPy import defineConcurrencyLimit, intInnit, oopsieKwargsie
|
|
41
|
+
|
|
42
|
+
# Smart concurrency limit calculation
|
|
43
|
+
cpuLimit = defineConcurrencyLimit(limit=0.75) # Use 75% of available CPUs
|
|
44
|
+
cpuLimit = defineConcurrencyLimit(limit=True) # Use exactly 1 CPU
|
|
45
|
+
cpuLimit = defineConcurrencyLimit(limit=4) # Use exactly 4 CPUs
|
|
46
|
+
|
|
47
|
+
# Robust integer validation
|
|
48
|
+
validatedIntegers = intInnit([1, "2", 3.0, "4"], "port_numbers")
|
|
49
|
+
|
|
50
|
+
# String-to-boolean conversion for configuration
|
|
51
|
+
userInput = "True"
|
|
52
|
+
booleanValue = oopsieKwargsie(userInput) # Returns True
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## File System Utilities
|
|
56
|
+
|
|
57
|
+
Safe file operations and dynamic module importing.
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from hunterMakesPy import (
|
|
61
|
+
importLogicalPath2Identifier,
|
|
62
|
+
importPathFilename2Identifier,
|
|
63
|
+
makeDirsSafely,
|
|
64
|
+
writeStringToHere
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Dynamic imports
|
|
68
|
+
gcdFunction = importLogicalPath2Identifier("math", "gcd")
|
|
69
|
+
customFunction = importPathFilename2Identifier("path/to/module.py", "functionName")
|
|
70
|
+
|
|
71
|
+
# Safe file operations
|
|
72
|
+
pathFilename = Path("deep/nested/directory/file.txt")
|
|
73
|
+
writeStringToHere("content", pathFilename) # Creates directories automatically
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Data Structure Manipulation
|
|
77
|
+
|
|
78
|
+
Utilities for string extraction, data flattening, and array compression.
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from hunterMakesPy import stringItUp, updateExtendPolishDictionaryLists, autoDecodingRLE
|
|
82
|
+
import numpy
|
|
83
|
+
|
|
84
|
+
# Extract all strings from nested data structures
|
|
85
|
+
nestedData = {"config": [1, "host", {"port": 8080}], "users": ["alice", "bob"]}
|
|
86
|
+
allStrings = stringItUp(nestedData) # ['config', 'host', 'port', 'users', 'alice', 'bob']
|
|
87
|
+
|
|
88
|
+
# Merge dictionaries containing lists
|
|
89
|
+
dictionaryAlpha = {"servers": ["web1", "web2"], "databases": ["db1"]}
|
|
90
|
+
dictionaryBeta = {"servers": ["web3"], "databases": ["db2", "db3"]}
|
|
91
|
+
merged = updateExtendPolishDictionaryLists(dictionaryAlpha, dictionaryBeta, destroyDuplicates=True)
|
|
92
|
+
|
|
93
|
+
# Compress NumPy arrays with run-length encoding
|
|
94
|
+
arrayData = numpy.array([1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 9])
|
|
95
|
+
compressed = autoDecodingRLE(arrayData) # "[1,*range(2,6)]+[5]*2+[*range(6,10)]"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Testing
|
|
99
|
+
|
|
100
|
+
The package includes comprehensive test suites that you can import and run:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from hunterMakesPy.pytestForYourUse import (
|
|
104
|
+
PytestFor_defineConcurrencyLimit,
|
|
105
|
+
PytestFor_intInnit,
|
|
106
|
+
PytestFor_oopsieKwargsie
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
# Run tests on the built-in functions
|
|
110
|
+
listOfTests = PytestFor_defineConcurrencyLimit()
|
|
111
|
+
for nameOfTest, callablePytest in listOfTests:
|
|
112
|
+
callablePytest()
|
|
113
|
+
|
|
114
|
+
# Or test your own compatible functions
|
|
115
|
+
@pytest.mark.parametrize("nameOfTest,callablePytest",
|
|
116
|
+
PytestFor_intInnit(callableToTest=myFunction))
|
|
117
|
+
def test_myFunction(nameOfTest, callablePytest):
|
|
118
|
+
callablePytest()
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## My recovery
|
|
122
|
+
|
|
123
|
+
[](https://HunterThinks.com/support)
|
|
124
|
+
[](https://www.youtube.com/@HunterHogan)
|
|
125
|
+
|
|
126
|
+
## How to code
|
|
127
|
+
|
|
128
|
+
Coding One Step at a Time:
|
|
129
|
+
|
|
130
|
+
0. WRITE CODE.
|
|
131
|
+
1. Don't write stupid code that's hard to revise.
|
|
132
|
+
2. Write good code.
|
|
133
|
+
3. When revising, write better code.
|
|
134
|
+
|
|
135
|
+
[](https://creativecommons.org/licenses/by-nc/4.0/)
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""A modular toolkit for defensive programming, parameter validation, file system utilities, and data structure manipulation.
|
|
2
|
+
|
|
3
|
+
(AI generated docstring)
|
|
4
|
+
|
|
5
|
+
This package provides:
|
|
6
|
+
- Defensive programming helpers for handling `None` values and error propagation.
|
|
7
|
+
- Parameter and input validation, integer parsing, and concurrency limit utilities.
|
|
8
|
+
- File system and import utilities for safe directory creation and dynamic module/attribute loading.
|
|
9
|
+
- Utilities for string extraction from nested data structures and merging dictionaries of lists.
|
|
10
|
+
|
|
11
|
+
"""
|
|
2
12
|
from hunterMakesPy.theTypes import identifierDotAttribute as identifierDotAttribute
|
|
3
13
|
|
|
4
14
|
from hunterMakesPy.coping import raiseIfNone as raiseIfNone
|
|
@@ -8,7 +18,7 @@ from hunterMakesPy.parseParameters import (defineConcurrencyLimit as defineConcu
|
|
|
8
18
|
|
|
9
19
|
from hunterMakesPy.filesystemToolkit import (importLogicalPath2Identifier as importLogicalPath2Identifier,
|
|
10
20
|
importPathFilename2Identifier as importPathFilename2Identifier, makeDirsSafely as makeDirsSafely,
|
|
11
|
-
|
|
21
|
+
writeStringToHere as writeStringToHere)
|
|
12
22
|
|
|
13
23
|
from hunterMakesPy.dataStructures import (autoDecodingRLE as autoDecodingRLE, stringItUp as stringItUp,
|
|
14
24
|
updateExtendPolishDictionaryLists as updateExtendPolishDictionaryLists)
|
|
@@ -13,7 +13,7 @@ if TYPE_CHECKING:
|
|
|
13
13
|
from importlib.machinery import ModuleSpec
|
|
14
14
|
|
|
15
15
|
try:
|
|
16
|
-
identifierPackagePACKAGING: str = tomli_loads(Path("pyproject.toml").read_text())["project"]["name"]
|
|
16
|
+
identifierPackagePACKAGING: str = tomli_loads(Path("pyproject.toml").read_text(encoding="utf-8"))["project"]["name"]
|
|
17
17
|
except Exception: # noqa: BLE001
|
|
18
18
|
identifierPackagePACKAGING = "hunterMakesPy"
|
|
19
19
|
|
|
@@ -125,29 +125,29 @@ def autoDecodingRLE(arrayTarget: NDArray[integer[Any]], *, assumeAddSpaces: bool
|
|
|
125
125
|
patternRegex = regex.compile(
|
|
126
126
|
"(?<!rang)(?:"
|
|
127
127
|
# Pattern 1: Comma ahead, bracket behind # noqa: ERA001
|
|
128
|
-
"(?P<joinAhead>,)\\((?P<malkovich>\\d+),(?P<
|
|
128
|
+
"(?P<joinAhead>,)\\((?P<malkovich>\\d+),(?P<multiply>\\d+)\\)(?P<bracketBehind>])|"
|
|
129
129
|
# Pattern 2: Bracket or start ahead, comma behind # noqa: ERA001
|
|
130
|
-
"(?P<bracketOrStartAhead>\\[|^.)\\((?P<
|
|
130
|
+
"(?P<bracketOrStartAhead>\\[|^.)\\((?P<malkovichMalkovich>\\d+),(?P<multiplyIDK>\\d+)\\)(?P<joinBehind>,)|"
|
|
131
131
|
# Pattern 3: Bracket ahead, bracket behind # noqa: ERA001
|
|
132
|
-
"(?P<bracketAhead>\\[)\\((?P<
|
|
132
|
+
"(?P<bracketAhead>\\[)\\((?P<malkovichMalkovichMalkovich>\\d+),(?P<multiply_whatever>\\d+)\\)(?P<bracketBehindBracketBehind>])|"
|
|
133
133
|
# Pattern 4: Comma ahead, comma behind # noqa: ERA001
|
|
134
|
-
"(?P<
|
|
134
|
+
"(?P<joinAheadJoinAhead>,)\\((?P<malkovichMalkovichMalkovichMalkovich>\\d+),(?P<multiplyOrSomething>\\d+)\\)(?P<joinBehindJoinBehind>,)"
|
|
135
135
|
")"
|
|
136
136
|
)
|
|
137
137
|
|
|
138
138
|
def replacementByContext(match: regex.Match[str]) -> str:
|
|
139
139
|
"""Generate replacement string based on context patterns."""
|
|
140
|
-
|
|
141
|
-
joinAhead =
|
|
142
|
-
malkovich =
|
|
143
|
-
|
|
144
|
-
joinBehind =
|
|
140
|
+
elephino = match.groupdict()
|
|
141
|
+
joinAhead = elephino.get('joinAhead') or elephino.get('joinAheadJoinAhead')
|
|
142
|
+
malkovich = elephino.get('malkovich') or elephino.get('malkovichMalkovich') or elephino.get('malkovichMalkovichMalkovich') or elephino.get('malkovichMalkovichMalkovichMalkovich')
|
|
143
|
+
multiply = elephino.get('multiply') or elephino.get('multiplyIDK') or elephino.get('multiply_whatever') or elephino.get('multiplyOrSomething')
|
|
144
|
+
joinBehind = elephino.get('joinBehind') or elephino.get('joinBehindJoinBehind')
|
|
145
145
|
|
|
146
146
|
replaceAhead = "]+[" if joinAhead == "," else "["
|
|
147
147
|
|
|
148
148
|
replaceBehind = "+[" if joinBehind == "," else ""
|
|
149
149
|
|
|
150
|
-
return f"{replaceAhead}{malkovich}]*{
|
|
150
|
+
return f"{replaceAhead}{malkovich}]*{multiply}{replaceBehind}"
|
|
151
151
|
|
|
152
152
|
arrayAsStr = patternRegex.sub(replacementByContext, arrayAsStr)
|
|
153
153
|
arrayAsStr = patternRegex.sub(replacementByContext, arrayAsStr)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""File system and module import utilities.
|
|
2
2
|
|
|
3
|
-
This module provides basic file I/O utilities such as
|
|
4
|
-
callables from modules, and safely creating directories.
|
|
3
|
+
This module provides basic file I/O utilities such as importing callables from modules, and safely creating directories.
|
|
5
4
|
|
|
6
5
|
"""
|
|
7
6
|
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hunterMakesPy
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A modular Python toolkit for defensive programming, parameter validation, file system utilities, and flexible data structure manipulation. Provides helpers for error propagation, input validation, concurrency limits, safe directory creation, dynamic module loading, string extraction from nested structures, and dictionary merging.
|
|
5
|
+
Author-email: Hunter Hogan <HunterHogan@pm.me>
|
|
6
|
+
License: CC-BY-NC-4.0
|
|
7
|
+
Project-URL: Donate, https://www.patreon.com/integrated
|
|
8
|
+
Project-URL: Homepage, https://github.com/hunterhogan/
|
|
9
|
+
Project-URL: Issues, https://github.com/hunterhogan/
|
|
10
|
+
Project-URL: Repository, https://github.com/hunterhogan/
|
|
11
|
+
Keywords: defensive programming,parameter validation,input validation,error propagation,concurrency limit,integer parsing,file system utilities,directory creation,dynamic import,module loading,attribute loading,string extraction,nested data structures,dictionary merging,package settings,configuration,pytest,test utilities
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Framework :: Pytest
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
17
|
+
Classifier: Intended Audience :: Other Audience
|
|
18
|
+
Classifier: Natural Language :: English
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3
|
|
25
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
|
+
Classifier: Programming Language :: Python
|
|
27
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
28
|
+
Classifier: Topic :: Utilities
|
|
29
|
+
Classifier: Typing :: Typed
|
|
30
|
+
Requires-Python: >=3.10
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Requires-Dist: charset_normalizer
|
|
34
|
+
Requires-Dist: more_itertools
|
|
35
|
+
Requires-Dist: numpy
|
|
36
|
+
Requires-Dist: python_minifier
|
|
37
|
+
Requires-Dist: tomli
|
|
38
|
+
Provides-Extra: testing
|
|
39
|
+
Requires-Dist: mypy; extra == "testing"
|
|
40
|
+
Requires-Dist: pytest; extra == "testing"
|
|
41
|
+
Requires-Dist: pytest-cov; extra == "testing"
|
|
42
|
+
Requires-Dist: pytest-xdist; extra == "testing"
|
|
43
|
+
Requires-Dist: pyupgrade; extra == "testing"
|
|
44
|
+
Requires-Dist: setuptools-scm; extra == "testing"
|
|
45
|
+
Dynamic: license-file
|
|
46
|
+
|
|
47
|
+
# hunterMakesPy
|
|
48
|
+
|
|
49
|
+
A modular Python toolkit for defensive programming, parameter validation, file system utilities, and flexible data structure manipulation.
|
|
50
|
+
|
|
51
|
+
[](https://pypi.org/project/hunterMakesPy/)
|
|
52
|
+
|
|
53
|
+
## Overview
|
|
54
|
+
|
|
55
|
+
hunterMakesPy provides utilities for safe error handling, flexible input validation, dynamic module and attribute importing, and merging or transforming complex data structures. The package emphasizes clear identifiers, robust type handling, and reusable components for building reliable Python applications.
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install hunterMakesPy
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Defensive Programming
|
|
64
|
+
|
|
65
|
+
Utilities for handling `None` values and defensive programming patterns.
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from hunterMakesPy import raiseIfNone
|
|
69
|
+
|
|
70
|
+
# Ensure a function result is not None
|
|
71
|
+
def findConfiguration(configName: str) -> dict[str, str] | None:
|
|
72
|
+
# ... search logic ...
|
|
73
|
+
return None
|
|
74
|
+
|
|
75
|
+
config = raiseIfNone(
|
|
76
|
+
findConfiguration("database"),
|
|
77
|
+
"Configuration 'database' is required but not found"
|
|
78
|
+
)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Parameter Validation
|
|
82
|
+
|
|
83
|
+
Parameter validation, integer parsing, and concurrency handling.
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from hunterMakesPy import defineConcurrencyLimit, intInnit, oopsieKwargsie
|
|
87
|
+
|
|
88
|
+
# Smart concurrency limit calculation
|
|
89
|
+
cpuLimit = defineConcurrencyLimit(limit=0.75) # Use 75% of available CPUs
|
|
90
|
+
cpuLimit = defineConcurrencyLimit(limit=True) # Use exactly 1 CPU
|
|
91
|
+
cpuLimit = defineConcurrencyLimit(limit=4) # Use exactly 4 CPUs
|
|
92
|
+
|
|
93
|
+
# Robust integer validation
|
|
94
|
+
validatedIntegers = intInnit([1, "2", 3.0, "4"], "port_numbers")
|
|
95
|
+
|
|
96
|
+
# String-to-boolean conversion for configuration
|
|
97
|
+
userInput = "True"
|
|
98
|
+
booleanValue = oopsieKwargsie(userInput) # Returns True
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## File System Utilities
|
|
102
|
+
|
|
103
|
+
Safe file operations and dynamic module importing.
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from hunterMakesPy import (
|
|
107
|
+
importLogicalPath2Identifier,
|
|
108
|
+
importPathFilename2Identifier,
|
|
109
|
+
makeDirsSafely,
|
|
110
|
+
writeStringToHere
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Dynamic imports
|
|
114
|
+
gcdFunction = importLogicalPath2Identifier("math", "gcd")
|
|
115
|
+
customFunction = importPathFilename2Identifier("path/to/module.py", "functionName")
|
|
116
|
+
|
|
117
|
+
# Safe file operations
|
|
118
|
+
pathFilename = Path("deep/nested/directory/file.txt")
|
|
119
|
+
writeStringToHere("content", pathFilename) # Creates directories automatically
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Data Structure Manipulation
|
|
123
|
+
|
|
124
|
+
Utilities for string extraction, data flattening, and array compression.
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from hunterMakesPy import stringItUp, updateExtendPolishDictionaryLists, autoDecodingRLE
|
|
128
|
+
import numpy
|
|
129
|
+
|
|
130
|
+
# Extract all strings from nested data structures
|
|
131
|
+
nestedData = {"config": [1, "host", {"port": 8080}], "users": ["alice", "bob"]}
|
|
132
|
+
allStrings = stringItUp(nestedData) # ['config', 'host', 'port', 'users', 'alice', 'bob']
|
|
133
|
+
|
|
134
|
+
# Merge dictionaries containing lists
|
|
135
|
+
dictionaryAlpha = {"servers": ["web1", "web2"], "databases": ["db1"]}
|
|
136
|
+
dictionaryBeta = {"servers": ["web3"], "databases": ["db2", "db3"]}
|
|
137
|
+
merged = updateExtendPolishDictionaryLists(dictionaryAlpha, dictionaryBeta, destroyDuplicates=True)
|
|
138
|
+
|
|
139
|
+
# Compress NumPy arrays with run-length encoding
|
|
140
|
+
arrayData = numpy.array([1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 9])
|
|
141
|
+
compressed = autoDecodingRLE(arrayData) # "[1,*range(2,6)]+[5]*2+[*range(6,10)]"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Testing
|
|
145
|
+
|
|
146
|
+
The package includes comprehensive test suites that you can import and run:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from hunterMakesPy.pytestForYourUse import (
|
|
150
|
+
PytestFor_defineConcurrencyLimit,
|
|
151
|
+
PytestFor_intInnit,
|
|
152
|
+
PytestFor_oopsieKwargsie
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Run tests on the built-in functions
|
|
156
|
+
listOfTests = PytestFor_defineConcurrencyLimit()
|
|
157
|
+
for nameOfTest, callablePytest in listOfTests:
|
|
158
|
+
callablePytest()
|
|
159
|
+
|
|
160
|
+
# Or test your own compatible functions
|
|
161
|
+
@pytest.mark.parametrize("nameOfTest,callablePytest",
|
|
162
|
+
PytestFor_intInnit(callableToTest=myFunction))
|
|
163
|
+
def test_myFunction(nameOfTest, callablePytest):
|
|
164
|
+
callablePytest()
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## My recovery
|
|
168
|
+
|
|
169
|
+
[](https://HunterThinks.com/support)
|
|
170
|
+
[](https://www.youtube.com/@HunterHogan)
|
|
171
|
+
|
|
172
|
+
## How to code
|
|
173
|
+
|
|
174
|
+
Coding One Step at a Time:
|
|
175
|
+
|
|
176
|
+
0. WRITE CODE.
|
|
177
|
+
1. Don't write stupid code that's hard to revise.
|
|
178
|
+
2. Write good code.
|
|
179
|
+
3. When revising, write better code.
|
|
180
|
+
|
|
181
|
+
[](https://creativecommons.org/licenses/by-nc/4.0/)
|
|
@@ -1,25 +1,49 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "hunterMakesPy"
|
|
3
|
-
version = "0.1.
|
|
4
|
-
description = ""
|
|
3
|
+
version = "0.1.1"
|
|
4
|
+
description = "A modular Python toolkit for defensive programming, parameter validation, file system utilities, and flexible data structure manipulation. Provides helpers for error propagation, input validation, concurrency limits, safe directory creation, dynamic module loading, string extraction from nested structures, and dictionary merging."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
7
7
|
license = { 'text' = "CC-BY-NC-4.0" }
|
|
8
8
|
authors = [{ name = "Hunter Hogan", email = "HunterHogan@pm.me" }]
|
|
9
|
-
keywords = [
|
|
9
|
+
keywords = [
|
|
10
|
+
"defensive programming",
|
|
11
|
+
"parameter validation",
|
|
12
|
+
"input validation",
|
|
13
|
+
"error propagation",
|
|
14
|
+
"concurrency limit",
|
|
15
|
+
"integer parsing",
|
|
16
|
+
"file system utilities",
|
|
17
|
+
"directory creation",
|
|
18
|
+
"dynamic import",
|
|
19
|
+
"module loading",
|
|
20
|
+
"attribute loading",
|
|
21
|
+
"string extraction",
|
|
22
|
+
"nested data structures",
|
|
23
|
+
"dictionary merging",
|
|
24
|
+
"package settings",
|
|
25
|
+
"configuration",
|
|
26
|
+
"pytest",
|
|
27
|
+
"test utilities"
|
|
28
|
+
]
|
|
10
29
|
classifiers = [
|
|
11
30
|
"Development Status :: 4 - Beta",
|
|
12
31
|
"Environment :: Console",
|
|
32
|
+
"Framework :: Pytest",
|
|
33
|
+
"Intended Audience :: Developers",
|
|
13
34
|
"Intended Audience :: End Users/Desktop",
|
|
14
35
|
"Intended Audience :: Other Audience",
|
|
15
36
|
"Natural Language :: English",
|
|
16
37
|
"Operating System :: OS Independent",
|
|
17
|
-
"Programming Language :: Python",
|
|
18
|
-
"Programming Language :: Python :: 3",
|
|
19
38
|
"Programming Language :: Python :: 3.10",
|
|
20
39
|
"Programming Language :: Python :: 3.11",
|
|
21
40
|
"Programming Language :: Python :: 3.12",
|
|
22
41
|
"Programming Language :: Python :: 3.13",
|
|
42
|
+
"Programming Language :: Python :: 3",
|
|
43
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
44
|
+
"Programming Language :: Python",
|
|
45
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
46
|
+
"Topic :: Utilities",
|
|
23
47
|
"Typing :: Typed",
|
|
24
48
|
]
|
|
25
49
|
urls = { Donate = "https://www.patreon.com/integrated", Homepage = "https://github.com/hunterhogan/", Issues = "https://github.com/hunterhogan/", Repository = "https://github.com/hunterhogan/" }
|
|
@@ -22,7 +22,7 @@ def testWriteStringToHereCreatesFileAndWritesContent(pathTmpTesting: pathlib.Pat
|
|
|
22
22
|
filePath = nestedDirectory / "test.txt"
|
|
23
23
|
writeStringToHere("hello world", filePath)
|
|
24
24
|
assert filePath.exists(), uniformTestFailureMessage(True, filePath.exists(), "testWriteStringToHereCreatesFileAndWritesContent", filePath)
|
|
25
|
-
assert filePath.read_text() == "hello world", uniformTestFailureMessage("hello world", filePath.read_text(), "testWriteStringToHereCreatesFileAndWritesContent", filePath)
|
|
25
|
+
assert filePath.read_text(encoding="utf-8") == "hello world", uniformTestFailureMessage("hello world", filePath.read_text(encoding="utf-8"), "testWriteStringToHereCreatesFileAndWritesContent", filePath)
|
|
26
26
|
|
|
27
27
|
@pytest.mark.parametrize(
|
|
28
28
|
"moduleName, identifier, expectedType",
|
huntermakespy-0.1.0/PKG-INFO
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: hunterMakesPy
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Author-email: Hunter Hogan <HunterHogan@pm.me>
|
|
5
|
-
License: CC-BY-NC-4.0
|
|
6
|
-
Project-URL: Donate, https://www.patreon.com/integrated
|
|
7
|
-
Project-URL: Homepage, https://github.com/hunterhogan/
|
|
8
|
-
Project-URL: Issues, https://github.com/hunterhogan/
|
|
9
|
-
Project-URL: Repository, https://github.com/hunterhogan/
|
|
10
|
-
Classifier: Development Status :: 4 - Beta
|
|
11
|
-
Classifier: Environment :: Console
|
|
12
|
-
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
-
Classifier: Intended Audience :: Other Audience
|
|
14
|
-
Classifier: Natural Language :: English
|
|
15
|
-
Classifier: Operating System :: OS Independent
|
|
16
|
-
Classifier: Programming Language :: Python
|
|
17
|
-
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
-
Classifier: Typing :: Typed
|
|
23
|
-
Requires-Python: >=3.10
|
|
24
|
-
Description-Content-Type: text/markdown
|
|
25
|
-
License-File: LICENSE
|
|
26
|
-
Requires-Dist: charset_normalizer
|
|
27
|
-
Requires-Dist: more_itertools
|
|
28
|
-
Requires-Dist: numpy
|
|
29
|
-
Requires-Dist: python_minifier
|
|
30
|
-
Requires-Dist: tomli
|
|
31
|
-
Provides-Extra: testing
|
|
32
|
-
Requires-Dist: mypy; extra == "testing"
|
|
33
|
-
Requires-Dist: pytest; extra == "testing"
|
|
34
|
-
Requires-Dist: pytest-cov; extra == "testing"
|
|
35
|
-
Requires-Dist: pytest-xdist; extra == "testing"
|
|
36
|
-
Requires-Dist: pyupgrade; extra == "testing"
|
|
37
|
-
Requires-Dist: setuptools-scm; extra == "testing"
|
|
38
|
-
Dynamic: license-file
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: hunterMakesPy
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Author-email: Hunter Hogan <HunterHogan@pm.me>
|
|
5
|
-
License: CC-BY-NC-4.0
|
|
6
|
-
Project-URL: Donate, https://www.patreon.com/integrated
|
|
7
|
-
Project-URL: Homepage, https://github.com/hunterhogan/
|
|
8
|
-
Project-URL: Issues, https://github.com/hunterhogan/
|
|
9
|
-
Project-URL: Repository, https://github.com/hunterhogan/
|
|
10
|
-
Classifier: Development Status :: 4 - Beta
|
|
11
|
-
Classifier: Environment :: Console
|
|
12
|
-
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
-
Classifier: Intended Audience :: Other Audience
|
|
14
|
-
Classifier: Natural Language :: English
|
|
15
|
-
Classifier: Operating System :: OS Independent
|
|
16
|
-
Classifier: Programming Language :: Python
|
|
17
|
-
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
-
Classifier: Typing :: Typed
|
|
23
|
-
Requires-Python: >=3.10
|
|
24
|
-
Description-Content-Type: text/markdown
|
|
25
|
-
License-File: LICENSE
|
|
26
|
-
Requires-Dist: charset_normalizer
|
|
27
|
-
Requires-Dist: more_itertools
|
|
28
|
-
Requires-Dist: numpy
|
|
29
|
-
Requires-Dist: python_minifier
|
|
30
|
-
Requires-Dist: tomli
|
|
31
|
-
Provides-Extra: testing
|
|
32
|
-
Requires-Dist: mypy; extra == "testing"
|
|
33
|
-
Requires-Dist: pytest; extra == "testing"
|
|
34
|
-
Requires-Dist: pytest-cov; extra == "testing"
|
|
35
|
-
Requires-Dist: pytest-xdist; extra == "testing"
|
|
36
|
-
Requires-Dist: pyupgrade; extra == "testing"
|
|
37
|
-
Requires-Dist: setuptools-scm; extra == "testing"
|
|
38
|
-
Dynamic: license-file
|
|
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
|