classcore 1.6.1__tar.gz → 1.8__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.
- {classcore-1.6.1 → classcore-1.8}/.gitignore +2 -0
- {classcore-1.6.1 → classcore-1.8}/PKG-INFO +30 -10
- {classcore-1.6.1 → classcore-1.8}/README.rst +29 -9
- {classcore-1.6.1 → classcore-1.8}/pyproject.toml +18 -10
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/__init__.py +1 -1
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/standard/behaviors.py +4 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/standard/classes.py +1 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/standard/decorators.py +95 -20
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/standard/modules.py +21 -7
- {classcore-1.6.1 → classcore-1.8}/LICENSE.txt +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/__/__init__.py +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/__/doctab.py +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/__/imports.py +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/__/nomina.py +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/decorators.py +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/exceptions.py +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/factories.py +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/nomina.py +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/py.typed +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/standard/__.py +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/standard/__init__.py +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/standard/dynadoc.py +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/standard/nomina.py +0 -0
- {classcore-1.6.1 → classcore-1.8}/sources/classcore/utilities.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: classcore
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8
|
|
4
4
|
Summary: Foundational class factories and decorators.
|
|
5
5
|
Project-URL: Homepage, https://github.com/emcd/python-classcore
|
|
6
6
|
Project-URL: Documentation, https://emcd.github.io/python-classcore
|
|
@@ -110,14 +110,17 @@ modules.
|
|
|
110
110
|
Installation 📦
|
|
111
111
|
===============================================================================
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
Method: Install Python Package
|
|
114
|
+
-------------------------------------------------------------------------------
|
|
115
|
+
|
|
116
|
+
Install via `uv <https://github.com/astral-sh/uv/blob/main/README.md>`_ ``pip``
|
|
114
117
|
command:
|
|
115
118
|
|
|
116
119
|
::
|
|
117
120
|
|
|
118
121
|
uv pip install classcore
|
|
119
122
|
|
|
120
|
-
Or, via ``pip``:
|
|
123
|
+
Or, install via ``pip``:
|
|
121
124
|
|
|
122
125
|
::
|
|
123
126
|
|
|
@@ -217,6 +220,23 @@ Use Cases 🎯
|
|
|
217
220
|
* 📦 **Frameworks**: Frameworks with controlled extension and modification.
|
|
218
221
|
|
|
219
222
|
|
|
223
|
+
Contribution 🤝
|
|
224
|
+
===============================================================================
|
|
225
|
+
|
|
226
|
+
Contribution to this project is welcome! However, it must follow the `code of
|
|
227
|
+
conduct
|
|
228
|
+
<https://emcd.github.io/python-project-common/stable/sphinx-html/common/conduct.html>`_
|
|
229
|
+
for the project.
|
|
230
|
+
|
|
231
|
+
Please file bug reports and feature requests in the `issue tracker
|
|
232
|
+
<https://github.com/emcd/python-classcore/issues>`_ or submit `pull
|
|
233
|
+
requests <https://github.com/emcd/python-classcore/pulls>`_ to
|
|
234
|
+
improve the source code or documentation.
|
|
235
|
+
|
|
236
|
+
For development guidance and standards, please see the `development guide
|
|
237
|
+
<https://emcd.github.io/python-classcore/stable/sphinx-html/contribution.html#development>`_.
|
|
238
|
+
|
|
239
|
+
|
|
220
240
|
`More Flair <https://www.imdb.com/title/tt0151804/characters/nm0431918>`_
|
|
221
241
|
===============================================================================
|
|
222
242
|
|
|
@@ -257,24 +277,24 @@ Other Projects by This Author 🌟
|
|
|
257
277
|
===============================================================================
|
|
258
278
|
|
|
259
279
|
|
|
260
|
-
* `python-absence <https://github.com/emcd/python-absence>`_ (`absence <https://pypi.org/project/absence/>`_ on PyPI)
|
|
280
|
+
* `python-absence <https://github.com/emcd/python-absence>`_ (`absence <https://pypi.org/project/absence/>`_ on PyPI)
|
|
261
281
|
|
|
262
282
|
🕳️ A Python library package which provides a **sentinel for absent values** - a falsey, immutable singleton that represents the absence of a value in contexts where ``None`` or ``False`` may be valid values.
|
|
263
|
-
* `python-accretive <https://github.com/emcd/python-accretive>`_ (`accretive <https://pypi.org/project/accretive/>`_ on PyPI)
|
|
283
|
+
* `python-accretive <https://github.com/emcd/python-accretive>`_ (`accretive <https://pypi.org/project/accretive/>`_ on PyPI)
|
|
264
284
|
|
|
265
285
|
🌌 A Python library package which provides **accretive data structures** - collections which can grow but never shrink.
|
|
266
|
-
* `python-dynadoc <https://github.com/emcd/python-dynadoc>`_ (`dynadoc <https://pypi.org/project/dynadoc/>`_ on PyPI)
|
|
286
|
+
* `python-dynadoc <https://github.com/emcd/python-dynadoc>`_ (`dynadoc <https://pypi.org/project/dynadoc/>`_ on PyPI)
|
|
267
287
|
|
|
268
288
|
📝 A Python library package which bridges the gap between **rich annotations** and **automatic documentation generation** with configurable renderers and support for reusable fragments.
|
|
269
|
-
* `python-falsifier <https://github.com/emcd/python-falsifier>`_ (`falsifier <https://pypi.org/project/falsifier/>`_ on PyPI)
|
|
289
|
+
* `python-falsifier <https://github.com/emcd/python-falsifier>`_ (`falsifier <https://pypi.org/project/falsifier/>`_ on PyPI)
|
|
270
290
|
|
|
271
291
|
🎭 A very simple Python library package which provides a **base class for falsey objects** - objects that evaluate to ``False`` in boolean contexts.
|
|
272
|
-
* `python-frigid <https://github.com/emcd/python-frigid>`_ (`frigid <https://pypi.org/project/frigid/>`_ on PyPI)
|
|
292
|
+
* `python-frigid <https://github.com/emcd/python-frigid>`_ (`frigid <https://pypi.org/project/frigid/>`_ on PyPI)
|
|
273
293
|
|
|
274
294
|
🔒 A Python library package which provides **immutable data structures** - collections which cannot be modified after creation.
|
|
275
|
-
* `python-icecream-truck <https://github.com/emcd/python-icecream-truck>`_ (`icecream-truck <https://pypi.org/project/icecream-truck/>`_ on PyPI)
|
|
295
|
+
* `python-icecream-truck <https://github.com/emcd/python-icecream-truck>`_ (`icecream-truck <https://pypi.org/project/icecream-truck/>`_ on PyPI)
|
|
276
296
|
|
|
277
297
|
🍦 **Flavorful Debugging** - A Python library which enhances the powerful and well-known ``icecream`` package with flavored traces, configuration hierarchies, customized outputs, ready-made recipes, and more.
|
|
278
|
-
* `python-mimeogram <https://github.com/emcd/python-mimeogram>`_ (`mimeogram <https://pypi.org/project/mimeogram/>`_ on PyPI)
|
|
298
|
+
* `python-mimeogram <https://github.com/emcd/python-mimeogram>`_ (`mimeogram <https://pypi.org/project/mimeogram/>`_ on PyPI)
|
|
279
299
|
|
|
280
300
|
📨 A command-line tool for **exchanging collections of files with Large Language Models** - bundle multiple files into a single clipboard-ready document while preserving directory structure and metadata... good for code reviews, project sharing, and LLM interactions.
|
|
@@ -81,14 +81,17 @@ modules.
|
|
|
81
81
|
Installation 📦
|
|
82
82
|
===============================================================================
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
Method: Install Python Package
|
|
85
|
+
-------------------------------------------------------------------------------
|
|
86
|
+
|
|
87
|
+
Install via `uv <https://github.com/astral-sh/uv/blob/main/README.md>`_ ``pip``
|
|
85
88
|
command:
|
|
86
89
|
|
|
87
90
|
::
|
|
88
91
|
|
|
89
92
|
uv pip install classcore
|
|
90
93
|
|
|
91
|
-
Or, via ``pip``:
|
|
94
|
+
Or, install via ``pip``:
|
|
92
95
|
|
|
93
96
|
::
|
|
94
97
|
|
|
@@ -188,6 +191,23 @@ Use Cases 🎯
|
|
|
188
191
|
* 📦 **Frameworks**: Frameworks with controlled extension and modification.
|
|
189
192
|
|
|
190
193
|
|
|
194
|
+
Contribution 🤝
|
|
195
|
+
===============================================================================
|
|
196
|
+
|
|
197
|
+
Contribution to this project is welcome! However, it must follow the `code of
|
|
198
|
+
conduct
|
|
199
|
+
<https://emcd.github.io/python-project-common/stable/sphinx-html/common/conduct.html>`_
|
|
200
|
+
for the project.
|
|
201
|
+
|
|
202
|
+
Please file bug reports and feature requests in the `issue tracker
|
|
203
|
+
<https://github.com/emcd/python-classcore/issues>`_ or submit `pull
|
|
204
|
+
requests <https://github.com/emcd/python-classcore/pulls>`_ to
|
|
205
|
+
improve the source code or documentation.
|
|
206
|
+
|
|
207
|
+
For development guidance and standards, please see the `development guide
|
|
208
|
+
<https://emcd.github.io/python-classcore/stable/sphinx-html/contribution.html#development>`_.
|
|
209
|
+
|
|
210
|
+
|
|
191
211
|
`More Flair <https://www.imdb.com/title/tt0151804/characters/nm0431918>`_
|
|
192
212
|
===============================================================================
|
|
193
213
|
|
|
@@ -228,24 +248,24 @@ Other Projects by This Author 🌟
|
|
|
228
248
|
===============================================================================
|
|
229
249
|
|
|
230
250
|
|
|
231
|
-
* `python-absence <https://github.com/emcd/python-absence>`_ (`absence <https://pypi.org/project/absence/>`_ on PyPI)
|
|
251
|
+
* `python-absence <https://github.com/emcd/python-absence>`_ (`absence <https://pypi.org/project/absence/>`_ on PyPI)
|
|
232
252
|
|
|
233
253
|
🕳️ A Python library package which provides a **sentinel for absent values** - a falsey, immutable singleton that represents the absence of a value in contexts where ``None`` or ``False`` may be valid values.
|
|
234
|
-
* `python-accretive <https://github.com/emcd/python-accretive>`_ (`accretive <https://pypi.org/project/accretive/>`_ on PyPI)
|
|
254
|
+
* `python-accretive <https://github.com/emcd/python-accretive>`_ (`accretive <https://pypi.org/project/accretive/>`_ on PyPI)
|
|
235
255
|
|
|
236
256
|
🌌 A Python library package which provides **accretive data structures** - collections which can grow but never shrink.
|
|
237
|
-
* `python-dynadoc <https://github.com/emcd/python-dynadoc>`_ (`dynadoc <https://pypi.org/project/dynadoc/>`_ on PyPI)
|
|
257
|
+
* `python-dynadoc <https://github.com/emcd/python-dynadoc>`_ (`dynadoc <https://pypi.org/project/dynadoc/>`_ on PyPI)
|
|
238
258
|
|
|
239
259
|
📝 A Python library package which bridges the gap between **rich annotations** and **automatic documentation generation** with configurable renderers and support for reusable fragments.
|
|
240
|
-
* `python-falsifier <https://github.com/emcd/python-falsifier>`_ (`falsifier <https://pypi.org/project/falsifier/>`_ on PyPI)
|
|
260
|
+
* `python-falsifier <https://github.com/emcd/python-falsifier>`_ (`falsifier <https://pypi.org/project/falsifier/>`_ on PyPI)
|
|
241
261
|
|
|
242
262
|
🎭 A very simple Python library package which provides a **base class for falsey objects** - objects that evaluate to ``False`` in boolean contexts.
|
|
243
|
-
* `python-frigid <https://github.com/emcd/python-frigid>`_ (`frigid <https://pypi.org/project/frigid/>`_ on PyPI)
|
|
263
|
+
* `python-frigid <https://github.com/emcd/python-frigid>`_ (`frigid <https://pypi.org/project/frigid/>`_ on PyPI)
|
|
244
264
|
|
|
245
265
|
🔒 A Python library package which provides **immutable data structures** - collections which cannot be modified after creation.
|
|
246
|
-
* `python-icecream-truck <https://github.com/emcd/python-icecream-truck>`_ (`icecream-truck <https://pypi.org/project/icecream-truck/>`_ on PyPI)
|
|
266
|
+
* `python-icecream-truck <https://github.com/emcd/python-icecream-truck>`_ (`icecream-truck <https://pypi.org/project/icecream-truck/>`_ on PyPI)
|
|
247
267
|
|
|
248
268
|
🍦 **Flavorful Debugging** - A Python library which enhances the powerful and well-known ``icecream`` package with flavored traces, configuration hierarchies, customized outputs, ready-made recipes, and more.
|
|
249
|
-
* `python-mimeogram <https://github.com/emcd/python-mimeogram>`_ (`mimeogram <https://pypi.org/project/mimeogram/>`_ on PyPI)
|
|
269
|
+
* `python-mimeogram <https://github.com/emcd/python-mimeogram>`_ (`mimeogram <https://pypi.org/project/mimeogram/>`_ on PyPI)
|
|
250
270
|
|
|
251
271
|
📨 A command-line tool for **exchanging collections of files with Large Language Models** - bundle multiple files into a single clipboard-ready document while preserving directory structure and metadata... good for code reviews, project sharing, and LLM interactions.
|
|
@@ -59,7 +59,7 @@ gha-runners = [
|
|
|
59
59
|
]
|
|
60
60
|
[tool.coverage.run]
|
|
61
61
|
branch = true
|
|
62
|
-
command_line = '-m pytest'
|
|
62
|
+
command_line = '-m pytest'
|
|
63
63
|
data_file = '.auxiliary/caches/pytest/coverage.sqlite3'
|
|
64
64
|
parallel = true
|
|
65
65
|
source = [ 'sources' ]
|
|
@@ -120,9 +120,9 @@ PYTHONUNBUFFERED = 'TRUE' # TODO: Only for coverage/pytest.
|
|
|
120
120
|
[tool.hatch.envs.develop.scripts]
|
|
121
121
|
docsgen = [
|
|
122
122
|
"""sphinx-build -E -b linkcheck -d .auxiliary/caches/sphinx \
|
|
123
|
-
|
|
123
|
+
documentation .auxiliary/artifacts/sphinx-linkcheck""",
|
|
124
124
|
"""sphinx-build -a -d .auxiliary/caches/sphinx \
|
|
125
|
-
|
|
125
|
+
documentation .auxiliary/artifacts/sphinx-html""",
|
|
126
126
|
]
|
|
127
127
|
linters = [
|
|
128
128
|
"""ruff check --quiet sources documentation tests""",
|
|
@@ -135,14 +135,19 @@ packagers = [
|
|
|
135
135
|
# --- BEGIN: Injected by Copier ---
|
|
136
136
|
# --- END: Injected by Copier ---
|
|
137
137
|
]
|
|
138
|
+
testers-documentation = [
|
|
139
|
+
"""coverage run -m sphinx.cmd.build \
|
|
140
|
+
-E -b doctest -d .auxiliary/caches/sphinx \
|
|
141
|
+
documentation .auxiliary/artifacts/sphinx-doctest""",
|
|
142
|
+
]
|
|
143
|
+
testers-serotine = [ """coverage run -m pytest -m slow""" ]
|
|
138
144
|
testers-no-reports = [
|
|
139
|
-
'coverage erase',
|
|
140
145
|
'coverage run',
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
documentation .auxiliary/artifacts/sphinx-doctest""",
|
|
146
|
+
'testers-documentation',
|
|
147
|
+
'testers-serotine',
|
|
144
148
|
]
|
|
145
149
|
testers = [
|
|
150
|
+
'coverage erase',
|
|
146
151
|
'testers-no-reports',
|
|
147
152
|
'coverage combine',
|
|
148
153
|
'coverage report --skip-covered',
|
|
@@ -184,8 +189,8 @@ strict = false
|
|
|
184
189
|
|
|
185
190
|
# https://microsoft.github.io/pyright/#/configuration
|
|
186
191
|
[tool.pyright]
|
|
187
|
-
ignore = [ 'documentation', 'tests' ] #
|
|
188
|
-
include = [ 'sources' ]
|
|
192
|
+
ignore = [ '.auxiliary', 'documentation', 'tests' ] # Ignore diagnostics.
|
|
193
|
+
include = [ 'sources', 'tests' ] # Consider for operations.
|
|
189
194
|
reportConstantRedefinition = true
|
|
190
195
|
reportInvalidTypeVarUse = true
|
|
191
196
|
reportMatchNotExhaustive = true
|
|
@@ -217,11 +222,14 @@ stubPath = 'sources/classcore/_typedecls'
|
|
|
217
222
|
# Note: Cannot run doctests from Pytest, because Pytest tries to update '_'
|
|
218
223
|
# attribute on protected modules. Instead, we use Sphinx to run doctests.
|
|
219
224
|
minversion = '8.1'
|
|
220
|
-
addopts =
|
|
225
|
+
addopts = """--capture=no --exitfirst -rfE -m 'not slow'""" # TODO? '--fail-under'
|
|
221
226
|
testpaths = [ 'tests' ]
|
|
222
227
|
python_files = [ 'test_*.py' ]
|
|
223
228
|
python_functions = [ 'test_[0-9][0-9][0-9]_*' ]
|
|
224
229
|
cache_dir = '.auxiliary/caches/pytest'
|
|
230
|
+
markers = [
|
|
231
|
+
"slow: long-running tests",
|
|
232
|
+
]
|
|
225
233
|
|
|
226
234
|
[tool.ruff]
|
|
227
235
|
#builtins = [ 'ic' ]
|
|
@@ -272,6 +272,8 @@ def produce_class_construction_postprocessor(
|
|
|
272
272
|
'instances_mutables', __.mutables_default )
|
|
273
273
|
instances_visibles = arguments.get(
|
|
274
274
|
'instances_visibles', __.visibles_default )
|
|
275
|
+
instances_ignore_init_arguments = arguments.get(
|
|
276
|
+
'instances_ignore_init_arguments', False )
|
|
275
277
|
if dcls_spec and dcls_spec.get( 'kw_only_default', False ):
|
|
276
278
|
from .decorators import dataclass_with_standard_behaviors
|
|
277
279
|
decorator_factory = dataclass_with_standard_behaviors
|
|
@@ -289,6 +291,7 @@ def produce_class_construction_postprocessor(
|
|
|
289
291
|
_nomina.DeleterCore, cores[ 'deleter' ] ),
|
|
290
292
|
surveyor_core = __.typx.cast(
|
|
291
293
|
_nomina.SurveyorCore, cores[ 'surveyor' ] ),
|
|
294
|
+
ignore_init_arguments = instances_ignore_init_arguments,
|
|
292
295
|
mutables = instances_mutables,
|
|
293
296
|
visibles = instances_visibles )
|
|
294
297
|
decorators.append( decorator )
|
|
@@ -391,6 +394,7 @@ def record_class_construction_arguments(
|
|
|
391
394
|
'instances_assigner_core',
|
|
392
395
|
'instances_deleter_core',
|
|
393
396
|
'instances_surveyor_core',
|
|
397
|
+
'instances_ignore_init_arguments',
|
|
394
398
|
'instances_mutables', 'instances_visibles',
|
|
395
399
|
):
|
|
396
400
|
if name not in arguments: continue
|
|
@@ -42,6 +42,7 @@ class ClassFactoryExtraArguments( __.typx.TypedDict, total = False ):
|
|
|
42
42
|
instances_assigner_core: _nomina.AssignerCore
|
|
43
43
|
instances_deleter_core: _nomina.DeleterCore
|
|
44
44
|
instances_surveyor_core: _nomina.SurveyorCore
|
|
45
|
+
instances_ignore_init_arguments: bool
|
|
45
46
|
instances_mutables: _nomina.BehaviorExclusionVerifiersOmni
|
|
46
47
|
instances_visibles: _nomina.BehaviorExclusionVerifiersOmni
|
|
47
48
|
|
|
@@ -220,15 +220,19 @@ def class_factory( # noqa: PLR0913
|
|
|
220
220
|
return decorate
|
|
221
221
|
|
|
222
222
|
|
|
223
|
-
def
|
|
223
|
+
def produce_instances_inception_decorator( # noqa: PLR0913
|
|
224
224
|
attributes_namer: _nomina.AttributesNamer,
|
|
225
225
|
assigner_core: __.typx.Optional[ _nomina.AssignerCore ],
|
|
226
226
|
deleter_core: __.typx.Optional[ _nomina.DeleterCore ],
|
|
227
227
|
surveyor_core: __.typx.Optional[ _nomina.SurveyorCore ],
|
|
228
|
+
ignore_init_arguments: bool,
|
|
228
229
|
mutables: _nomina.BehaviorExclusionVerifiersOmni,
|
|
229
230
|
visibles: _nomina.BehaviorExclusionVerifiersOmni,
|
|
230
231
|
) -> _nomina.Decorator[ __.U ]:
|
|
231
|
-
''' Produces decorator to inject '__init__' method
|
|
232
|
+
''' Produces decorator to inject '__new__' or '__init__' method.
|
|
233
|
+
|
|
234
|
+
Also handles common bookkeeping tasks.
|
|
235
|
+
'''
|
|
232
236
|
cores = dict(
|
|
233
237
|
instances_assigner_core = assigner_core,
|
|
234
238
|
instances_deleter_core = deleter_core,
|
|
@@ -249,7 +253,6 @@ def produce_instances_initialization_decorator( # noqa: PLR0913
|
|
|
249
253
|
core_aname = attributes_namer( 'instances', f"{core_name}_core" )
|
|
250
254
|
setattr( cls, core_aname, core_function )
|
|
251
255
|
behaviors: set[ str ] = set( )
|
|
252
|
-
behaviors_name = attributes_namer( 'instance', 'behaviors' )
|
|
253
256
|
_behaviors.record_behavior(
|
|
254
257
|
cls, attributes_namer = attributes_namer,
|
|
255
258
|
level = 'instances', basename = 'mutables',
|
|
@@ -260,6 +263,66 @@ def produce_instances_initialization_decorator( # noqa: PLR0913
|
|
|
260
263
|
level = 'instances', basename = 'visibles',
|
|
261
264
|
label = _nomina.concealment_label, behaviors = behaviors,
|
|
262
265
|
verifiers = visibles )
|
|
266
|
+
decorator = produce_instances_initialization_decorator(
|
|
267
|
+
attributes_namer = attributes_namer,
|
|
268
|
+
behaviors = behaviors,
|
|
269
|
+
ignore_init_arguments = ignore_init_arguments )
|
|
270
|
+
return decorator( cls )
|
|
271
|
+
|
|
272
|
+
return decorate
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
# def produce_instances_construction_decorator(
|
|
276
|
+
# attributes_namer: _nomina.AttributesNamer,
|
|
277
|
+
# behaviors: __.cabc.MutableSet[ str ],
|
|
278
|
+
# ) -> _nomina.Decorator[ __.U ]:
|
|
279
|
+
# ''' Produces decorator to inject '__new__' method. '''
|
|
280
|
+
# def decorate( cls_: type[ __.U ] ) -> type[ __.U ]:
|
|
281
|
+
# behaviors_name = attributes_namer( 'instance', 'behaviors' )
|
|
282
|
+
# original = cls_.__dict__.get( '__new__' )
|
|
283
|
+
#
|
|
284
|
+
# if original is None:
|
|
285
|
+
#
|
|
286
|
+
# def initialize_with_super(
|
|
287
|
+
# cls: type[ __.U ],
|
|
288
|
+
# *posargs: __.typx.Any,
|
|
289
|
+
# **nomargs: __.typx.Any,
|
|
290
|
+
# ) -> __.U:
|
|
291
|
+
# self = super( cls_, cls ).__new__( cls, *posargs, **nomargs )
|
|
292
|
+
# _activate_instance_behaviors(
|
|
293
|
+
# cls_, self, behaviors_name, behaviors )
|
|
294
|
+
# return self
|
|
295
|
+
#
|
|
296
|
+
# cls_.__new__ = initialize_with_super
|
|
297
|
+
#
|
|
298
|
+
# else:
|
|
299
|
+
#
|
|
300
|
+
# @__.funct.wraps( original )
|
|
301
|
+
# def initialize_with_original(
|
|
302
|
+
# cls: type[ __.U ],
|
|
303
|
+
# *posargs: __.typx.Any,
|
|
304
|
+
# **nomargs: __.typx.Any,
|
|
305
|
+
# ) -> __.U:
|
|
306
|
+
# self = original( cls, *posargs, **nomargs )
|
|
307
|
+
# _activate_instance_behaviors(
|
|
308
|
+
# cls_, self, behaviors_name, behaviors )
|
|
309
|
+
# return self
|
|
310
|
+
#
|
|
311
|
+
# cls_.__new__ = initialize_with_original
|
|
312
|
+
#
|
|
313
|
+
# return cls_
|
|
314
|
+
#
|
|
315
|
+
# return decorate
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def produce_instances_initialization_decorator(
|
|
319
|
+
attributes_namer: _nomina.AttributesNamer,
|
|
320
|
+
behaviors: __.cabc.MutableSet[ str ],
|
|
321
|
+
ignore_init_arguments: bool,
|
|
322
|
+
) -> _nomina.Decorator[ __.U ]:
|
|
323
|
+
''' Produces decorator to inject '__init__' method into class. '''
|
|
324
|
+
def decorate( cls: type[ __.U ] ) -> type[ __.U ]:
|
|
325
|
+
behaviors_name = attributes_namer( 'instance', 'behaviors' )
|
|
263
326
|
original = cls.__dict__.get( '__init__' )
|
|
264
327
|
|
|
265
328
|
if original is None:
|
|
@@ -267,14 +330,10 @@ def produce_instances_initialization_decorator( # noqa: PLR0913
|
|
|
267
330
|
def initialize_with_super(
|
|
268
331
|
self: object, *posargs: __.typx.Any, **nomargs: __.typx.Any
|
|
269
332
|
) -> None:
|
|
270
|
-
super( cls, self ).__init__(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
_utilities.getattr0( self, behaviors_name, set( ) ) )
|
|
275
|
-
behaviors_.update( behaviors )
|
|
276
|
-
_utilities.setattr0(
|
|
277
|
-
self, behaviors_name, frozenset( behaviors_ ) )
|
|
333
|
+
if ignore_init_arguments: super( cls, self ).__init__( )
|
|
334
|
+
else: super( cls, self ).__init__( *posargs, **nomargs )
|
|
335
|
+
_activate_instance_behaviors(
|
|
336
|
+
cls, self, behaviors_name, behaviors )
|
|
278
337
|
|
|
279
338
|
cls.__init__ = initialize_with_super
|
|
280
339
|
|
|
@@ -284,14 +343,10 @@ def produce_instances_initialization_decorator( # noqa: PLR0913
|
|
|
284
343
|
def initialize_with_original(
|
|
285
344
|
self: object, *posargs: __.typx.Any, **nomargs: __.typx.Any
|
|
286
345
|
) -> None:
|
|
287
|
-
original( self
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
_utilities.getattr0( self, behaviors_name, set( ) ) )
|
|
292
|
-
behaviors_.update( behaviors )
|
|
293
|
-
_utilities.setattr0(
|
|
294
|
-
self, behaviors_name, frozenset( behaviors_ ) )
|
|
346
|
+
if ignore_init_arguments: original( self )
|
|
347
|
+
else: original( self, *posargs, **nomargs )
|
|
348
|
+
_activate_instance_behaviors(
|
|
349
|
+
cls, self, behaviors_name, behaviors )
|
|
295
350
|
|
|
296
351
|
cls.__init__ = initialize_with_original
|
|
297
352
|
|
|
@@ -484,6 +539,7 @@ def dataclass_with_standard_behaviors( # noqa: PLR0913
|
|
|
484
539
|
assigner_core: __.typx.Optional[ _nomina.AssignerCore ] = None,
|
|
485
540
|
deleter_core: __.typx.Optional[ _nomina.DeleterCore ] = None,
|
|
486
541
|
surveyor_core: __.typx.Optional[ _nomina.SurveyorCore ] = None,
|
|
542
|
+
ignore_init_arguments: bool = False,
|
|
487
543
|
mutables: _nomina.BehaviorExclusionVerifiersOmni = __.mutables_default,
|
|
488
544
|
visibles: _nomina.BehaviorExclusionVerifiersOmni = __.visibles_default,
|
|
489
545
|
) -> _nomina.Decorator[ __.U ]:
|
|
@@ -496,6 +552,7 @@ def dataclass_with_standard_behaviors( # noqa: PLR0913
|
|
|
496
552
|
assigner_core = assigner_core,
|
|
497
553
|
deleter_core = deleter_core,
|
|
498
554
|
surveyor_core = surveyor_core,
|
|
555
|
+
ignore_init_arguments = ignore_init_arguments,
|
|
499
556
|
mutables = mutables,
|
|
500
557
|
visibles = visibles ) )
|
|
501
558
|
preparers: _nomina.DecorationPreparers[ __.U ] = (
|
|
@@ -514,6 +571,7 @@ def with_standard_behaviors( # noqa: PLR0913
|
|
|
514
571
|
assigner_core: __.typx.Optional[ _nomina.AssignerCore ] = None,
|
|
515
572
|
deleter_core: __.typx.Optional[ _nomina.DeleterCore ] = None,
|
|
516
573
|
surveyor_core: __.typx.Optional[ _nomina.SurveyorCore ] = None,
|
|
574
|
+
ignore_init_arguments: bool = False,
|
|
517
575
|
mutables: _nomina.BehaviorExclusionVerifiersOmni = __.mutables_default,
|
|
518
576
|
visibles: _nomina.BehaviorExclusionVerifiersOmni = __.visibles_default,
|
|
519
577
|
) -> _nomina.Decorator[ __.U ]:
|
|
@@ -525,6 +583,7 @@ def with_standard_behaviors( # noqa: PLR0913
|
|
|
525
583
|
assigner_core = assigner_core,
|
|
526
584
|
deleter_core = deleter_core,
|
|
527
585
|
surveyor_core = surveyor_core,
|
|
586
|
+
ignore_init_arguments = ignore_init_arguments,
|
|
528
587
|
mutables = mutables,
|
|
529
588
|
visibles = visibles ) )
|
|
530
589
|
preparers: _nomina.DecorationPreparers[ __.U ] = (
|
|
@@ -534,6 +593,20 @@ def with_standard_behaviors( # noqa: PLR0913
|
|
|
534
593
|
return decoration_by( *decorators, *decorators_, preparers = preparers )
|
|
535
594
|
|
|
536
595
|
|
|
596
|
+
def _activate_instance_behaviors(
|
|
597
|
+
cls: type[ __.U ],
|
|
598
|
+
self: object,
|
|
599
|
+
behaviors_name: str,
|
|
600
|
+
behaviors: __.cabc.MutableSet[ str ],
|
|
601
|
+
) -> None:
|
|
602
|
+
# Only record behaviors at start of MRO.
|
|
603
|
+
if cls is not type( self ): return
|
|
604
|
+
behaviors_: set[ str ] = (
|
|
605
|
+
_utilities.getattr0( self, behaviors_name, set( ) ) )
|
|
606
|
+
behaviors_.update( behaviors )
|
|
607
|
+
_utilities.setattr0( self, behaviors_name, frozenset( behaviors_ ) )
|
|
608
|
+
|
|
609
|
+
|
|
537
610
|
def _produce_instances_decoration_preparers(
|
|
538
611
|
attributes_namer: _nomina.AttributesNamer,
|
|
539
612
|
error_class_provider: _nomina.ErrorClassProvider,
|
|
@@ -554,17 +627,19 @@ def _produce_instances_decorators( # noqa: PLR0913
|
|
|
554
627
|
assigner_core: __.typx.Optional[ _nomina.AssignerCore ],
|
|
555
628
|
deleter_core: __.typx.Optional[ _nomina.DeleterCore ],
|
|
556
629
|
surveyor_core: __.typx.Optional[ _nomina.SurveyorCore ],
|
|
630
|
+
ignore_init_arguments: bool,
|
|
557
631
|
mutables: _nomina.BehaviorExclusionVerifiersOmni,
|
|
558
632
|
visibles: _nomina.BehaviorExclusionVerifiersOmni,
|
|
559
633
|
) -> _nomina.Decorators[ __.U ]:
|
|
560
634
|
''' Produces standard decorators. '''
|
|
561
635
|
decorators: list[ _nomina.Decorator[ __.U ] ] = [ ]
|
|
562
636
|
decorators.append(
|
|
563
|
-
|
|
637
|
+
produce_instances_inception_decorator(
|
|
564
638
|
attributes_namer = attributes_namer,
|
|
565
639
|
assigner_core = assigner_core,
|
|
566
640
|
deleter_core = deleter_core,
|
|
567
641
|
surveyor_core = surveyor_core,
|
|
642
|
+
ignore_init_arguments = ignore_init_arguments,
|
|
568
643
|
mutables = mutables, visibles = visibles ) )
|
|
569
644
|
decorators.append(
|
|
570
645
|
produce_attributes_assignment_decorator(
|
|
@@ -42,6 +42,10 @@ def finalize_module( # noqa: PLR0913
|
|
|
42
42
|
dynadoc_introspection: _nomina.DynadocIntrospectionArgument = (
|
|
43
43
|
_dynadoc.dynadoc_introspection_on_package ),
|
|
44
44
|
dynadoc_table: _nomina.DynadocTableArgument = __.dictproxy_empty,
|
|
45
|
+
excludes: __.typx.Annotated[
|
|
46
|
+
__.typx.Optional[ __.cabc.MutableSet[ __.types.ModuleType ] ],
|
|
47
|
+
__.ddoc.Doc( ''' Modules to exclude from reclassification. ''' ),
|
|
48
|
+
] = None,
|
|
45
49
|
recursive: __.typx.Annotated[
|
|
46
50
|
bool, __.ddoc.Doc( ''' Recursively reclassify package modules? ''' )
|
|
47
51
|
] = False,
|
|
@@ -84,7 +88,7 @@ def finalize_module( # noqa: PLR0913
|
|
|
84
88
|
_reclassify_module(
|
|
85
89
|
module,
|
|
86
90
|
attributes_namer = attributes_namer,
|
|
87
|
-
recursive = recursive,
|
|
91
|
+
excludes = excludes, recursive = recursive,
|
|
88
92
|
replacement_class = replacement_class )
|
|
89
93
|
|
|
90
94
|
|
|
@@ -100,6 +104,10 @@ def reclassify_modules(
|
|
|
100
104
|
__.ddoc.Doc(
|
|
101
105
|
''' Attributes namer function with which to seal class. ''' ),
|
|
102
106
|
] = __.calculate_attrname,
|
|
107
|
+
excludes: __.typx.Annotated[
|
|
108
|
+
__.typx.Optional[ __.cabc.MutableSet[ __.types.ModuleType ] ],
|
|
109
|
+
__.ddoc.Doc( ''' Modules to exclude from reclassification. ''' ),
|
|
110
|
+
] = None,
|
|
103
111
|
recursive: __.typx.Annotated[
|
|
104
112
|
bool, __.ddoc.Doc( ''' Recursively reclassify package modules? ''' )
|
|
105
113
|
] = False,
|
|
@@ -123,11 +131,11 @@ def reclassify_modules(
|
|
|
123
131
|
_reclassify_module(
|
|
124
132
|
attributes,
|
|
125
133
|
attributes_namer = attributes_namer,
|
|
126
|
-
recursive = recursive,
|
|
134
|
+
excludes = excludes, recursive = recursive,
|
|
127
135
|
replacement_class = replacement_class )
|
|
128
136
|
|
|
129
137
|
|
|
130
|
-
def _reclassify_module(
|
|
138
|
+
def _reclassify_module( # noqa: C901,PLR0912
|
|
131
139
|
attributes: __.typx.Annotated[
|
|
132
140
|
__.cabc.Mapping[ str, __.typx.Any ] | __.types.ModuleType | str,
|
|
133
141
|
__.ddoc.Doc(
|
|
@@ -138,6 +146,10 @@ def _reclassify_module(
|
|
|
138
146
|
__.ddoc.Doc(
|
|
139
147
|
''' Attributes namer function with which to seal class. ''' ),
|
|
140
148
|
] = __.calculate_attrname,
|
|
149
|
+
excludes: __.typx.Annotated[
|
|
150
|
+
__.typx.Optional[ __.cabc.MutableSet[ __.types.ModuleType ] ],
|
|
151
|
+
__.ddoc.Doc( ''' Modules to exclude from reclassification. ''' ),
|
|
152
|
+
] = None,
|
|
141
153
|
recursive: __.typx.Annotated[
|
|
142
154
|
bool, __.ddoc.Doc( ''' Recursively reclassify package modules? ''' )
|
|
143
155
|
] = False,
|
|
@@ -164,22 +176,24 @@ def _reclassify_module(
|
|
|
164
176
|
attributes = __.sys.modules[ attributes ]
|
|
165
177
|
if isinstance( attributes, __.types.ModuleType ):
|
|
166
178
|
module = attributes
|
|
167
|
-
|
|
179
|
+
if excludes and module in excludes: return
|
|
180
|
+
attributes = module.__dict__
|
|
168
181
|
else: module = None
|
|
182
|
+
if excludes is None: excludes = set( )
|
|
183
|
+
if module: excludes.add( module )
|
|
169
184
|
package_name = (
|
|
170
185
|
attributes.get( '__package__' ) or attributes.get( '__name__' ) )
|
|
171
186
|
if not package_name: return
|
|
172
187
|
for value in attributes.values( ):
|
|
173
188
|
if not __.inspect.ismodule( value ): continue
|
|
174
189
|
if not value.__name__.startswith( f"{package_name}." ): continue
|
|
190
|
+
if isinstance( value, replacement_class ): continue
|
|
175
191
|
if recursive:
|
|
176
192
|
_reclassify_module(
|
|
177
193
|
value,
|
|
178
194
|
attributes_namer = attributes_namer,
|
|
179
|
-
recursive = True,
|
|
195
|
+
excludes = excludes, recursive = True,
|
|
180
196
|
replacement_class = replacement_class )
|
|
181
|
-
if isinstance( value, replacement_class ): continue
|
|
182
|
-
_seal_module( value, attributes_namer, replacement_class )
|
|
183
197
|
if module and not isinstance( module, replacement_class ):
|
|
184
198
|
_seal_module( module, attributes_namer, replacement_class )
|
|
185
199
|
|
|
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
|