hunterMakesPy 0.1.0__tar.gz → 0.1.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.
Files changed (30) hide show
  1. huntermakespy-0.1.2/PKG-INFO +180 -0
  2. huntermakespy-0.1.2/README.md +135 -0
  3. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/hunterMakesPy/__init__.py +11 -3
  4. huntermakespy-0.1.2/hunterMakesPy/_theSSOT.py +4 -0
  5. huntermakespy-0.1.2/hunterMakesPy/coping.py +149 -0
  6. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/hunterMakesPy/dataStructures.py +12 -12
  7. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/hunterMakesPy/filesystemToolkit.py +1 -2
  8. huntermakespy-0.1.2/hunterMakesPy.egg-info/PKG-INFO +180 -0
  9. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/hunterMakesPy.egg-info/SOURCES.txt +1 -0
  10. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/hunterMakesPy.egg-info/requires.txt +5 -4
  11. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/pyproject.toml +32 -9
  12. huntermakespy-0.1.2/tests/test_coping.py +216 -0
  13. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/tests/test_filesystemToolkit.py +1 -1
  14. huntermakespy-0.1.0/PKG-INFO +0 -38
  15. huntermakespy-0.1.0/hunterMakesPy/_theSSOT.py +0 -40
  16. huntermakespy-0.1.0/hunterMakesPy/coping.py +0 -73
  17. huntermakespy-0.1.0/hunterMakesPy.egg-info/PKG-INFO +0 -38
  18. huntermakespy-0.1.0/tests/test_coping.py +0 -56
  19. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/LICENSE +0 -0
  20. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/hunterMakesPy/parseParameters.py +0 -0
  21. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/hunterMakesPy/py.typed +0 -0
  22. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/hunterMakesPy/pytestForYourUse.py +0 -0
  23. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/hunterMakesPy/theTypes.py +0 -0
  24. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/hunterMakesPy.egg-info/dependency_links.txt +0 -0
  25. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/hunterMakesPy.egg-info/top_level.txt +0 -0
  26. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/setup.cfg +0 -0
  27. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/tests/__init__.py +0 -0
  28. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/tests/conftest.py +0 -0
  29. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/tests/test_dataStructures.py +0 -0
  30. {huntermakespy-0.1.0 → huntermakespy-0.1.2}/tests/test_parseParameters.py +0 -0
@@ -0,0 +1,180 @@
1
+ Metadata-Version: 2.4
2
+ Name: hunterMakesPy
3
+ Version: 0.1.2
4
+ Summary: Easy Python functions making making functional Python functions easier.
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: attribute loading,concurrency limit,configuration,defensive programming,dictionary merging,directory creation,dynamic import,error propagation,file system utilities,input validation,integer parsing,module loading,nested data structures,package settings,parameter validation,pytest,string extraction,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
21
+ Classifier: Programming Language :: Python :: 3
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Programming Language :: Python :: Implementation :: CPython
26
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
+ Classifier: Topic :: Utilities
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.11
30
+ Description-Content-Type: text/markdown
31
+ License-File: LICENSE
32
+ Requires-Dist: charset_normalizer
33
+ Requires-Dist: more_itertools
34
+ Requires-Dist: numpy
35
+ Requires-Dist: python_minifier
36
+ Provides-Extra: development
37
+ Requires-Dist: mypy; extra == "development"
38
+ Requires-Dist: pyupgrade; extra == "development"
39
+ Requires-Dist: setuptools-scm; extra == "development"
40
+ Provides-Extra: testing
41
+ Requires-Dist: pytest; extra == "testing"
42
+ Requires-Dist: pytest-cov; extra == "testing"
43
+ Requires-Dist: pytest-xdist; extra == "testing"
44
+ Dynamic: license-file
45
+
46
+ # hunterMakesPy
47
+
48
+ A modular Python toolkit for defensive programming, parameter validation, file system utilities, and flexible data structure manipulation.
49
+
50
+ [![pip install hunterMakesPy](https://img.shields.io/badge/pip%20install-hunterMakesPy-gray.svg?colorB=3b434b)](https://pypi.org/project/hunterMakesPy/)
51
+
52
+ ## Overview
53
+
54
+ 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.
55
+
56
+ ## Installation
57
+
58
+ ```bash
59
+ pip install hunterMakesPy
60
+ ```
61
+
62
+ ## Defensive Programming
63
+
64
+ Utilities for handling `None` values and defensive programming patterns.
65
+
66
+ ```python
67
+ from hunterMakesPy import raiseIfNone
68
+
69
+ # Ensure a function result is not None
70
+ def findConfiguration(configName: str) -> dict[str, str] | None:
71
+ # ... search logic ...
72
+ return None
73
+
74
+ config = raiseIfNone(
75
+ findConfiguration("database"),
76
+ "Configuration 'database' is required but not found"
77
+ )
78
+ ```
79
+
80
+ ## Parameter Validation
81
+
82
+ Parameter validation, integer parsing, and concurrency handling.
83
+
84
+ ```python
85
+ from hunterMakesPy import defineConcurrencyLimit, intInnit, oopsieKwargsie
86
+
87
+ # Smart concurrency limit calculation
88
+ cpuLimit = defineConcurrencyLimit(limit=0.75) # Use 75% of available CPUs
89
+ cpuLimit = defineConcurrencyLimit(limit=True) # Use exactly 1 CPU
90
+ cpuLimit = defineConcurrencyLimit(limit=4) # Use exactly 4 CPUs
91
+
92
+ # Robust integer validation
93
+ validatedIntegers = intInnit([1, "2", 3.0, "4"], "port_numbers")
94
+
95
+ # String-to-boolean conversion for configuration
96
+ userInput = "True"
97
+ booleanValue = oopsieKwargsie(userInput) # Returns True
98
+ ```
99
+
100
+ ## File System Utilities
101
+
102
+ Safe file operations and dynamic module importing.
103
+
104
+ ```python
105
+ from hunterMakesPy import (
106
+ importLogicalPath2Identifier,
107
+ importPathFilename2Identifier,
108
+ makeDirsSafely,
109
+ writeStringToHere
110
+ )
111
+
112
+ # Dynamic imports
113
+ gcdFunction = importLogicalPath2Identifier("math", "gcd")
114
+ customFunction = importPathFilename2Identifier("path/to/module.py", "functionName")
115
+
116
+ # Safe file operations
117
+ pathFilename = Path("deep/nested/directory/file.txt")
118
+ writeStringToHere("content", pathFilename) # Creates directories automatically
119
+ ```
120
+
121
+ ## Data Structure Manipulation
122
+
123
+ Utilities for string extraction, data flattening, and array compression.
124
+
125
+ ```python
126
+ from hunterMakesPy import stringItUp, updateExtendPolishDictionaryLists, autoDecodingRLE
127
+ import numpy
128
+
129
+ # Extract all strings from nested data structures
130
+ nestedData = {"config": [1, "host", {"port": 8080}], "users": ["alice", "bob"]}
131
+ allStrings = stringItUp(nestedData) # ['config', 'host', 'port', 'users', 'alice', 'bob']
132
+
133
+ # Merge dictionaries containing lists
134
+ dictionaryAlpha = {"servers": ["web1", "web2"], "databases": ["db1"]}
135
+ dictionaryBeta = {"servers": ["web3"], "databases": ["db2", "db3"]}
136
+ merged = updateExtendPolishDictionaryLists(dictionaryAlpha, dictionaryBeta, destroyDuplicates=True)
137
+
138
+ # Compress NumPy arrays with run-length encoding
139
+ arrayData = numpy.array([1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 9])
140
+ compressed = autoDecodingRLE(arrayData) # "[1,*range(2,6)]+[5]*2+[*range(6,10)]"
141
+ ```
142
+
143
+ ## Testing
144
+
145
+ The package includes comprehensive test suites that you can import and run:
146
+
147
+ ```python
148
+ from hunterMakesPy.pytestForYourUse import (
149
+ PytestFor_defineConcurrencyLimit,
150
+ PytestFor_intInnit,
151
+ PytestFor_oopsieKwargsie
152
+ )
153
+
154
+ # Run tests on the built-in functions
155
+ listOfTests = PytestFor_defineConcurrencyLimit()
156
+ for nameOfTest, callablePytest in listOfTests:
157
+ callablePytest()
158
+
159
+ # Or test your own compatible functions
160
+ @pytest.mark.parametrize("nameOfTest,callablePytest",
161
+ PytestFor_intInnit(callableToTest=myFunction))
162
+ def test_myFunction(nameOfTest, callablePytest):
163
+ callablePytest()
164
+ ```
165
+
166
+ ## My recovery
167
+
168
+ [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
169
+ [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
170
+
171
+ ## How to code
172
+
173
+ Coding One Step at a Time:
174
+
175
+ 0. WRITE CODE.
176
+ 1. Don't write stupid code that's hard to revise.
177
+ 2. Write good code.
178
+ 3. When revising, write better code.
179
+
180
+ [![CC-BY-NC-4.0](https://github.com/hunterhogan/hunterMakesPy/blob/main/CC-BY-NC-4.0.svg)](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
+ [![pip install hunterMakesPy](https://img.shields.io/badge/pip%20install-hunterMakesPy-gray.svg?colorB=3b434b)](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
+ [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
124
+ [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](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
+ [![CC-BY-NC-4.0](https://github.com/hunterhogan/hunterMakesPy/blob/main/CC-BY-NC-4.0.svg)](https://creativecommons.org/licenses/by-nc/4.0/)
@@ -1,14 +1,22 @@
1
- """`import hunterMakesPy as humpy`."""
1
+ """A modular toolkit for defensive programming, parameter validation, file system utilities, and data structure manipulation.
2
+
3
+ This package provides:
4
+ - Defensive programming helpers for handling `None` values and error propagation.
5
+ - Parameter and input validation, integer parsing, and concurrency limit utilities.
6
+ - File system and import utilities for safe directory creation and dynamic module/attribute loading.
7
+ - Utilities for string extraction from nested data structures and merging dictionaries of lists.
8
+
9
+ """
2
10
  from hunterMakesPy.theTypes import identifierDotAttribute as identifierDotAttribute
3
11
 
4
- from hunterMakesPy.coping import raiseIfNone as raiseIfNone
12
+ from hunterMakesPy.coping import PackageSettings as PackageSettings, raiseIfNone as raiseIfNone
5
13
 
6
14
  from hunterMakesPy.parseParameters import (defineConcurrencyLimit as defineConcurrencyLimit, intInnit as intInnit,
7
15
  oopsieKwargsie as oopsieKwargsie)
8
16
 
9
17
  from hunterMakesPy.filesystemToolkit import (importLogicalPath2Identifier as importLogicalPath2Identifier,
10
18
  importPathFilename2Identifier as importPathFilename2Identifier, makeDirsSafely as makeDirsSafely,
11
- writeStringToHere as writeStringToHere)
19
+ writeStringToHere as writeStringToHere)
12
20
 
13
21
  from hunterMakesPy.dataStructures import (autoDecodingRLE as autoDecodingRLE, stringItUp as stringItUp,
14
22
  updateExtendPolishDictionaryLists as updateExtendPolishDictionaryLists)
@@ -0,0 +1,4 @@
1
+ """Settings for this package."""
2
+ from hunterMakesPy import PackageSettings
3
+
4
+ settingsPackage = PackageSettings(identifierPackageFALLBACK="hunterMakesPy")
@@ -0,0 +1,149 @@
1
+ """Package configuration and defensive programming utilities for Python projects."""
2
+ from importlib.util import find_spec
3
+ from pathlib import Path
4
+ from tomllib import loads as tomllib_loads
5
+ from typing import TYPE_CHECKING, TypeVar
6
+ import dataclasses
7
+
8
+ if TYPE_CHECKING:
9
+ from importlib.machinery import ModuleSpec
10
+
11
+ TypeSansNone = TypeVar('TypeSansNone')
12
+
13
+ def getIdentifierPackagePACKAGING(identifierPackageFALLBACK: str) -> str:
14
+ """Get package name from pyproject.toml or fallback to provided value."""
15
+ try:
16
+ return tomllib_loads(Path('pyproject.toml').read_text(encoding='utf-8'))['project']['name']
17
+ except Exception: # noqa: BLE001
18
+ return identifierPackageFALLBACK
19
+
20
+ def getPathPackageINSTALLING(identifierPackage: str) -> Path:
21
+ """Return the root directory of the installed package."""
22
+ try:
23
+ moduleSpecification: ModuleSpec | None = find_spec(identifierPackage)
24
+ if moduleSpecification and moduleSpecification.origin:
25
+ pathFilename = Path(moduleSpecification.origin)
26
+ return pathFilename.parent if pathFilename.is_file() else pathFilename
27
+ except ModuleNotFoundError:
28
+ pass
29
+ return Path.cwd()
30
+
31
+ @dataclasses.dataclass
32
+ class PackageSettings:
33
+ """Configuration container for Python package metadata and runtime settings.
34
+
35
+ This `class` provides a simple way to store and access basic information about a Python package, It will automatically resolve
36
+ package identifiers and installation paths if they are not passed to the `class` constructor. Python `dataclasses` are easy to
37
+ subtype and extend.
38
+
39
+ Parameters
40
+ ----------
41
+ identifierPackageFALLBACK : str = ''
42
+ Fallback package identifier used only during initialization when automatic discovery fails.
43
+ pathPackage : Path = Path()
44
+ Absolute path to the installed package directory. Automatically resolved from `identifierPackage` if not provided.
45
+ identifierPackage : str = ''
46
+ Canonical name of the package. Automatically extracted from `pyproject.toml`.
47
+ fileExtension : str = '.py'
48
+ Default file extension.
49
+
50
+ Examples
51
+ --------
52
+ Automatic package discovery from development environment:
53
+
54
+ ```python
55
+ settings = PackageSettings(identifierPackageFALLBACK='cobraPy')
56
+ # Automatically discovers package name from pyproject.toml
57
+ # Resolves installation path from package identifier
58
+ ```
59
+
60
+ Explicit configuration for specific deployment:
61
+
62
+ ```python
63
+ settings = PackageSettings(
64
+ identifierPackage='cobraPy',
65
+ pathPackage=Path('/opt/tenEx/packages/cobraPy'),
66
+ fileExtension='.pyx'
67
+ )
68
+ ```
69
+
70
+ """
71
+
72
+ identifierPackageFALLBACK: dataclasses.InitVar[str] = ''
73
+ """Fallback package identifier used during initialization only."""
74
+ pathPackage: Path = dataclasses.field(default_factory=Path, metadata={'evaluateWhen': 'installing'})
75
+ """Absolute path to the installed package."""
76
+ identifierPackage: str = dataclasses.field(default='', metadata={'evaluateWhen': 'packaging'})
77
+ """Name of this package."""
78
+ fileExtension: str = dataclasses.field(default='.py', metadata={'evaluateWhen': 'installing'})
79
+ """Default file extension for files."""
80
+
81
+ def __post_init__(self, identifierPackageFALLBACK: str) -> None:
82
+ """Initialize computed fields after dataclass initialization."""
83
+ if not self.identifierPackage and identifierPackageFALLBACK:
84
+ self.identifierPackage = getIdentifierPackagePACKAGING(identifierPackageFALLBACK)
85
+ if self.pathPackage == Path() and self.identifierPackage:
86
+ self.pathPackage = getPathPackageINSTALLING(self.identifierPackage)
87
+
88
+ def raiseIfNone(returnTarget: TypeSansNone | None, errorMessage: str | None = None) -> TypeSansNone:
89
+ """Raise a `ValueError` if the target value is `None`, otherwise return the value: tell the type checker that the return value is not `None`.
90
+
91
+ (AI generated docstring)
92
+
93
+ This is a defensive programming function that converts unexpected `None` values into explicit errors with context. It is useful for asserting that functions that might return `None` have actually returned a meaningful value.
94
+
95
+ Parameters
96
+ ----------
97
+ returnTarget : TypeSansNone | None
98
+ The value to check for `None`. If not `None`, this value is returned unchanged.
99
+ errorMessage : str | None = None
100
+ Custom error message to include in the `ValueError`. If `None`, a default message with debugging hints is used.
101
+
102
+ Returns
103
+ -------
104
+ returnTarget : TypeSansNone
105
+ The original `returnTarget` value, guaranteed to not be `None`.
106
+
107
+ Raises
108
+ ------
109
+ ValueError
110
+ If `returnTarget` is `None`.
111
+
112
+ Examples
113
+ --------
114
+ Ensure a function result is not `None`:
115
+
116
+ ```python
117
+ def findFirstMatch(listItems: list[str], pattern: str) -> str | None:
118
+ for item in listItems:
119
+ if pattern in item:
120
+ return item
121
+ return None
122
+
123
+ listFiles = ['document.txt', 'image.png', 'data.csv']
124
+ filename = raiseIfNone(findFirstMatch(listFiles, '.txt'))
125
+ # Returns 'document.txt'
126
+ ```
127
+
128
+ Handle dictionary lookups with custom error messages:
129
+
130
+ ```python
131
+ configurationMapping = {'host': 'localhost', 'port': 8080}
132
+ host = raiseIfNone(configurationMapping.get('host'),
133
+ "Configuration must include 'host' setting")
134
+ # Returns 'localhost'
135
+
136
+ # This would raise ValueError with custom message:
137
+ # database = raiseIfNone(configurationMapping.get('database'),
138
+ # "Configuration must include 'database' setting")
139
+ ```
140
+
141
+ Thanks
142
+ ------
143
+ sobolevn, https://github.com/sobolevn, for the seed of the function. https://github.com/python/typing/discussions/1997#discussioncomment-13108399
144
+
145
+ """
146
+ if returnTarget is None:
147
+ message = errorMessage or 'A function unexpectedly returned `None`. Hint: look at the traceback immediately before `raiseIfNone`.'
148
+ raise ValueError(message)
149
+ return returnTarget
@@ -46,7 +46,7 @@ def autoDecodingRLE(arrayTarget: NDArray[integer[Any]], *, assumeAddSpaces: bool
46
46
  """
47
47
  def sliceNDArrayToNestedLists(arraySlice: NDArray[integer[Any]]) -> Any:
48
48
  def getLengthOption(optionAsStr: str) -> int:
49
- # `assumeAddSpaces` characters: `,` 1; `]*` 2 # noqa: ERA001
49
+ """`assumeAddSpaces` characters: `,` 1; `]*` 2."""
50
50
  return assumeAddSpaces * (optionAsStr.count(',') + optionAsStr.count(']*') * 2) + len(optionAsStr)
51
51
 
52
52
  if arraySlice.ndim > 1:
@@ -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<multiple>\\d+)\\)(?P<bracketBehind>])|"
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<malkovichmalkovich>\\d+),(?P<multiple_fml>\\d+)\\)(?P<joinBehind>,)|"
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<malkovichmalkovichmalkovich>\\d+),(?P<multiple_whatever>\\d+)\\)(?P<bracketBehindbracketBehind>])|"
132
+ "(?P<bracketAhead>\\[)\\((?P<malkovichMalkovichMalkovich>\\d+),(?P<multiply_whatever>\\d+)\\)(?P<bracketBehindBracketBehind>])|"
133
133
  # Pattern 4: Comma ahead, comma behind # noqa: ERA001
134
- "(?P<joinAhead_prayharder>,)\\((?P<malkovichmalkovichmalkovichmalkovich>\\d+),(?P<multiple_prayharder>\\d+)\\)(?P<joinBehind_prayharder>,)"
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
- yourIdentifiersSuck = match.groupdict()
141
- joinAhead = yourIdentifiersSuck.get('joinAhead') or yourIdentifiersSuck.get('joinAhead_prayharder')
142
- malkovich = yourIdentifiersSuck.get('malkovich') or yourIdentifiersSuck.get('malkovichmalkovich') or yourIdentifiersSuck.get('malkovichmalkovichmalkovich') or yourIdentifiersSuck.get('malkovichmalkovichmalkovichmalkovich')
143
- multiple = yourIdentifiersSuck.get('multiple') or yourIdentifiersSuck.get('multiple_fml') or yourIdentifiersSuck.get('multiple_whatever') or yourIdentifiersSuck.get('multiple_prayharder')
144
- joinBehind = yourIdentifiersSuck.get('joinBehind') or yourIdentifiersSuck.get('joinBehind_prayharder')
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}]*{multiple}{replaceBehind}"
150
+ return f"{replaceAhead}{malkovich}]*{multiply}{replaceBehind}"
151
151
 
152
152
  arrayAsStr = patternRegex.sub(replacementByContext, arrayAsStr)
153
153
  arrayAsStr = patternRegex.sub(replacementByContext, arrayAsStr)
@@ -249,7 +249,7 @@ def updateExtendPolishDictionaryLists(*dictionaryLists: Mapping[str, list[Any] |
249
249
  ImaStr = str(keyName)
250
250
  ImaList = list(keyValue)
251
251
  ePluribusUnum.setdefault(ImaStr, []).extend(ImaList)
252
- except TypeError: # noqa: PERF203
252
+ except TypeError:
253
253
  if killErroneousDataTypes:
254
254
  continue
255
255
  else:
@@ -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 writing tabular data to files, computing canonical relative paths, importing
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