55
66from misc .codegen .lib .schema import Property
77
8+ _set = set
9+
810
911@_dataclass
1012class _ChildModifier (_schema .PropertyModifier ):
@@ -79,7 +81,7 @@ class _SynthModifier(_schema.PropertyModifier, _Namespace):
7981 def modify (self , prop : _schema .Property ):
8082 prop .synth = self .synth
8183
82- def negate (self ) -> " PropertyModifier" :
84+ def negate (self ) -> _schema . PropertyModifier :
8385 return _SynthModifier (self .name , False )
8486
8587
@@ -100,14 +102,18 @@ class _ClassPragma(_PragmaBase):
100102 """ A class pragma.
101103 For schema classes it acts as a python decorator with `@`.
102104 """
105+ inherited : bool = False
103106 value : object = None
104107
105108 def __call__ (self , cls : type ) -> type :
106109 """ 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 )
111117 return cls
112118
113119 def _apply (self , pragmas : _Dict [str , object ]) -> None :
@@ -125,7 +131,7 @@ class _Pragma(_ClassPragma, _schema.PropertyModifier):
125131 def modify (self , prop : _schema .Property ):
126132 self ._apply (prop .pragmas )
127133
128- def negate (self ) -> " PropertyModifier" :
134+ def negate (self ) -> _schema . PropertyModifier :
129135 return _Pragma (self .pragma , remove = True )
130136
131137 def _apply (self , pragmas : _Dict [str , object ]) -> None :
@@ -142,13 +148,14 @@ class _ParametrizedClassPragma(_PragmaBase):
142148 """
143149 _pragma_class : _ClassVar [type ] = _ClassPragma
144150
145- function : _Callable [..., object ] = None
151+ inherited : bool = False
152+ factory : _Callable [..., object ] = None
146153
147154 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 )
149156
150157 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 ))
152159
153160
154161@_dataclass
@@ -233,24 +240,24 @@ def f(cls: type) -> type:
233240qltest .add (_ClassPragma ("uncollapse_hierarchy" ))
234241qltest .test_with = lambda cls : _annotate (test_with = cls ) # inheritable
235242
236- ql .add (_ParametrizedClassPragma ("default_doc_name" , lambda doc : doc ))
243+ ql .add (_ParametrizedClassPragma ("default_doc_name" , factory = lambda doc : doc ))
237244ql .hideable = _annotate (hideable = True ) # inheritable
238245ql .add (_Pragma ("internal" ))
239246
240247cpp .add (_Pragma ("skip" ))
241248
242249rust .add (_Pragma ("skip_doc_test" ))
243250
244- rust .add (_ParametrizedClassPragma ("doc_test_signature" , lambda signature : signature ))
251+ rust .add (_ParametrizedClassPragma ("doc_test_signature" , factory = lambda signature : signature ))
245252
246253
247254def group (name : str = "" ) -> _ClassDecorator :
248255 return _annotate (group = name )
249256
250257
251- synth .add (_ParametrizedClassPragma ("from_class" , lambda ref : _schema .SynthInfo (
258+ synth .add (_ParametrizedClassPragma ("from_class" , factory = lambda ref : _schema .SynthInfo (
252259 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 :
254261 _schema .SynthInfo (on_arguments = {k : _schema .get_type_name (t ) for k , t in kwargs .items ()})), key = "synth" )
255262
256263
@@ -288,12 +295,11 @@ def decorator(cls: type) -> _PropertyAnnotation:
288295 raise _schema .Error ("Annotation classes must be named _" )
289296 if cls .__doc__ is not None :
290297 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 ))
297303 for a , v in cls .__dict__ .items ():
298304 # transfer annotations
299305 if a .startswith ("_" ) and not a .startswith ("__" ) and a != "_pragmas" :
0 commit comments