Skip to content

Commit 854d766

Browse files
authored
Merge pull request github#17730 from github/redsun82/codegen-annotate
Rust: insert `CallExprBase` in the hierarchy
2 parents 57c6e4d + f3bf347 commit 854d766

File tree

19 files changed

+544
-371
lines changed

19 files changed

+544
-371
lines changed

misc/codegen/lib/schemadefs.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
from typing import Callable as _Callable, Dict as _Dict, ClassVar as _ClassVar
1+
from typing import (
2+
Callable as _Callable,
3+
Dict as _Dict,
4+
ClassVar as _ClassVar,
5+
)
26
from misc.codegen.lib import schema as _schema
37
import inspect as _inspect
48
from dataclasses import dataclass as _dataclass
@@ -271,14 +275,16 @@ def __or__(self, other: _schema.PropertyModifier):
271275

272276
_ = _PropertyAnnotation()
273277

278+
drop = object()
274279

275-
def annotate(annotated_cls: type) -> _Callable[[type], _PropertyAnnotation]:
280+
281+
def annotate(annotated_cls: type, replace_bases: _Dict[type, type] | None = None) -> _Callable[[type], _PropertyAnnotation]:
276282
"""
277-
Add or modify schema annotations after a class has been defined
278-
For the moment, only docstring annotation is supported. In the future, any kind of
279-
modification will be allowed.
283+
Add or modify schema annotations after a class has been defined previously.
284+
285+
The name of the class used for annotation must be `_`.
280286
281-
The name of the class used for annotation must be `_`
287+
`replace_bases` can be used to replace bases on the annotated class.
282288
"""
283289
def decorator(cls: type) -> _PropertyAnnotation:
284290
if cls.__name__ != "_":
@@ -287,11 +293,15 @@ def decorator(cls: type) -> _PropertyAnnotation:
287293
annotated_cls.__doc__ = cls.__doc__
288294
for p, v in cls.__dict__.get("_pragmas", {}).items():
289295
_ClassPragma(p, value=v)(annotated_cls)
296+
if replace_bases:
297+
annotated_cls.__bases__ = tuple(replace_bases.get(b, b) for b in annotated_cls.__bases__)
290298
for a in dir(cls):
291299
if a.startswith(_schema.inheritable_pragma_prefix):
292300
setattr(annotated_cls, a, getattr(cls, a))
293301
for p, a in cls.__annotations__.items():
294-
if p in annotated_cls.__annotations__:
302+
if a is drop:
303+
del annotated_cls.__annotations__[p]
304+
elif p in annotated_cls.__annotations__:
295305
annotated_cls.__annotations__[p] |= a
296306
elif isinstance(a, (_PropertyAnnotation, _PropertyModifierList)):
297307
raise _schema.Error(f"annotated property {p} not present in annotated class "

misc/codegen/test/test_schemaloader.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,56 @@ class Something:
884884
"""
885885

886886

887+
def test_annotate_replace_bases():
888+
@load
889+
class data:
890+
class Root:
891+
pass
892+
893+
class A(Root):
894+
pass
895+
896+
class B(Root):
897+
pass
898+
899+
class C(B):
900+
pass
901+
902+
class Derived(A, B):
903+
pass
904+
905+
@defs.annotate(Derived, replace_bases={B: C})
906+
class _:
907+
pass
908+
assert data.classes == {
909+
"Root": schema.Class("Root", derived={"A", "B"}),
910+
"A": schema.Class("A", bases=["Root"], derived={"Derived"}),
911+
"B": schema.Class("B", bases=["Root"], derived={"C"}),
912+
"C": schema.Class("C", bases=["B"], derived={"Derived"}),
913+
"Derived": schema.Class("Derived", bases=["A", "C"]),
914+
}
915+
916+
917+
def test_annotate_drop_field():
918+
@load
919+
class data:
920+
class Root:
921+
x: defs.int
922+
y: defs.string
923+
z: defs.boolean
924+
925+
@defs.annotate(Root)
926+
class _:
927+
y: defs.drop
928+
929+
assert data.classes == {
930+
"Root": schema.Class("Root", properties=[
931+
schema.SingleProperty("x", "int"),
932+
schema.SingleProperty("z", "boolean"),
933+
]),
934+
}
935+
936+
887937
def test_test_with_unknown_string():
888938
with pytest.raises(schema.Error):
889939
@load

rust/extractor/src/generated/.generated.list

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)