classcore 1.4.1__tar.gz → 1.5__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.4.1 → classcore-1.5}/PKG-INFO +1 -1
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/__/doctab.py +0 -6
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/__/imports.py +1 -1
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/__init__.py +2 -2
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/factories.py +3 -3
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/nomina.py +68 -39
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/standard/behaviors.py +40 -10
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/standard/decorators.py +78 -46
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/standard/dynadoc.py +20 -20
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/standard/modules.py +5 -4
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/standard/nomina.py +17 -9
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/utilities.py +3 -0
- {classcore-1.4.1 → classcore-1.5}/.gitignore +0 -0
- {classcore-1.4.1 → classcore-1.5}/LICENSE.txt +0 -0
- {classcore-1.4.1 → classcore-1.5}/README.rst +0 -0
- {classcore-1.4.1 → classcore-1.5}/pyproject.toml +0 -0
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/__/__init__.py +0 -0
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/__/nomina.py +0 -0
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/decorators.py +0 -0
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/exceptions.py +0 -0
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/py.typed +0 -0
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/standard/__.py +0 -0
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/standard/__init__.py +0 -0
- {classcore-1.4.1 → classcore-1.5}/sources/classcore/standard/classes.py +0 -0
|
@@ -61,8 +61,8 @@ from .decorators import *
|
|
|
61
61
|
from .factories import *
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
__version__: __.typx.Annotated[ str, __.
|
|
65
|
-
__version__ = '1.
|
|
64
|
+
__version__: __.typx.Annotated[ str, __.ddoc.Visibilities.Reveal ]
|
|
65
|
+
__version__ = '1.5'
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
standard.dynadoc.assign_module_docstring( __name__, table = __.fragments )
|
|
@@ -29,8 +29,8 @@ from . import utilities as _utilities
|
|
|
29
29
|
|
|
30
30
|
def produce_class_constructor(
|
|
31
31
|
attributes_namer: _nomina.AttributesNamer,
|
|
32
|
-
preprocessors: _nomina.
|
|
33
|
-
postprocessors: _nomina.
|
|
32
|
+
preprocessors: _nomina.ClassConstructionPreprocessors[ __.T ] = ( ),
|
|
33
|
+
postprocessors: _nomina.ClassConstructionPostprocessors[ __.T ] = ( ),
|
|
34
34
|
) -> _nomina.ClassConstructor[ __.T ]:
|
|
35
35
|
''' Produces constructors for classes. '''
|
|
36
36
|
|
|
@@ -68,7 +68,7 @@ def produce_class_constructor(
|
|
|
68
68
|
|
|
69
69
|
def produce_class_initializer(
|
|
70
70
|
attributes_namer: _nomina.AttributesNamer,
|
|
71
|
-
completers: _nomina.
|
|
71
|
+
completers: _nomina.ClassInitializationCompleters = ( ),
|
|
72
72
|
) -> _nomina.ClassInitializer:
|
|
73
73
|
''' Produces initializers for classes. '''
|
|
74
74
|
|
|
@@ -24,36 +24,68 @@
|
|
|
24
24
|
from . import __
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
AttributesNamer: __.typx.TypeAlias = __.
|
|
27
|
+
AttributesNamer: __.typx.TypeAlias = __.typx.Annotated[
|
|
28
|
+
__.cabc.Callable[ [ str, str ], str ],
|
|
29
|
+
__.ddoc.Doc(
|
|
30
|
+
''' Names attribute from level and core arguments.
|
|
31
|
+
|
|
32
|
+
Level will be one of 'class', 'instances', or 'instance'.
|
|
33
|
+
Core will be the core of the name as supplied this package.
|
|
34
|
+
|
|
35
|
+
Can be used by downstream packages to determine names of
|
|
36
|
+
bookkeeping attributes assigned by this package.
|
|
37
|
+
''' ),
|
|
38
|
+
]
|
|
28
39
|
|
|
29
40
|
Decorator: __.typx.TypeAlias = __.typx.Annotated[
|
|
30
41
|
__.cabc.Callable[ [ type[ __.U ] ], type[ __.U ] ],
|
|
31
|
-
__.
|
|
42
|
+
__.ddoc.Doc(
|
|
32
43
|
''' Class decorator.
|
|
33
44
|
|
|
34
45
|
Takes class argument and returns class.
|
|
35
46
|
''' ),
|
|
36
47
|
]
|
|
37
48
|
Decorators: __.typx.TypeAlias = __.typx.Annotated[
|
|
38
|
-
__.cabc.Sequence[ Decorator[ __.U ] ],
|
|
49
|
+
__.cabc.Sequence[ Decorator[ __.U ] ],
|
|
50
|
+
__.ddoc.Doc(
|
|
51
|
+
''' Sequence of class decorators.
|
|
52
|
+
|
|
53
|
+
Each element takes a class argument and returns a class.
|
|
54
|
+
''' ),
|
|
39
55
|
]
|
|
40
56
|
DecoratorsMutable: __.typx.TypeAlias = __.typx.Annotated[
|
|
41
57
|
__.cabc.MutableSequence[ Decorator[ __.U ] ],
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
58
|
+
__.ddoc.Doc(
|
|
59
|
+
''' Sequence of class decorators.
|
|
60
|
+
|
|
61
|
+
Each element takes a class argument and returns a class.
|
|
62
|
+
|
|
63
|
+
Decorators may be inserted or removed from sequence.
|
|
64
|
+
''' ),
|
|
45
65
|
]
|
|
46
66
|
|
|
47
|
-
DecorationPreparer: __.typx.TypeAlias =
|
|
48
|
-
__.cabc.Callable[ [ type[ __.U ], DecoratorsMutable[ __.U ] ], None ]
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
67
|
+
DecorationPreparer: __.typx.TypeAlias = __.typx.Annotated[
|
|
68
|
+
__.cabc.Callable[ [ type[ __.U ], DecoratorsMutable[ __.U ] ], None ],
|
|
69
|
+
__.ddoc.Doc(
|
|
70
|
+
''' Class decoration preparer.
|
|
71
|
+
|
|
72
|
+
Takes class and mutable sequence of decorators as arguments.
|
|
73
|
+
Can alter the sequence.
|
|
74
|
+
''' ),
|
|
75
|
+
]
|
|
76
|
+
DecorationPreparers: __.typx.TypeAlias = __.typx.Annotated[
|
|
77
|
+
__.cabc.Sequence[ DecorationPreparer[ __.U ] ],
|
|
78
|
+
__.ddoc.Doc(
|
|
79
|
+
''' Sequence of class decoration preparers.
|
|
80
|
+
|
|
81
|
+
Each element takes class and mutable sequence of decorators as
|
|
82
|
+
arguments. And, each element can alter the sequence.
|
|
83
|
+
''' ),
|
|
84
|
+
]
|
|
53
85
|
|
|
54
86
|
ClassConstructorLigation: __.typx.TypeAlias = __.typx.Annotated[
|
|
55
87
|
__.cabc.Callable[ ..., type ],
|
|
56
|
-
__.
|
|
88
|
+
__.ddoc.Doc(
|
|
57
89
|
''' Bound class constructor function.
|
|
58
90
|
|
|
59
91
|
Usually from ``super( ).__new__`` or a partial function.
|
|
@@ -61,7 +93,7 @@ ClassConstructorLigation: __.typx.TypeAlias = __.typx.Annotated[
|
|
|
61
93
|
]
|
|
62
94
|
InitializerLigation: __.typx.TypeAlias = __.typx.Annotated[
|
|
63
95
|
__.cabc.Callable[ ..., None ],
|
|
64
|
-
__.
|
|
96
|
+
__.ddoc.Doc(
|
|
65
97
|
''' Bound initializer function.
|
|
66
98
|
|
|
67
99
|
Usually from ``super( ).__init__`` or a partial function.
|
|
@@ -69,7 +101,7 @@ InitializerLigation: __.typx.TypeAlias = __.typx.Annotated[
|
|
|
69
101
|
]
|
|
70
102
|
AssignerLigation: __.typx.TypeAlias = __.typx.Annotated[
|
|
71
103
|
__.cabc.Callable[ [ str, __.typx.Any ], None ],
|
|
72
|
-
__.
|
|
104
|
+
__.ddoc.Doc(
|
|
73
105
|
''' Bound attributes assigner function.
|
|
74
106
|
|
|
75
107
|
Usually from ``super( ).__setattr__`` or a partial function.
|
|
@@ -77,7 +109,7 @@ AssignerLigation: __.typx.TypeAlias = __.typx.Annotated[
|
|
|
77
109
|
]
|
|
78
110
|
DeleterLigation: __.typx.TypeAlias = __.typx.Annotated[
|
|
79
111
|
__.cabc.Callable[ [ str ], None ],
|
|
80
|
-
__.
|
|
112
|
+
__.ddoc.Doc(
|
|
81
113
|
''' Bound attributes deleter function.
|
|
82
114
|
|
|
83
115
|
Usually from ``super( ).__delattr__`` or a partial function.
|
|
@@ -85,7 +117,7 @@ DeleterLigation: __.typx.TypeAlias = __.typx.Annotated[
|
|
|
85
117
|
]
|
|
86
118
|
SurveyorLigation: __.typx.TypeAlias = __.typx.Annotated[
|
|
87
119
|
__.cabc.Callable[ [ ], __.cabc.Iterable[ str ] ],
|
|
88
|
-
__.
|
|
120
|
+
__.ddoc.Doc(
|
|
89
121
|
''' Bound attributes surveyor function.
|
|
90
122
|
|
|
91
123
|
Usually from ``super( ).__dir__`` or a partial function.
|
|
@@ -105,30 +137,44 @@ ClassConstructionPreprocessor: __.typx.TypeAlias = __.typx.Annotated[
|
|
|
105
137
|
],
|
|
106
138
|
None
|
|
107
139
|
],
|
|
108
|
-
__.
|
|
140
|
+
__.ddoc.Doc(
|
|
109
141
|
''' Processes class data before construction.
|
|
110
142
|
|
|
111
143
|
For use cases, such as argument conversion.
|
|
112
144
|
''' ),
|
|
113
145
|
]
|
|
146
|
+
ClassConstructionPreprocessors: __.typx.TypeAlias = __.typx.Annotated[
|
|
147
|
+
__.cabc.Sequence[ ClassConstructionPreprocessor[ __.U ] ],
|
|
148
|
+
__.ddoc.Doc( ''' Processors to apply before construction of class. ''' ),
|
|
149
|
+
]
|
|
114
150
|
ClassConstructionPostprocessor: __.typx.TypeAlias = __.typx.Annotated[
|
|
115
151
|
__.cabc.Callable[ [ type, DecoratorsMutable[ __.U ] ], None ],
|
|
116
|
-
__.
|
|
152
|
+
__.ddoc.Doc(
|
|
117
153
|
''' Processes class before decoration.
|
|
118
154
|
|
|
119
155
|
For use cases, such as decorator list manipulation.
|
|
120
156
|
''' ),
|
|
121
157
|
]
|
|
158
|
+
ClassConstructionPostprocessors: __.typx.TypeAlias = __.typx.Annotated[
|
|
159
|
+
__.cabc.Sequence[ ClassConstructionPostprocessor[ __.U ] ],
|
|
160
|
+
__.ddoc.Doc(
|
|
161
|
+
''' Processors to apply before decoration of class. ''' ),
|
|
162
|
+
]
|
|
122
163
|
# TODO: ClassInitializationPreparer (arguments mutation)
|
|
123
164
|
ClassInitializationCompleter: __.typx.TypeAlias = __.typx.Annotated[
|
|
124
165
|
__.cabc.Callable[ [ type ], None ],
|
|
125
|
-
__.
|
|
166
|
+
__.ddoc.Doc(
|
|
126
167
|
''' Completes initialization of class.
|
|
127
168
|
|
|
128
169
|
For use cases, such as enabling immutability once all other
|
|
129
170
|
initialization has occurred.
|
|
130
171
|
''' ),
|
|
131
172
|
]
|
|
173
|
+
ClassInitializationCompleters: __.typx.TypeAlias = __.typx.Annotated[
|
|
174
|
+
__.cabc.Sequence[ ClassInitializationCompleter ],
|
|
175
|
+
__.ddoc.Doc(
|
|
176
|
+
''' Processors to apply at final stage of class initialization. ''' ),
|
|
177
|
+
]
|
|
132
178
|
|
|
133
179
|
|
|
134
180
|
ClassConstructor: __.typx.TypeAlias = __.typx.Annotated[
|
|
@@ -144,7 +190,7 @@ ClassConstructor: __.typx.TypeAlias = __.typx.Annotated[
|
|
|
144
190
|
],
|
|
145
191
|
type
|
|
146
192
|
],
|
|
147
|
-
__.
|
|
193
|
+
__.ddoc.Doc( ''' Constructor to use with metaclass. ''' ),
|
|
148
194
|
]
|
|
149
195
|
ClassInitializer: __.typx.TypeAlias = __.typx.Annotated[
|
|
150
196
|
__.cabc.Callable[
|
|
@@ -156,22 +202,5 @@ ClassInitializer: __.typx.TypeAlias = __.typx.Annotated[
|
|
|
156
202
|
],
|
|
157
203
|
None
|
|
158
204
|
],
|
|
159
|
-
__.
|
|
160
|
-
]
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
ProduceConstructorPreprocsArgument: __.typx.TypeAlias = __.typx.Annotated[
|
|
164
|
-
__.cabc.Sequence[ ClassConstructionPreprocessor[ __.U ] ],
|
|
165
|
-
__.dynadoc.Doc(
|
|
166
|
-
''' Processors to apply before construction of class. ''' ),
|
|
167
|
-
]
|
|
168
|
-
ProduceConstructorPostprocsArgument: __.typx.TypeAlias = __.typx.Annotated[
|
|
169
|
-
__.cabc.Sequence[ ClassConstructionPostprocessor[ __.U ] ],
|
|
170
|
-
__.dynadoc.Doc(
|
|
171
|
-
''' Processors to apply before decoration of class. ''' ),
|
|
172
|
-
]
|
|
173
|
-
ProduceInitializerCompletersArgument: __.typx.TypeAlias = __.typx.Annotated[
|
|
174
|
-
__.cabc.Sequence[ ClassInitializationCompleter ],
|
|
175
|
-
__.dynadoc.Doc(
|
|
176
|
-
''' Processors to apply at final stage of class initialization. ''' ),
|
|
205
|
+
__.ddoc.Doc( ''' Initializer to use with metaclass. ''' ),
|
|
177
206
|
]
|
|
@@ -28,6 +28,26 @@ from . import __
|
|
|
28
28
|
from . import nomina as _nomina
|
|
29
29
|
|
|
30
30
|
|
|
31
|
+
def access_core_function( # noqa: PLR0913
|
|
32
|
+
cls: type, /, *,
|
|
33
|
+
attributes_namer: _nomina.AttributesNamer,
|
|
34
|
+
arguments: __.cabc.Mapping[ str, __.typx.Any ],
|
|
35
|
+
level: str,
|
|
36
|
+
name: str,
|
|
37
|
+
default: __.cabc.Callable[ ..., __.typx.Any ],
|
|
38
|
+
) -> __.cabc.Callable[ ..., __.typx.Any ]:
|
|
39
|
+
''' Accesses core behavior function.
|
|
40
|
+
|
|
41
|
+
First checks for override argument, then checks for heritable
|
|
42
|
+
attribute. Finally, falls back to provided default.
|
|
43
|
+
'''
|
|
44
|
+
argument_name = f"{level}_{name}_core"
|
|
45
|
+
attribute_name = attributes_namer( level, f"{name}_core" )
|
|
46
|
+
return (
|
|
47
|
+
arguments.get( argument_name )
|
|
48
|
+
or getattr( cls, attribute_name, default ) )
|
|
49
|
+
|
|
50
|
+
|
|
31
51
|
def assign_attribute_if_mutable( # noqa: PLR0913
|
|
32
52
|
obj: object, /, *,
|
|
33
53
|
ligation: _nomina.AssignerLigation,
|
|
@@ -225,6 +245,10 @@ def produce_class_construction_postprocessor(
|
|
|
225
245
|
) -> _nomina.ClassConstructionPostprocessor[ __.U ]:
|
|
226
246
|
''' Produces construction processor which determines class decorators. '''
|
|
227
247
|
arguments_name = attributes_namer( 'class', 'construction_arguments' )
|
|
248
|
+
cores_default = dict(
|
|
249
|
+
assigner = assign_attribute_if_mutable,
|
|
250
|
+
deleter = delete_attribute_if_mutable,
|
|
251
|
+
surveyor = survey_visible_attributes )
|
|
228
252
|
|
|
229
253
|
def postprocess(
|
|
230
254
|
cls: type, decorators: _nomina.DecoratorsMutable[ __.U ]
|
|
@@ -236,16 +260,19 @@ def produce_class_construction_postprocessor(
|
|
|
236
260
|
dynadoc_cfg_name = (
|
|
237
261
|
attributes_namer( 'classes', 'dynadoc_configuration' ) )
|
|
238
262
|
dynadoc_cfg = getattr( clscls, dynadoc_cfg_name, { } )
|
|
239
|
-
decorators.append( __.
|
|
263
|
+
decorators.append( __.ddoc.with_docstring( **dynadoc_cfg ) )
|
|
240
264
|
dcls_spec = getattr( cls, '__dataclass_transform__', None )
|
|
241
265
|
if not dcls_spec: # either base class or metaclass may be marked
|
|
242
266
|
dcls_spec = getattr( clscls, '__dataclass_transform__', None )
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
267
|
+
cores = { }
|
|
268
|
+
for core_name in ( 'assigner', 'deleter', 'surveyor' ):
|
|
269
|
+
core_function = access_core_function(
|
|
270
|
+
cls,
|
|
271
|
+
attributes_namer = attributes_namer,
|
|
272
|
+
arguments = arguments,
|
|
273
|
+
level = 'instances', name = core_name,
|
|
274
|
+
default = cores_default[ core_name ] )
|
|
275
|
+
cores[ core_name ] = core_function
|
|
249
276
|
instances_mutables = arguments.get(
|
|
250
277
|
'instances_mutables', __.mutables_default )
|
|
251
278
|
instances_visibles = arguments.get(
|
|
@@ -261,9 +288,12 @@ def produce_class_construction_postprocessor(
|
|
|
261
288
|
decorator: _nomina.Decorator[ __.U ] = decorator_factory(
|
|
262
289
|
attributes_namer = attributes_namer,
|
|
263
290
|
error_class_provider = error_class_provider,
|
|
264
|
-
assigner_core =
|
|
265
|
-
|
|
266
|
-
|
|
291
|
+
assigner_core = __.typx.cast(
|
|
292
|
+
_nomina.AssignerCore, cores[ 'assigner' ] ),
|
|
293
|
+
deleter_core = __.typx.cast(
|
|
294
|
+
_nomina.DeleterCore, cores[ 'deleter' ] ),
|
|
295
|
+
surveyor_core = __.typx.cast(
|
|
296
|
+
_nomina.SurveyorCore, cores[ 'surveyor' ] ),
|
|
267
297
|
mutables = instances_mutables,
|
|
268
298
|
visibles = instances_visibles )
|
|
269
299
|
decorators.append( decorator )
|
|
@@ -21,8 +21,6 @@
|
|
|
21
21
|
''' Standard decorators. '''
|
|
22
22
|
# TODO? Add attribute value transformer as standard decorator argument.
|
|
23
23
|
|
|
24
|
-
# ruff: noqa: F401
|
|
25
|
-
|
|
26
24
|
|
|
27
25
|
from .. import factories as _factories
|
|
28
26
|
from .. import utilities as _utilities
|
|
@@ -190,13 +188,34 @@ def class_factory( # noqa: PLR0913
|
|
|
190
188
|
return decorate
|
|
191
189
|
|
|
192
190
|
|
|
193
|
-
def produce_instances_initialization_decorator(
|
|
191
|
+
def produce_instances_initialization_decorator( # noqa: PLR0913
|
|
194
192
|
attributes_namer: _nomina.AttributesNamer,
|
|
193
|
+
assigner_core: __.typx.Optional[ _nomina.AssignerCore ],
|
|
194
|
+
deleter_core: __.typx.Optional[ _nomina.DeleterCore ],
|
|
195
|
+
surveyor_core: __.typx.Optional[ _nomina.SurveyorCore ],
|
|
195
196
|
mutables: _nomina.BehaviorExclusionVerifiersOmni,
|
|
196
197
|
visibles: _nomina.BehaviorExclusionVerifiersOmni,
|
|
197
198
|
) -> _nomina.Decorator[ __.U ]:
|
|
198
199
|
''' Produces decorator to inject '__init__' method into class. '''
|
|
200
|
+
cores = dict(
|
|
201
|
+
instances_assigner_core = assigner_core,
|
|
202
|
+
instances_deleter_core = deleter_core,
|
|
203
|
+
instances_surveyor_core = surveyor_core )
|
|
204
|
+
cores_default = dict(
|
|
205
|
+
assigner = _behaviors.assign_attribute_if_mutable,
|
|
206
|
+
deleter = _behaviors.delete_attribute_if_mutable,
|
|
207
|
+
surveyor = _behaviors.survey_visible_attributes )
|
|
208
|
+
|
|
199
209
|
def decorate( cls: type[ __.U ] ) -> type[ __.U ]:
|
|
210
|
+
for core_name in ( 'assigner', 'deleter', 'surveyor' ):
|
|
211
|
+
core_function = _behaviors.access_core_function(
|
|
212
|
+
cls,
|
|
213
|
+
attributes_namer = attributes_namer,
|
|
214
|
+
arguments = cores,
|
|
215
|
+
level = 'instances', name = core_name,
|
|
216
|
+
default = cores_default[ core_name ] )
|
|
217
|
+
core_aname = attributes_namer( 'instances', f"{core_name}_core" )
|
|
218
|
+
setattr( cls, core_aname, core_function )
|
|
200
219
|
behaviors: set[ str ] = set( )
|
|
201
220
|
behaviors_name = attributes_namer( 'instance', 'behaviors' )
|
|
202
221
|
_behaviors.record_behavior(
|
|
@@ -253,12 +272,18 @@ def produce_attributes_assignment_decorator(
|
|
|
253
272
|
level: str,
|
|
254
273
|
attributes_namer: _nomina.AttributesNamer,
|
|
255
274
|
error_class_provider: _nomina.ErrorClassProvider,
|
|
256
|
-
implementation_core: _nomina.AssignerCore,
|
|
275
|
+
implementation_core: __.typx.Optional[ _nomina.AssignerCore ],
|
|
257
276
|
) -> _nomina.Decorator[ __.U ]:
|
|
258
277
|
''' Produces decorator to inject '__setattr__' method into class. '''
|
|
259
278
|
def decorate( cls: type[ __.U ] ) -> type[ __.U ]:
|
|
260
279
|
leveli = 'class' if level == 'classes' else level
|
|
261
280
|
original = cls.__dict__.get( '__setattr__' )
|
|
281
|
+
core = _behaviors.access_core_function(
|
|
282
|
+
cls,
|
|
283
|
+
attributes_namer = attributes_namer,
|
|
284
|
+
arguments = { f"{leveli}_assigner": implementation_core },
|
|
285
|
+
level = leveli, name = 'assigner',
|
|
286
|
+
default = _behaviors.assign_attribute_if_mutable )
|
|
262
287
|
|
|
263
288
|
if original is None:
|
|
264
289
|
|
|
@@ -270,7 +295,7 @@ def produce_attributes_assignment_decorator(
|
|
|
270
295
|
if cls is not type( self ):
|
|
271
296
|
ligation( name, value )
|
|
272
297
|
return
|
|
273
|
-
|
|
298
|
+
core(
|
|
274
299
|
self,
|
|
275
300
|
ligation = ligation,
|
|
276
301
|
attributes_namer = attributes_namer,
|
|
@@ -291,7 +316,7 @@ def produce_attributes_assignment_decorator(
|
|
|
291
316
|
if cls is not type( self ):
|
|
292
317
|
ligation( name, value )
|
|
293
318
|
return
|
|
294
|
-
|
|
319
|
+
core(
|
|
295
320
|
self,
|
|
296
321
|
ligation = ligation,
|
|
297
322
|
attributes_namer = attributes_namer,
|
|
@@ -310,12 +335,18 @@ def produce_attributes_deletion_decorator(
|
|
|
310
335
|
level: str,
|
|
311
336
|
attributes_namer: _nomina.AttributesNamer,
|
|
312
337
|
error_class_provider: _nomina.ErrorClassProvider,
|
|
313
|
-
implementation_core: _nomina.DeleterCore,
|
|
338
|
+
implementation_core: __.typx.Optional[ _nomina.DeleterCore ],
|
|
314
339
|
) -> _nomina.Decorator[ __.U ]:
|
|
315
340
|
''' Produces decorator to inject '__delattr__' method into class. '''
|
|
316
341
|
def decorate( cls: type[ __.U ] ) -> type[ __.U ]:
|
|
317
342
|
leveli = 'class' if level == 'classes' else level
|
|
318
343
|
original = cls.__dict__.get( '__delattr__' )
|
|
344
|
+
core = _behaviors.access_core_function(
|
|
345
|
+
cls,
|
|
346
|
+
attributes_namer = attributes_namer,
|
|
347
|
+
arguments = { f"{leveli}_deleter": implementation_core },
|
|
348
|
+
level = leveli, name = 'deleter',
|
|
349
|
+
default = _behaviors.delete_attribute_if_mutable )
|
|
319
350
|
|
|
320
351
|
if original is None:
|
|
321
352
|
|
|
@@ -325,7 +356,7 @@ def produce_attributes_deletion_decorator(
|
|
|
325
356
|
if cls is not type( self ):
|
|
326
357
|
ligation( name )
|
|
327
358
|
return
|
|
328
|
-
|
|
359
|
+
core(
|
|
329
360
|
self,
|
|
330
361
|
ligation = ligation,
|
|
331
362
|
attributes_namer = attributes_namer,
|
|
@@ -344,7 +375,7 @@ def produce_attributes_deletion_decorator(
|
|
|
344
375
|
if cls is not type( self ):
|
|
345
376
|
ligation( name )
|
|
346
377
|
return
|
|
347
|
-
|
|
378
|
+
core(
|
|
348
379
|
self,
|
|
349
380
|
ligation = ligation,
|
|
350
381
|
attributes_namer = attributes_namer,
|
|
@@ -362,12 +393,18 @@ def produce_attributes_deletion_decorator(
|
|
|
362
393
|
def produce_attributes_surveillance_decorator(
|
|
363
394
|
level: str,
|
|
364
395
|
attributes_namer: _nomina.AttributesNamer,
|
|
365
|
-
implementation_core: _nomina.SurveyorCore,
|
|
396
|
+
implementation_core: __.typx.Optional[ _nomina.SurveyorCore ],
|
|
366
397
|
) -> _nomina.Decorator[ __.U ]:
|
|
367
398
|
''' Produces decorator to inject '__dir__' method into class. '''
|
|
368
399
|
def decorate( cls: type[ __.U ] ) -> type[ __.U ]:
|
|
369
400
|
leveli = 'class' if level == 'classes' else level
|
|
370
401
|
original = cls.__dict__.get( '__dir__' )
|
|
402
|
+
core = _behaviors.access_core_function(
|
|
403
|
+
cls,
|
|
404
|
+
attributes_namer = attributes_namer,
|
|
405
|
+
arguments = { f"{leveli}_surveyor": implementation_core },
|
|
406
|
+
level = leveli, name = 'surveyor',
|
|
407
|
+
default = _behaviors.survey_visible_attributes )
|
|
371
408
|
|
|
372
409
|
if original is None:
|
|
373
410
|
|
|
@@ -377,7 +414,7 @@ def produce_attributes_surveillance_decorator(
|
|
|
377
414
|
ligation = super( cls, self ).__dir__
|
|
378
415
|
# Only enforce behaviors at start of MRO.
|
|
379
416
|
if cls is not type( self ): return ligation( )
|
|
380
|
-
return
|
|
417
|
+
return core(
|
|
381
418
|
self,
|
|
382
419
|
ligation = ligation,
|
|
383
420
|
attributes_namer = attributes_namer,
|
|
@@ -394,7 +431,7 @@ def produce_attributes_surveillance_decorator(
|
|
|
394
431
|
ligation = __.funct.partial( original, self )
|
|
395
432
|
# Only enforce behaviors at start of MRO.
|
|
396
433
|
if cls is not type( self ): return ligation( )
|
|
397
|
-
return
|
|
434
|
+
return core(
|
|
398
435
|
self,
|
|
399
436
|
ligation = ligation,
|
|
400
437
|
attributes_namer = attributes_namer,
|
|
@@ -412,12 +449,9 @@ def dataclass_with_standard_behaviors( # noqa: PLR0913
|
|
|
412
449
|
attributes_namer: _nomina.AttributesNamer = __.calculate_attrname,
|
|
413
450
|
error_class_provider: _nomina.ErrorClassProvider = __.provide_error_class,
|
|
414
451
|
decorators: _nomina.Decorators[ __.U ] = ( ),
|
|
415
|
-
assigner_core: _nomina.AssignerCore =
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
_behaviors.delete_attribute_if_mutable ),
|
|
419
|
-
surveyor_core: _nomina.SurveyorCore = (
|
|
420
|
-
_behaviors.survey_visible_attributes ),
|
|
452
|
+
assigner_core: __.typx.Optional[ _nomina.AssignerCore ] = None,
|
|
453
|
+
deleter_core: __.typx.Optional[ _nomina.DeleterCore ] = None,
|
|
454
|
+
surveyor_core: __.typx.Optional[ _nomina.SurveyorCore ] = None,
|
|
421
455
|
mutables: _nomina.BehaviorExclusionVerifiersOmni = __.mutables_default,
|
|
422
456
|
visibles: _nomina.BehaviorExclusionVerifiersOmni = __.visibles_default,
|
|
423
457
|
) -> _nomina.Decorator[ __.U ]:
|
|
@@ -445,12 +479,9 @@ def with_standard_behaviors( # noqa: PLR0913
|
|
|
445
479
|
attributes_namer: _nomina.AttributesNamer = __.calculate_attrname,
|
|
446
480
|
error_class_provider: _nomina.ErrorClassProvider = __.provide_error_class,
|
|
447
481
|
decorators: _nomina.Decorators[ __.U ] = ( ),
|
|
448
|
-
assigner_core: _nomina.AssignerCore =
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
_behaviors.delete_attribute_if_mutable ),
|
|
452
|
-
surveyor_core: _nomina.SurveyorCore = (
|
|
453
|
-
_behaviors.survey_visible_attributes ),
|
|
482
|
+
assigner_core: __.typx.Optional[ _nomina.AssignerCore ] = None,
|
|
483
|
+
deleter_core: __.typx.Optional[ _nomina.DeleterCore ] = None,
|
|
484
|
+
surveyor_core: __.typx.Optional[ _nomina.SurveyorCore ] = None,
|
|
454
485
|
mutables: _nomina.BehaviorExclusionVerifiersOmni = __.mutables_default,
|
|
455
486
|
visibles: _nomina.BehaviorExclusionVerifiersOmni = __.visibles_default,
|
|
456
487
|
) -> _nomina.Decorator[ __.U ]:
|
|
@@ -488,9 +519,9 @@ def _produce_instances_decoration_preparers(
|
|
|
488
519
|
def _produce_instances_decorators( # noqa: PLR0913
|
|
489
520
|
attributes_namer: _nomina.AttributesNamer,
|
|
490
521
|
error_class_provider: _nomina.ErrorClassProvider,
|
|
491
|
-
assigner_core: _nomina.AssignerCore,
|
|
492
|
-
deleter_core: _nomina.DeleterCore,
|
|
493
|
-
surveyor_core: _nomina.SurveyorCore,
|
|
522
|
+
assigner_core: __.typx.Optional[ _nomina.AssignerCore ],
|
|
523
|
+
deleter_core: __.typx.Optional[ _nomina.DeleterCore ],
|
|
524
|
+
surveyor_core: __.typx.Optional[ _nomina.SurveyorCore ],
|
|
494
525
|
mutables: _nomina.BehaviorExclusionVerifiersOmni,
|
|
495
526
|
visibles: _nomina.BehaviorExclusionVerifiersOmni,
|
|
496
527
|
) -> _nomina.Decorators[ __.U ]:
|
|
@@ -499,24 +530,25 @@ def _produce_instances_decorators( # noqa: PLR0913
|
|
|
499
530
|
decorators.append(
|
|
500
531
|
produce_instances_initialization_decorator(
|
|
501
532
|
attributes_namer = attributes_namer,
|
|
533
|
+
assigner_core = assigner_core,
|
|
534
|
+
deleter_core = deleter_core,
|
|
535
|
+
surveyor_core = surveyor_core,
|
|
502
536
|
mutables = mutables, visibles = visibles ) )
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
attributes_namer = attributes_namer,
|
|
521
|
-
implementation_core = surveyor_core ) )
|
|
537
|
+
decorators.append(
|
|
538
|
+
produce_attributes_assignment_decorator(
|
|
539
|
+
level = 'instances',
|
|
540
|
+
attributes_namer = attributes_namer,
|
|
541
|
+
error_class_provider = error_class_provider,
|
|
542
|
+
implementation_core = assigner_core ) )
|
|
543
|
+
decorators.append(
|
|
544
|
+
produce_attributes_deletion_decorator(
|
|
545
|
+
level = 'instances',
|
|
546
|
+
attributes_namer = attributes_namer,
|
|
547
|
+
error_class_provider = error_class_provider,
|
|
548
|
+
implementation_core = deleter_core ) )
|
|
549
|
+
decorators.append(
|
|
550
|
+
produce_attributes_surveillance_decorator(
|
|
551
|
+
level = 'instances',
|
|
552
|
+
attributes_namer = attributes_namer,
|
|
553
|
+
implementation_core = surveyor_core ) )
|
|
522
554
|
return decorators
|
|
@@ -26,34 +26,34 @@ from . import __
|
|
|
26
26
|
from . import nomina as _nomina
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
dynadoc_context = __.
|
|
29
|
+
dynadoc_context = __.ddoc.produce_context( )
|
|
30
30
|
dynadoc_class_introspection_control = (
|
|
31
|
-
__.
|
|
31
|
+
__.ddoc.ClassIntrospectionControl(
|
|
32
32
|
inheritance = True,
|
|
33
33
|
introspectors = (
|
|
34
|
-
__.
|
|
34
|
+
__.ddoc.introspection.introspect_special_classes, ) ) )
|
|
35
35
|
dynadoc_module_introspection_control = (
|
|
36
|
-
__.
|
|
36
|
+
__.ddoc.ModuleIntrospectionControl( ) )
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
def dynadoc_avoid_immutables(
|
|
40
40
|
objct: object,
|
|
41
|
-
introspection: __.
|
|
41
|
+
introspection: __.ddoc.IntrospectionControl,
|
|
42
42
|
attributes_namer: _nomina.AttributesNamer,
|
|
43
|
-
) -> __.
|
|
43
|
+
) -> __.ddoc.IntrospectionControl:
|
|
44
44
|
''' Disables introspection of immutable objects. '''
|
|
45
45
|
if __.inspect.isclass( objct ):
|
|
46
46
|
behaviors_name = attributes_namer( 'class', 'behaviors' )
|
|
47
47
|
behaviors = _utilities.getattr0( objct, behaviors_name, frozenset( ) )
|
|
48
48
|
if _nomina.immutability_label in behaviors:
|
|
49
49
|
return introspection.with_limit(
|
|
50
|
-
__.
|
|
50
|
+
__.ddoc.IntrospectionLimit( disable = True ) )
|
|
51
51
|
return introspection
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
def produce_dynadoc_introspection_limiter(
|
|
55
55
|
attributes_namer: _nomina.AttributesNamer = __.calculate_attrname,
|
|
56
|
-
) -> __.
|
|
56
|
+
) -> __.ddoc.IntrospectionLimiter:
|
|
57
57
|
''' Produces introspection limiter which avoids immutable objects. '''
|
|
58
58
|
return __.funct.partial(
|
|
59
59
|
dynadoc_avoid_immutables, attributes_namer = attributes_namer )
|
|
@@ -63,17 +63,17 @@ dynadoc_introspection_limiter = produce_dynadoc_introspection_limiter( )
|
|
|
63
63
|
|
|
64
64
|
def produce_dynadoc_introspection_control(
|
|
65
65
|
enable: bool = True,
|
|
66
|
-
class_control: __.
|
|
66
|
+
class_control: __.ddoc.ClassIntrospectionControl = (
|
|
67
67
|
dynadoc_class_introspection_control ),
|
|
68
|
-
module_control: __.
|
|
68
|
+
module_control: __.ddoc.ModuleIntrospectionControl = (
|
|
69
69
|
dynadoc_module_introspection_control ),
|
|
70
|
-
limiters: __.
|
|
70
|
+
limiters: __.ddoc.IntrospectionLimiters = (
|
|
71
71
|
dynadoc_introspection_limiter, ),
|
|
72
|
-
targets: __.
|
|
73
|
-
__.
|
|
74
|
-
) -> __.
|
|
72
|
+
targets: __.ddoc.IntrospectionTargets = (
|
|
73
|
+
__.ddoc.IntrospectionTargetsSansModule ),
|
|
74
|
+
) -> __.ddoc.IntrospectionControl:
|
|
75
75
|
''' Produces compatible Dynadoc introspection control. '''
|
|
76
|
-
return __.
|
|
76
|
+
return __.ddoc.IntrospectionControl(
|
|
77
77
|
enable = enable,
|
|
78
78
|
class_control = class_control,
|
|
79
79
|
module_control = module_control,
|
|
@@ -83,18 +83,18 @@ def produce_dynadoc_introspection_control(
|
|
|
83
83
|
dynadoc_introspection_on_class = produce_dynadoc_introspection_control( )
|
|
84
84
|
dynadoc_introspection_on_package = (
|
|
85
85
|
produce_dynadoc_introspection_control(
|
|
86
|
-
targets = __.
|
|
86
|
+
targets = __.ddoc.IntrospectionTargetsOmni ) )
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
def assign_module_docstring( # noqa: PLR0913
|
|
90
90
|
module: str | __.types.ModuleType, /,
|
|
91
|
-
*fragments: __.
|
|
91
|
+
*fragments: __.ddoc.interfaces.Fragment,
|
|
92
92
|
context: _nomina.DynadocContextArgument = dynadoc_context,
|
|
93
93
|
introspection: _nomina.DynadocIntrospectionArgument = (
|
|
94
94
|
dynadoc_introspection_on_package ),
|
|
95
95
|
preserve: _nomina.DynadocPreserveArgument = True,
|
|
96
|
-
renderer: __.
|
|
97
|
-
__.
|
|
96
|
+
renderer: __.ddoc.xtnsapi.Renderer = (
|
|
97
|
+
__.ddoc.assembly.renderer_default ),
|
|
98
98
|
table: _nomina.DynadocTableArgument = __.dictproxy_empty,
|
|
99
99
|
) -> None:
|
|
100
100
|
''' Updates module docstring based on introspection.
|
|
@@ -104,7 +104,7 @@ def assign_module_docstring( # noqa: PLR0913
|
|
|
104
104
|
|
|
105
105
|
By default, ignores previously-decorated immutable classes.
|
|
106
106
|
'''
|
|
107
|
-
__.
|
|
107
|
+
__.ddoc.assign_module_docstring(
|
|
108
108
|
module,
|
|
109
109
|
*fragments,
|
|
110
110
|
context = context,
|
|
@@ -34,20 +34,20 @@ class Module( _classes.Object, __.types.ModuleType ):
|
|
|
34
34
|
def reclassify_modules(
|
|
35
35
|
attributes: __.typx.Annotated[
|
|
36
36
|
__.cabc.Mapping[ str, __.typx.Any ] | __.types.ModuleType | str,
|
|
37
|
-
__.
|
|
37
|
+
__.ddoc.Doc(
|
|
38
38
|
''' Module, module name, or dictionary of object attributes. ''' ),
|
|
39
39
|
], /, *,
|
|
40
40
|
attributes_namer: __.typx.Annotated[
|
|
41
41
|
_nomina.AttributesNamer,
|
|
42
|
-
__.
|
|
42
|
+
__.ddoc.Doc(
|
|
43
43
|
''' Attributes namer function with which to seal class. ''' ),
|
|
44
44
|
] = __.calculate_attrname,
|
|
45
45
|
recursive: __.typx.Annotated[
|
|
46
|
-
bool, __.
|
|
46
|
+
bool, __.ddoc.Doc( ''' Recursively reclassify package modules? ''' )
|
|
47
47
|
] = False,
|
|
48
48
|
replacement_class: __.typx.Annotated[
|
|
49
49
|
type[ __.types.ModuleType ],
|
|
50
|
-
__.
|
|
50
|
+
__.ddoc.Doc( ''' New class for module. ''' ),
|
|
51
51
|
] = Module,
|
|
52
52
|
) -> None:
|
|
53
53
|
# TODO? Ensure correct operation with namespace packages.
|
|
@@ -78,6 +78,7 @@ def reclassify_modules(
|
|
|
78
78
|
if recursive:
|
|
79
79
|
reclassify_modules(
|
|
80
80
|
value,
|
|
81
|
+
attributes_namer = attributes_namer,
|
|
81
82
|
recursive = True,
|
|
82
83
|
replacement_class = replacement_class )
|
|
83
84
|
if isinstance( value, replacement_class ): continue
|
|
@@ -46,8 +46,15 @@ BehaviorExclusionVerifiers: __.typx.TypeAlias = (
|
|
|
46
46
|
__.cabc.Sequence[ BehaviorExclusionVerifier ] )
|
|
47
47
|
BehaviorExclusionVerifiersOmni: __.typx.TypeAlias = (
|
|
48
48
|
BehaviorExclusionVerifiers | __.typx.Literal[ '*' ] )
|
|
49
|
-
ErrorClassProvider: __.typx.TypeAlias =
|
|
50
|
-
__.cabc.Callable[ [ str ], type[ Exception ] ]
|
|
49
|
+
ErrorClassProvider: __.typx.TypeAlias = __.typx.Annotated[
|
|
50
|
+
__.cabc.Callable[ [ str ], type[ Exception ] ],
|
|
51
|
+
__.ddoc.Doc(
|
|
52
|
+
''' Takes name of exception class and returns corresponding class.
|
|
53
|
+
|
|
54
|
+
Can be used by downstream packages to provide exceptions from their
|
|
55
|
+
own hierarchies rather than the hierarchy from this package.
|
|
56
|
+
''' ),
|
|
57
|
+
]
|
|
51
58
|
|
|
52
59
|
|
|
53
60
|
class AssignerCore( __.typx.Protocol ):
|
|
@@ -103,9 +110,10 @@ class ClassPreparer( __.typx.Protocol ):
|
|
|
103
110
|
|
|
104
111
|
|
|
105
112
|
DynadocConfiguration: __.typx.TypeAlias = __.cabc.Mapping[ str, __.typx.Any ]
|
|
113
|
+
# TODO: Use argument type aliases from 'dynadoc' package.
|
|
106
114
|
DynadocContextArgument: __.typx.TypeAlias = __.typx.Annotated[
|
|
107
|
-
__.
|
|
108
|
-
__.
|
|
115
|
+
__.ddoc.Context,
|
|
116
|
+
__.ddoc.Doc(
|
|
109
117
|
''' Dynadoc context.
|
|
110
118
|
|
|
111
119
|
Renderer, dictionaries for resolution of stringified annotations,
|
|
@@ -113,8 +121,8 @@ DynadocContextArgument: __.typx.TypeAlias = __.typx.Annotated[
|
|
|
113
121
|
''' ),
|
|
114
122
|
]
|
|
115
123
|
DynadocIntrospectionArgument: __.typx.TypeAlias = __.typx.Annotated[
|
|
116
|
-
__.
|
|
117
|
-
__.
|
|
124
|
+
__.ddoc.IntrospectionControl,
|
|
125
|
+
__.ddoc.Doc(
|
|
118
126
|
''' Dynadoc introspection control.
|
|
119
127
|
|
|
120
128
|
Which kinds of object to recursively introspect?
|
|
@@ -124,15 +132,15 @@ DynadocIntrospectionArgument: __.typx.TypeAlias = __.typx.Annotated[
|
|
|
124
132
|
''' ),
|
|
125
133
|
]
|
|
126
134
|
DynadocPreserveArgument: __.typx.TypeAlias = __.typx.Annotated[
|
|
127
|
-
bool, __.
|
|
135
|
+
bool, __.ddoc.Doc( ''' Preserve existing docstring? ''' )
|
|
128
136
|
]
|
|
129
137
|
DynadocTableArgument: __.typx.TypeAlias = __.typx.Annotated[
|
|
130
138
|
__.cabc.Mapping[ str, str ],
|
|
131
|
-
__.
|
|
139
|
+
__.ddoc.Doc( ''' Table of documentation fragments. ''' ),
|
|
132
140
|
]
|
|
133
141
|
ProduceDynadocConfigurationReturn: __.typx.TypeAlias = __.typx.Annotated[
|
|
134
142
|
DynadocConfiguration,
|
|
135
|
-
__.
|
|
143
|
+
__.ddoc.Doc(
|
|
136
144
|
''' Dynadoc configuration dictionary.
|
|
137
145
|
|
|
138
146
|
Suitable as a keyword expansion (``**``) argument to
|
|
@@ -95,8 +95,11 @@ def mangle_name( objct: object, /, name: str ) -> str:
|
|
|
95
95
|
Effectively provides name of private member attribute,
|
|
96
96
|
which is unique across class inheritance.
|
|
97
97
|
'''
|
|
98
|
+
# TODO: Replace expensive SHA-256 hash with simple 'id'.
|
|
99
|
+
# Need to debug weird issue with using 'id' early on dataclasses.
|
|
98
100
|
if not __.inspect.isclass( objct ):
|
|
99
101
|
return mangle_name( type( objct ), name )
|
|
102
|
+
# return "{name}_{uid}".format( name = name, uid = id( objct ) )
|
|
100
103
|
namehash = __.hashlib.sha256( )
|
|
101
104
|
namehash.update( qualify_class_name( objct ).encode( ) )
|
|
102
105
|
namehash_hex = namehash.hexdigest( )
|
|
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
|