5
5
6
6
from misc .codegen .lib .schema import Property
7
7
8
+ _set = set
9
+
8
10
9
11
@_dataclass
10
12
class _ChildModifier (_schema .PropertyModifier ):
@@ -79,7 +81,7 @@ class _SynthModifier(_schema.PropertyModifier, _Namespace):
79
81
def modify (self , prop : _schema .Property ):
80
82
prop .synth = self .synth
81
83
82
- def negate (self ) -> " PropertyModifier" :
84
+ def negate (self ) -> _schema . PropertyModifier :
83
85
return _SynthModifier (self .name , False )
84
86
85
87
@@ -100,14 +102,18 @@ class _ClassPragma(_PragmaBase):
100
102
""" A class pragma.
101
103
For schema classes it acts as a python decorator with `@`.
102
104
"""
105
+ inherited : bool = False
103
106
value : object = None
104
107
105
108
def __call__ (self , cls : type ) -> type :
106
109
""" use this pragma as a decorator on classes """
107
- # not using hasattr as we don't want to land on inherited pragmas
108
- if "_pragmas" not in cls .__dict__ :
109
- cls ._pragmas = {}
110
- self ._apply (cls ._pragmas )
110
+ if self .inherited :
111
+ setattr (cls , f"{ _schema .inheritable_pragma_prefix } { self .pragma } " , self .value )
112
+ else :
113
+ # not using hasattr as we don't want to land on inherited pragmas
114
+ if "_pragmas" not in cls .__dict__ :
115
+ cls ._pragmas = {}
116
+ self ._apply (cls ._pragmas )
111
117
return cls
112
118
113
119
def _apply (self , pragmas : _Dict [str , object ]) -> None :
@@ -125,7 +131,7 @@ class _Pragma(_ClassPragma, _schema.PropertyModifier):
125
131
def modify (self , prop : _schema .Property ):
126
132
self ._apply (prop .pragmas )
127
133
128
- def negate (self ) -> " PropertyModifier" :
134
+ def negate (self ) -> _schema . PropertyModifier :
129
135
return _Pragma (self .pragma , remove = True )
130
136
131
137
def _apply (self , pragmas : _Dict [str , object ]) -> None :
@@ -142,13 +148,14 @@ class _ParametrizedClassPragma(_PragmaBase):
142
148
"""
143
149
_pragma_class : _ClassVar [type ] = _ClassPragma
144
150
145
- function : _Callable [..., object ] = None
151
+ inherited : bool = False
152
+ factory : _Callable [..., object ] = None
146
153
147
154
def __post_init__ (self ):
148
- self .__signature__ = _inspect .signature (self .function ).replace (return_annotation = self ._pragma_class )
155
+ self .__signature__ = _inspect .signature (self .factory ).replace (return_annotation = self ._pragma_class )
149
156
150
157
def __call__ (self , * args , ** kwargs ) -> _pragma_class :
151
- return self ._pragma_class (self .pragma , value = self .function (* args , ** kwargs ))
158
+ return self ._pragma_class (self .pragma , self . inherited , value = self .factory (* args , ** kwargs ))
152
159
153
160
154
161
@_dataclass
@@ -233,24 +240,24 @@ def f(cls: type) -> type:
233
240
qltest .add (_ClassPragma ("uncollapse_hierarchy" ))
234
241
qltest .test_with = lambda cls : _annotate (test_with = cls ) # inheritable
235
242
236
- ql .add (_ParametrizedClassPragma ("default_doc_name" , lambda doc : doc ))
243
+ ql .add (_ParametrizedClassPragma ("default_doc_name" , factory = lambda doc : doc ))
237
244
ql .hideable = _annotate (hideable = True ) # inheritable
238
245
ql .add (_Pragma ("internal" ))
239
246
240
247
cpp .add (_Pragma ("skip" ))
241
248
242
249
rust .add (_Pragma ("skip_doc_test" ))
243
250
244
- rust .add (_ParametrizedClassPragma ("doc_test_signature" , lambda signature : signature ))
251
+ rust .add (_ParametrizedClassPragma ("doc_test_signature" , factory = lambda signature : signature ))
245
252
246
253
247
254
def group (name : str = "" ) -> _ClassDecorator :
248
255
return _annotate (group = name )
249
256
250
257
251
- synth .add (_ParametrizedClassPragma ("from_class" , lambda ref : _schema .SynthInfo (
258
+ synth .add (_ParametrizedClassPragma ("from_class" , factory = lambda ref : _schema .SynthInfo (
252
259
from_class = _schema .get_type_name (ref ))), key = "synth" )
253
- synth .add (_ParametrizedClassPragma ("on_arguments" , lambda ** kwargs :
260
+ synth .add (_ParametrizedClassPragma ("on_arguments" , factory = lambda ** kwargs :
254
261
_schema .SynthInfo (on_arguments = {k : _schema .get_type_name (t ) for k , t in kwargs .items ()})), key = "synth" )
255
262
256
263
@@ -288,12 +295,11 @@ def decorator(cls: type) -> _PropertyAnnotation:
288
295
raise _schema .Error ("Annotation classes must be named _" )
289
296
if cls .__doc__ is not None :
290
297
annotated_cls .__doc__ = cls .__doc__
291
- old_pragmas = getattr (annotated_cls , "_pragmas" , None )
292
- new_pragmas = getattr (cls , "_pragmas" , {})
293
- if old_pragmas :
294
- old_pragmas .update (new_pragmas )
295
- else :
296
- annotated_cls ._pragmas = new_pragmas
298
+ for p , v in cls .__dict__ .get ("_pragmas" , {}).items ():
299
+ _ClassPragma (p , value = v )(annotated_cls )
300
+ for a in dir (cls ):
301
+ if a .startswith (_schema .inheritable_pragma_prefix ):
302
+ setattr (annotated_cls , a , getattr (cls , a ))
297
303
for a , v in cls .__dict__ .items ():
298
304
# transfer annotations
299
305
if a .startswith ("_" ) and not a .startswith ("__" ) and a != "_pragmas" :
0 commit comments