From 74c0fa7154d64fc28e3e3177fe39a674c43153a4 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 20 Sep 2024 08:40:34 +0200 Subject: [PATCH] Codegen: allow annotations to add class decorations --- misc/codegen/lib/schemadefs.py | 18 ++++++++++++---- misc/codegen/test/test_schemaloader.py | 30 +++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/misc/codegen/lib/schemadefs.py b/misc/codegen/lib/schemadefs.py index d5d7576c5b4..adcaf4fbf1a 100644 --- a/misc/codegen/lib/schemadefs.py +++ b/misc/codegen/lib/schemadefs.py @@ -20,10 +20,9 @@ class _ChildModifier(_schema.PropertyModifier): def negate(self) -> _schema.PropertyModifier: return _ChildModifier(False) -# make ~doc same as doc(None) - class _DocModifierMetaclass(type(_schema.PropertyModifier)): + # make ~doc same as doc(None) def __invert__(self) -> _schema.PropertyModifier: return _DocModifier(None) @@ -41,8 +40,8 @@ class _DocModifier(_schema.PropertyModifier, metaclass=_DocModifierMetaclass): return _DocModifier(None) -# make ~desc same as desc(None) class _DescModifierMetaclass(type(_schema.PropertyModifier)): + # make ~desc same as desc(None) def __invert__(self) -> _schema.PropertyModifier: return _DescModifier(None) @@ -249,7 +248,18 @@ def annotate(annotated_cls: type) -> _Callable[[type], _PropertyAnnotation]: def decorator(cls: type) -> _PropertyAnnotation: if cls.__name__ != "_": raise _schema.Error("Annotation classes must be named _") - annotated_cls.__doc__ = cls.__doc__ + if cls.__doc__ is not None: + annotated_cls.__doc__ = cls.__doc__ + old_pragmas = getattr(annotated_cls, "_pragmas", None) + new_pragmas = getattr(cls, "_pragmas", []) + if old_pragmas: + old_pragmas.extend(new_pragmas) + else: + annotated_cls._pragmas = new_pragmas + for a, v in cls.__dict__.items(): + # transfer annotations + if a.startswith("_") and not a.startswith("__") and a != "_pragmas": + setattr(annotated_cls, a, v) for p, a in cls.__annotations__.items(): if p in annotated_cls.__annotations__: annotated_cls.__annotations__[p] |= a diff --git a/misc/codegen/test/test_schemaloader.py b/misc/codegen/test/test_schemaloader.py index 02d8f71d41c..a9b457b8318 100644 --- a/misc/codegen/test/test_schemaloader.py +++ b/misc/codegen/test/test_schemaloader.py @@ -763,6 +763,9 @@ def test_annotate_docstring(): class Root: """ old docstring """ + class A(Root): + """ A docstring """ + @defs.annotate(Root) class _: """ @@ -770,8 +773,33 @@ def test_annotate_docstring(): docstring """ + @defs.annotate(A) + class _: + pass + assert data.classes == { - "Root": schema.Class("Root", doc=["new", "docstring"]), + "Root": schema.Class("Root", doc=["new", "docstring"], derived={"A"}), + "A": schema.Class("A", bases=["Root"], doc=["A docstring"]), + } + + +def test_annotate_decorations(): + @load + class data: + @defs.qltest.skip + class Root: + pass + + @defs.annotate(Root) + @defs.qltest.collapse_hierarchy + @defs.ql.hideable + @defs.cpp.skip + class _: + pass + + assert data.classes == { + "Root": schema.Class("Root", hideable=True, + pragmas=["qltest_skip", "cpp_skip", "qltest_collapse_hierarchy"]), }