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
@@ -204,15 +211,6 @@ def __getitem__(self, item):
204211_ClassDecorator = _Callable [[type ], type ]
205212
206213
207- def _annotate (** kwargs ) -> _ClassDecorator :
208- def f (cls : type ) -> type :
209- for k , v in kwargs .items ():
210- setattr (cls , f"_{ k } " , v )
211- return cls
212-
213- return f
214-
215-
216214boolean = "boolean"
217215int = "int"
218216string = "string"
@@ -226,31 +224,29 @@ def f(cls: type) -> type:
226224doc = _DocModifier
227225desc = _DescModifier
228226
229- use_for_null = _annotate ( null = True )
227+ use_for_null = _ClassPragma ( " null" )
230228
231229qltest .add (_Pragma ("skip" ))
232230qltest .add (_ClassPragma ("collapse_hierarchy" ))
233231qltest .add (_ClassPragma ("uncollapse_hierarchy" ))
234- qltest .test_with = lambda cls : _annotate ( test_with = cls ) # inheritable
232+ qltest .add ( _ParametrizedClassPragma ( " test_with" , inherited = True , factory = _schema . get_type_name ))
235233
236- ql .add (_ParametrizedClassPragma ("default_doc_name" , lambda doc : doc ))
237- ql .hideable = _annotate ( hideable = True ) # inheritable
234+ ql .add (_ParametrizedClassPragma ("default_doc_name" , factory = lambda doc : doc ))
235+ ql .add ( _ClassPragma ( " hideable" , inherited = True ))
238236ql .add (_Pragma ("internal" ))
239237
240238cpp .add (_Pragma ("skip" ))
241239
242240rust .add (_Pragma ("skip_doc_test" ))
243241
244- rust .add (_ParametrizedClassPragma ("doc_test_signature" , lambda signature : signature ))
242+ rust .add (_ParametrizedClassPragma ("doc_test_signature" , factory = lambda signature : signature ))
245243
244+ group = _ParametrizedClassPragma ("group" , inherited = True , factory = lambda group : group )
246245
247- def group (name : str = "" ) -> _ClassDecorator :
248- return _annotate (group = name )
249246
250-
251- synth .add (_ParametrizedClassPragma ("from_class" , lambda ref : _schema .SynthInfo (
247+ synth .add (_ParametrizedClassPragma ("from_class" , factory = lambda ref : _schema .SynthInfo (
252248 from_class = _schema .get_type_name (ref ))), key = "synth" )
253- synth .add (_ParametrizedClassPragma ("on_arguments" , lambda ** kwargs :
249+ synth .add (_ParametrizedClassPragma ("on_arguments" , factory = lambda ** kwargs :
254250 _schema .SynthInfo (on_arguments = {k : _schema .get_type_name (t ) for k , t in kwargs .items ()})), key = "synth" )
255251
256252
@@ -288,16 +284,11 @@ def decorator(cls: type) -> _PropertyAnnotation:
288284 raise _schema .Error ("Annotation classes must be named _" )
289285 if cls .__doc__ is not None :
290286 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
297- for a , v in cls .__dict__ .items ():
298- # transfer annotations
299- if a .startswith ("_" ) and not a .startswith ("__" ) and a != "_pragmas" :
300- setattr (annotated_cls , a , v )
287+ for p , v in cls .__dict__ .get ("_pragmas" , {}).items ():
288+ _ClassPragma (p , value = v )(annotated_cls )
289+ for a in dir (cls ):
290+ if a .startswith (_schema .inheritable_pragma_prefix ):
291+ setattr (annotated_cls , a , getattr (cls , a ))
301292 for p , a in cls .__annotations__ .items ():
302293 if p in annotated_cls .__annotations__ :
303294 annotated_cls .__annotations__ [p ] |= a
0 commit comments