classcore 1.1__tar.gz → 1.2rc0__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.2rc0/.gitignore +7 -0
- {classcore-1.1 → classcore-1.2rc0}/PKG-INFO +17 -19
- {classcore-1.1 → classcore-1.2rc0}/README.rst +15 -18
- {classcore-1.1 → classcore-1.2rc0}/pyproject.toml +4 -1
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/__/__init__.py +8 -0
- classcore-1.2rc0/sources/classcore/__/doctab.py +76 -0
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/__/imports.py +1 -5
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/__/nomina.py +2 -3
- classcore-1.2rc0/sources/classcore/__init__.py +69 -0
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/decorators.py +14 -17
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/exceptions.py +2 -4
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/factories.py +9 -13
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/nomina.py +42 -27
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/standard/__.py +0 -2
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/standard/__init__.py +26 -2
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/standard/behaviors.py +27 -17
- classcore-1.2rc0/sources/classcore/standard/classes.py +242 -0
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/standard/decorators.py +143 -76
- classcore-1.2rc0/sources/classcore/standard/dynadoc.py +129 -0
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/standard/modules.py +11 -14
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/standard/nomina.py +45 -4
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/utilities.py +5 -5
- classcore-1.1/.gitignore +0 -4
- classcore-1.1/sources/classcore/__init__.py +0 -38
- classcore-1.1/sources/classcore/standard/classes.py +0 -92
- {classcore-1.1 → classcore-1.2rc0}/LICENSE.txt +0 -0
- {classcore-1.1 → classcore-1.2rc0}/sources/classcore/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: classcore
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2rc0
|
|
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
|
|
@@ -23,6 +23,7 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
|
23
23
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
24
24
|
Classifier: Topic :: Software Development
|
|
25
25
|
Requires-Python: >=3.10
|
|
26
|
+
Requires-Dist: dynadoc
|
|
26
27
|
Requires-Dist: typing-extensions
|
|
27
28
|
Description-Content-Type: text/x-rst
|
|
28
29
|
|
|
@@ -256,27 +257,24 @@ Other Projects by This Author 🌟
|
|
|
256
257
|
===============================================================================
|
|
257
258
|
|
|
258
259
|
|
|
259
|
-
* `python-absence <https://github.com/emcd/python-absence>`_
|
|
260
|
-
- PyPI: `absence <https://pypi.org/project/absence/>`_
|
|
260
|
+
* `python-absence <https://github.com/emcd/python-absence>`_ (`absence <https://pypi.org/project/absence/>`_ on PyPI)
|
|
261
261
|
|
|
262
|
-
|
|
263
|
-
* `python-accretive <https://github.com/emcd/python-accretive>`_
|
|
264
|
-
- PyPI: `accretive <https://pypi.org/project/accretive/>`_
|
|
262
|
+
🕳️ 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)
|
|
265
264
|
|
|
266
|
-
|
|
267
|
-
* `python-
|
|
268
|
-
- PyPI: `falsifier <https://pypi.org/project/falsifier/>`_
|
|
265
|
+
🌌 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)
|
|
269
267
|
|
|
270
|
-
|
|
271
|
-
* `python-
|
|
272
|
-
- PyPI: `frigid <https://pypi.org/project/frigid/>`_
|
|
268
|
+
📝 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)
|
|
273
270
|
|
|
274
|
-
|
|
275
|
-
* `python-
|
|
276
|
-
- PyPI: `icecream-truck <https://pypi.org/project/icecream-truck/>`_
|
|
271
|
+
🎭 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)
|
|
277
273
|
|
|
278
|
-
|
|
279
|
-
* `python-
|
|
280
|
-
- PyPI: `mimeogram <https://pypi.org/project/mimeogram/>`_
|
|
274
|
+
🔒 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)
|
|
281
276
|
|
|
282
|
-
|
|
277
|
+
🍦 **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)
|
|
279
|
+
|
|
280
|
+
📨 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.
|
|
@@ -228,27 +228,24 @@ Other Projects by This Author 🌟
|
|
|
228
228
|
===============================================================================
|
|
229
229
|
|
|
230
230
|
|
|
231
|
-
* `python-absence <https://github.com/emcd/python-absence>`_
|
|
232
|
-
- PyPI: `absence <https://pypi.org/project/absence/>`_
|
|
231
|
+
* `python-absence <https://github.com/emcd/python-absence>`_ (`absence <https://pypi.org/project/absence/>`_ on PyPI)
|
|
233
232
|
|
|
234
|
-
|
|
235
|
-
* `python-accretive <https://github.com/emcd/python-accretive>`_
|
|
236
|
-
- PyPI: `accretive <https://pypi.org/project/accretive/>`_
|
|
233
|
+
🕳️ 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)
|
|
237
235
|
|
|
238
|
-
|
|
239
|
-
* `python-
|
|
240
|
-
- PyPI: `falsifier <https://pypi.org/project/falsifier/>`_
|
|
236
|
+
🌌 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)
|
|
241
238
|
|
|
242
|
-
|
|
243
|
-
* `python-
|
|
244
|
-
- PyPI: `frigid <https://pypi.org/project/frigid/>`_
|
|
239
|
+
📝 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)
|
|
245
241
|
|
|
246
|
-
|
|
247
|
-
* `python-
|
|
248
|
-
- PyPI: `icecream-truck <https://pypi.org/project/icecream-truck/>`_
|
|
242
|
+
🎭 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)
|
|
249
244
|
|
|
250
|
-
|
|
251
|
-
* `python-
|
|
252
|
-
- PyPI: `mimeogram <https://pypi.org/project/mimeogram/>`_
|
|
245
|
+
🔒 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)
|
|
253
247
|
|
|
254
|
-
|
|
248
|
+
🍦 **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)
|
|
250
|
+
|
|
251
|
+
📨 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.
|
|
@@ -15,6 +15,7 @@ license = 'Apache-2.0'
|
|
|
15
15
|
readme = { 'file' = 'README.rst', 'content-type' = 'text/x-rst' }
|
|
16
16
|
requires-python = '>= 3.10'
|
|
17
17
|
dependencies = [
|
|
18
|
+
'dynadoc',
|
|
18
19
|
'typing-extensions',
|
|
19
20
|
# --- BEGIN: Injected by Copier ---
|
|
20
21
|
# --- END: Injected by Copier ---
|
|
@@ -166,6 +167,8 @@ python = [
|
|
|
166
167
|
'3.13',
|
|
167
168
|
'pypy3.10',
|
|
168
169
|
]
|
|
170
|
+
# [tool.hatch.metadata]
|
|
171
|
+
# allow-direct-references = true
|
|
169
172
|
[tool.hatch.version]
|
|
170
173
|
path = 'sources/classcore/__init__.py'
|
|
171
174
|
|
|
@@ -182,7 +185,7 @@ strict = false
|
|
|
182
185
|
|
|
183
186
|
# https://microsoft.github.io/pyright/#/configuration
|
|
184
187
|
[tool.pyright]
|
|
185
|
-
ignore = [ 'tests' ] # Stronger hint for language server.
|
|
188
|
+
ignore = [ 'documentation', 'tests' ] # Stronger hint for language server.
|
|
186
189
|
include = [ 'sources' ]
|
|
187
190
|
reportConstantRedefinition = true
|
|
188
191
|
reportInvalidTypeVarUse = true
|
|
@@ -21,5 +21,13 @@
|
|
|
21
21
|
''' Common constants, imports, and utilities. '''
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
from .doctab import *
|
|
24
25
|
from .imports import *
|
|
25
26
|
from .nomina import *
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
T = typx.TypeVar( 'T', bound = type )
|
|
30
|
+
U = typx.TypeVar( 'U' )
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
dictproxy_empty: cabc.Mapping[ str, str ] = types.MappingProxyType( { } )
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# vim: set filetype=python fileencoding=utf-8:
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
#============================================================================#
|
|
5
|
+
# #
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); #
|
|
7
|
+
# you may not use this file except in compliance with the License. #
|
|
8
|
+
# You may obtain a copy of the License at #
|
|
9
|
+
# #
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0 #
|
|
11
|
+
# #
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software #
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
15
|
+
# See the License for the specific language governing permissions and #
|
|
16
|
+
# limitations under the License. #
|
|
17
|
+
# #
|
|
18
|
+
#============================================================================#
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
''' Docstring fragments. '''
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
from . import imports as __
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
_FragmentsTable: __.typx.TypeAlias = __.cabc.Mapping[ str, str ]
|
|
28
|
+
fragments: _FragmentsTable = __.types.MappingProxyType( {
|
|
29
|
+
|
|
30
|
+
'cfc class conceal':
|
|
31
|
+
''' By default, conceals non-public class attributes. ''',
|
|
32
|
+
|
|
33
|
+
'cfc class protect':
|
|
34
|
+
''' By default, protects class attributes. ''',
|
|
35
|
+
|
|
36
|
+
'cfc dynadoc': ''' Applies Dynadoc decoration to classes. ''',
|
|
37
|
+
|
|
38
|
+
'cfc instance conceal':
|
|
39
|
+
''' Produces classes which can conceal instance attributes. ''',
|
|
40
|
+
|
|
41
|
+
'cfc instance protect':
|
|
42
|
+
''' Produces classes which can protect instance attributes. ''',
|
|
43
|
+
|
|
44
|
+
'cfc produce dataclass':
|
|
45
|
+
''' Produces inheritable dataclasses with keyword-only instantiation. ''',
|
|
46
|
+
|
|
47
|
+
'cfc produce protocol class':
|
|
48
|
+
''' Produces :pep:`544` protocol classes. ''',
|
|
49
|
+
|
|
50
|
+
'class concealment':
|
|
51
|
+
''' By default, non-public class attributes are invisible. ''',
|
|
52
|
+
|
|
53
|
+
'class protection':
|
|
54
|
+
''' By default, class attributes are immutable. ''',
|
|
55
|
+
|
|
56
|
+
'class instance conceal':
|
|
57
|
+
''' By default, conceals non-public instance attributes. ''',
|
|
58
|
+
|
|
59
|
+
'class instance protect':
|
|
60
|
+
''' By default, protects instance attributes. ''',
|
|
61
|
+
|
|
62
|
+
'dataclass':
|
|
63
|
+
''' Inheritable dataclass with keyword-only instantiation. ''',
|
|
64
|
+
|
|
65
|
+
'protocol class':
|
|
66
|
+
''' Protocol class (:pep:`544`). Nominal and structural subtyping. ''',
|
|
67
|
+
|
|
68
|
+
'class dynadoc': ''' Is decorated by Dynadoc. ''',
|
|
69
|
+
|
|
70
|
+
'decorators':
|
|
71
|
+
''' Sequence of class decorators.
|
|
72
|
+
|
|
73
|
+
Each element takes a class argument and returns a class.
|
|
74
|
+
''',
|
|
75
|
+
|
|
76
|
+
} )
|
|
@@ -23,8 +23,6 @@
|
|
|
23
23
|
# ruff: noqa: F401
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
from __future__ import annotations
|
|
27
|
-
|
|
28
26
|
import collections.abc as cabc
|
|
29
27
|
import dataclasses as dcls
|
|
30
28
|
import functools as funct
|
|
@@ -35,9 +33,7 @@ import re
|
|
|
35
33
|
import sys
|
|
36
34
|
import types
|
|
37
35
|
|
|
36
|
+
import dynadoc
|
|
38
37
|
import typing_extensions as typx
|
|
39
38
|
# --- BEGIN: Injected by Copier ---
|
|
40
39
|
# --- END: Injected by Copier ---
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
ComparisonResult: typx.TypeAlias = bool | types.NotImplementedType
|
|
@@ -18,14 +18,13 @@
|
|
|
18
18
|
#============================================================================#
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
'''
|
|
21
|
+
''' Common names and type aliases. '''
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
from __future__ import annotations
|
|
25
|
-
|
|
26
24
|
from . import imports as __
|
|
27
25
|
|
|
28
26
|
|
|
27
|
+
ComparisonResult: __.typx.TypeAlias = bool | __.types.NotImplementedType
|
|
29
28
|
NominativeArguments: __.typx.TypeAlias = __.cabc.Mapping[ str, __.typx.Any ]
|
|
30
29
|
PositionalArguments: __.typx.TypeAlias = __.cabc.Sequence[ __.typx.Any ]
|
|
31
30
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# vim: set filetype=python fileencoding=utf-8:
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
#============================================================================#
|
|
5
|
+
# #
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); #
|
|
7
|
+
# you may not use this file except in compliance with the License. #
|
|
8
|
+
# You may obtain a copy of the License at #
|
|
9
|
+
# #
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0 #
|
|
11
|
+
# #
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software #
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS, #
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
|
15
|
+
# See the License for the specific language governing permissions and #
|
|
16
|
+
# limitations under the License. #
|
|
17
|
+
# #
|
|
18
|
+
#============================================================================#
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
''' Foundational class factories and decorators.
|
|
22
|
+
|
|
23
|
+
Provides ability to create class decorators and metaclasses
|
|
24
|
+
with customization hooks. The metaclasses can apply class decorators
|
|
25
|
+
inline during the class construction and initialization process, properly
|
|
26
|
+
handling cases where decorators replace classes (e.g.,
|
|
27
|
+
``dataclasses.dataclass( slots = True )``). They also backport the repair
|
|
28
|
+
mechanism from newer versions of CPython to ensure that the class closure
|
|
29
|
+
cells are rectified on replaced classes, so that zero-argument ``super``
|
|
30
|
+
calls function correctly in them.
|
|
31
|
+
|
|
32
|
+
The ``classcore.standard`` subpackage is an example of the decorators and
|
|
33
|
+
customization hooks being used to provide a set of practical classes and
|
|
34
|
+
class decorators. Furthermore, the exception classes in the
|
|
35
|
+
:py:mod:`classcore.exceptions` module inherit from one of the standard
|
|
36
|
+
classes, making both the exception classes, themselves, and their
|
|
37
|
+
instances immutable and concealing their non-public attributes to reduce
|
|
38
|
+
API noise. I.e., this package "eats its own dog food" and provides
|
|
39
|
+
practical examples in so doing.
|
|
40
|
+
|
|
41
|
+
This package is not as magical as it might seem. It does **not** rely on
|
|
42
|
+
any ``exec`` or ``eval`` calls and it does **not** do anything with
|
|
43
|
+
``ctypes`` or similar surgical instruments. It relies completely on the
|
|
44
|
+
documented Python data model and the machinery that it provides. While it
|
|
45
|
+
is true that metaclasses can be tricky, this package is developed with a
|
|
46
|
+
deep, highly-evolved understanding of them. We seek simplicity over
|
|
47
|
+
cleverness and maintain robust tests across multiple Python
|
|
48
|
+
implementations and versions. The package is also very clean in terms of
|
|
49
|
+
static type checking (via Pyright).
|
|
50
|
+
'''
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
from . import __
|
|
54
|
+
from . import exceptions
|
|
55
|
+
from . import nomina
|
|
56
|
+
from . import standard
|
|
57
|
+
# --- BEGIN: Injected by Copier ---
|
|
58
|
+
# --- END: Injected by Copier ---
|
|
59
|
+
|
|
60
|
+
from .decorators import *
|
|
61
|
+
from .factories import *
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
__version__: __.typx.Annotated[ str, __.dynadoc.Visibilities.Reveal ]
|
|
65
|
+
__version__ = '1.2rc0'
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
standard.dynadoc.assign_module_docstring( __name__, table = __.fragments )
|
|
69
|
+
standard.reclassify_modules( __name__, recursive = True )
|
|
@@ -21,17 +21,14 @@
|
|
|
21
21
|
''' Utilities for the decoration of classes, including metaclasses. '''
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
from __future__ import annotations
|
|
25
|
-
|
|
26
24
|
from . import __
|
|
27
25
|
from . import nomina as _nomina
|
|
28
26
|
from . import utilities as _utilities
|
|
29
27
|
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def apply_decorators( cls: type, decorators: _nomina.Decorators ) -> type:
|
|
29
|
+
def apply_decorators(
|
|
30
|
+
cls: type[ __.U ], decorators: _nomina.Decorators[ __.U ]
|
|
31
|
+
) -> type:
|
|
35
32
|
''' Applies sequence of decorators to class.
|
|
36
33
|
|
|
37
34
|
If decorators replace classes (e.g., ``dataclass( slots = True )``),
|
|
@@ -49,9 +46,9 @@ def apply_decorators( cls: type, decorators: _nomina.Decorators ) -> type:
|
|
|
49
46
|
|
|
50
47
|
|
|
51
48
|
def decoration_by(
|
|
52
|
-
*decorators: _nomina.Decorator,
|
|
53
|
-
preparers: _nomina.DecorationPreparers = ( ),
|
|
54
|
-
) -> _nomina.Decorator:
|
|
49
|
+
*decorators: _nomina.Decorator[ __.U ],
|
|
50
|
+
preparers: _nomina.DecorationPreparers[ __.U ] = ( ),
|
|
51
|
+
) -> _nomina.Decorator[ __.U ]:
|
|
55
52
|
''' Class decorator which applies other class decorators.
|
|
56
53
|
|
|
57
54
|
Useful to apply a stack of decorators as a sequence.
|
|
@@ -61,7 +58,7 @@ def decoration_by(
|
|
|
61
58
|
decorators list itself, such as to inject decorators based on
|
|
62
59
|
introspection of the class.
|
|
63
60
|
'''
|
|
64
|
-
def decorate( cls: type ) -> type:
|
|
61
|
+
def decorate( cls: type[ __.U ] ) -> type[ __.U ]:
|
|
65
62
|
decorators_ = list( decorators )
|
|
66
63
|
for preparer in preparers: preparer( cls, decorators_ )
|
|
67
64
|
return apply_decorators( cls, decorators_ )
|
|
@@ -71,24 +68,24 @@ def decoration_by(
|
|
|
71
68
|
|
|
72
69
|
def produce_class_construction_decorator(
|
|
73
70
|
attributes_namer: _nomina.AttributesNamer,
|
|
74
|
-
constructor: _nomina.ClassConstructor,
|
|
75
|
-
) -> _nomina.Decorator:
|
|
71
|
+
constructor: _nomina.ClassConstructor[ __.T ],
|
|
72
|
+
) -> _nomina.Decorator[ __.T ]:
|
|
76
73
|
''' Produces metaclass decorator to control class construction.
|
|
77
74
|
|
|
78
75
|
Decorator overrides ``__new__`` on metaclass.
|
|
79
76
|
'''
|
|
80
|
-
def decorate( clscls: type[
|
|
77
|
+
def decorate( clscls: type[ __.T ] ) -> type[ __.T ]:
|
|
81
78
|
constructor_name = attributes_namer( 'classes', 'constructor' )
|
|
82
79
|
extant = getattr( clscls, constructor_name, None )
|
|
83
80
|
original = getattr( clscls, '__new__' )
|
|
84
81
|
if extant is original: return clscls
|
|
85
82
|
|
|
86
83
|
def construct(
|
|
87
|
-
clscls_: type[
|
|
84
|
+
clscls_: type[ __.T ],
|
|
88
85
|
name: str,
|
|
89
86
|
bases: tuple[ type, ... ],
|
|
90
87
|
namespace: dict[ str, __.typx.Any ], *,
|
|
91
|
-
decorators: _nomina.Decorators = ( ),
|
|
88
|
+
decorators: _nomina.Decorators[ __.T ] = ( ),
|
|
92
89
|
**arguments: __.typx.Any,
|
|
93
90
|
) -> type[ object ]:
|
|
94
91
|
return constructor(
|
|
@@ -105,12 +102,12 @@ def produce_class_construction_decorator(
|
|
|
105
102
|
def produce_class_initialization_decorator(
|
|
106
103
|
attributes_namer: _nomina.AttributesNamer,
|
|
107
104
|
initializer: _nomina.ClassInitializer,
|
|
108
|
-
) -> _nomina.Decorator:
|
|
105
|
+
) -> _nomina.Decorator[ __.T ]:
|
|
109
106
|
''' Produces metaclass decorator to control class initialization.
|
|
110
107
|
|
|
111
108
|
Decorator overrides ``__init__`` on metaclass.
|
|
112
109
|
'''
|
|
113
|
-
def decorate( clscls: type[
|
|
110
|
+
def decorate( clscls: type[ __.T ] ) -> type[ __.T ]:
|
|
114
111
|
initializer_name = attributes_namer( 'classes', 'initializer' )
|
|
115
112
|
extant = getattr( clscls, initializer_name, None )
|
|
116
113
|
original = getattr( clscls, '__init__' )
|
|
@@ -21,15 +21,13 @@
|
|
|
21
21
|
''' Exceptions from package. '''
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
from __future__ import annotations
|
|
25
|
-
|
|
26
24
|
from . import __
|
|
27
25
|
from . import standard as _standard
|
|
28
26
|
|
|
29
27
|
|
|
30
|
-
class Omniexception(
|
|
28
|
+
class Omniexception(
|
|
31
29
|
BaseException, _standard.Object,
|
|
32
|
-
instances_visibles = ( '__cause__', '__context__' ),
|
|
30
|
+
instances_visibles = ( '__cause__', '__context__' ),
|
|
33
31
|
):
|
|
34
32
|
''' Base exception for package. '''
|
|
35
33
|
|
|
@@ -21,39 +21,35 @@
|
|
|
21
21
|
''' Factories which produce metaclass implementations. '''
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
from __future__ import annotations
|
|
25
|
-
|
|
26
24
|
from . import __
|
|
27
25
|
from . import decorators as _decorators
|
|
28
26
|
from . import nomina as _nomina
|
|
29
27
|
from . import utilities as _utilities
|
|
30
28
|
|
|
31
29
|
|
|
32
|
-
_T = __.typx.TypeVar( '_T', bound = type )
|
|
33
|
-
|
|
34
|
-
|
|
35
30
|
def produce_class_constructor(
|
|
36
31
|
attributes_namer: _nomina.AttributesNamer,
|
|
37
|
-
preprocessors: _nomina.ProduceConstructorPreprocsArgument = ( ),
|
|
38
|
-
postprocessors: _nomina.ProduceConstructorPostprocsArgument = ( ),
|
|
39
|
-
) -> _nomina.ClassConstructor:
|
|
32
|
+
preprocessors: _nomina.ProduceConstructorPreprocsArgument[ __.T ] = ( ),
|
|
33
|
+
postprocessors: _nomina.ProduceConstructorPostprocsArgument[ __.T ] = ( ),
|
|
34
|
+
) -> _nomina.ClassConstructor[ __.T ]:
|
|
40
35
|
''' Produces constructors for classes. '''
|
|
41
36
|
|
|
42
37
|
def construct( # noqa: PLR0913
|
|
43
|
-
clscls: type[
|
|
38
|
+
clscls: type[ __.T ],
|
|
44
39
|
superf: _nomina.ClassConstructorLigation,
|
|
45
40
|
name: str,
|
|
46
41
|
bases: tuple[ type, ... ],
|
|
47
42
|
namespace: dict[ str, __.typx.Any ],
|
|
48
43
|
arguments: __.NominativeArguments,
|
|
49
|
-
decorators: _nomina.Decorators,
|
|
44
|
+
decorators: _nomina.Decorators[ __.T ],
|
|
50
45
|
) -> type:
|
|
51
46
|
''' Constructs class, applying decorators and hooks. '''
|
|
52
47
|
bases_ = list( bases )
|
|
53
48
|
arguments_ = dict( arguments )
|
|
54
49
|
decorators_ = list( decorators )
|
|
55
|
-
for
|
|
56
|
-
|
|
50
|
+
for preprocessor in preprocessors:
|
|
51
|
+
preprocessor(
|
|
52
|
+
clscls, name, bases_, namespace, arguments_, decorators_ )
|
|
57
53
|
cls = superf( clscls, name, tuple( bases_ ), namespace, **arguments_ )
|
|
58
54
|
# Some decorators create new classes, which invokes this method again.
|
|
59
55
|
# Short-circuit to prevent recursive decoration and other tangles.
|
|
@@ -62,7 +58,7 @@ def produce_class_constructor(
|
|
|
62
58
|
in_progress = getattr( cls, progress_name_m, False )
|
|
63
59
|
if in_progress: return cls
|
|
64
60
|
setattr( cls, progress_name_m, True )
|
|
65
|
-
for
|
|
61
|
+
for postprocessor in postprocessors: postprocessor( cls, decorators_ )
|
|
66
62
|
cls = _decorators.apply_decorators( cls, decorators_ )
|
|
67
63
|
setattr( cls, progress_name_m, False )
|
|
68
64
|
return cls
|