diff --git a/fhir_py_types/__init__.py b/fhir_py_types/__init__.py index 98e292d..be71948 100644 --- a/fhir_py_types/__init__.py +++ b/fhir_py_types/__init__.py @@ -33,6 +33,7 @@ class StructurePropertyType: isarray: bool = False literal: bool = False target_profile: list[str] | None = None + alias: str | None = None @dataclass(frozen=True) diff --git a/fhir_py_types/ast.py b/fhir_py_types/ast.py index 2f2d843..8c2ed7a 100644 --- a/fhir_py_types/ast.py +++ b/fhir_py_types/ast.py @@ -51,7 +51,7 @@ def make_default_initializer( ) -> ast.expr | None: default: ast.expr | None = None - if keyword.iskeyword(identifier): + if keyword.iskeyword(identifier) or type_.alias: default = ast.Call( ast.Name("Field"), args=[], @@ -61,7 +61,7 @@ def make_default_initializer( if not type_.required else [] ), - ast.keyword(arg="alias", value=ast.Constant(identifier)), + ast.keyword(arg="alias", value=ast.Constant(type_.alias or identifier)), ], ) else: @@ -115,19 +115,20 @@ def zip_identifier_type( result = [] for t in [remap_type(definition, t) for t in definition.type]: - result.append((format_identifier(definition, identifier, t), t)) - if ( - definition.kind != StructureDefinitionKind.PRIMITIVE - and is_primitive_type(t) + name = format_identifier(definition, identifier, t) + result.append((name, t)) + if definition.kind != StructureDefinitionKind.PRIMITIVE and is_primitive_type( + t ): result.append( ( - f"_{format_identifier(definition, identifier, t)}", + f"{name}__ext", StructurePropertyType( code="Element", target_profile=[], required=False, isarray=definition.type[0].isarray, + alias=f"_{name}" ), ) ) diff --git a/fhir_py_types/cli.py b/fhir_py_types/cli.py index 1c08540..1acd577 100644 --- a/fhir_py_types/cli.py +++ b/fhir_py_types/cli.py @@ -40,7 +40,6 @@ def main() -> None: load_from_bundle(bundle) for bundle in args.from_bundles ) ) - with open(os.path.join(dir_path, "header.py.tpl")) as header_file: header_lines = header_file.readlines() diff --git a/fhir_py_types/header.py.tpl b/fhir_py_types/header.py.tpl index c22d38c..61e023a 100644 --- a/fhir_py_types/header.py.tpl +++ b/fhir_py_types/header.py.tpl @@ -3,6 +3,7 @@ from typing import List as List_, Optional as Optional_, Literal as Literal_, An from pydantic import BaseModel as BaseModel_, Field, Extra + class BaseModel(BaseModel_): class Config: extra = Extra.forbid diff --git a/tests/test_ast.py b/tests/test_ast.py index c3e5e23..0270655 100644 --- a/tests/test_ast.py +++ b/tests/test_ast.py @@ -20,6 +20,17 @@ def assert_eq( assert generated == expected +def build_field_with_alias(identifier: str) -> ast.Call: + return ast.Call( + func=ast.Name(id="Field"), + args=[], + keywords=[ + ast.keyword(arg="default", value=ast.Constant(value=None)), + ast.keyword(arg="alias", value=ast.Constant(value=identifier)), + ], + ) + + def test_generates_empty_ast_from_empty_definitions() -> None: assert build_ast([]) == [] @@ -64,12 +75,12 @@ def test_generates_class_for_flat_definition() -> None: ), ast.Expr(value=ast.Constant(value="test resource property 1")), ast.AnnAssign( - target=ast.Name(id="_property1"), + target=ast.Name(id="property1__ext"), annotation=ast.Subscript( value=ast.Name(id="Optional_"), slice=ast.Constant("Element"), ), - value=ast.Constant(None), + value=build_field_with_alias("_property1"), simple=1, ), ast.Expr(value=ast.Constant(value="test resource property 1")), @@ -176,13 +187,13 @@ def test_generates_multiple_classes_for_compound_definition() -> None: value=ast.Constant(value="nested test resource property 1") ), ast.AnnAssign( - target=ast.Name(id="_property1"), + target=ast.Name(id="property1__ext"), annotation=ast.Subscript( value=ast.Name(id="Optional_"), slice=ast.Constant("Element"), ), simple=1, - value=ast.Constant(None), + value=build_field_with_alias("_property1"), ), ast.Expr( value=ast.Constant(value="nested test resource property 1") @@ -329,7 +340,7 @@ def test_generates_annotations_according_to_structure_type( ), ast.Expr(value=ast.Constant(value="test resource property 1")), ast.AnnAssign( - target=ast.Name(id="_property1"), + target=ast.Name(id="property1__ext"), annotation=ast.Subscript( value=ast.Name(id="Optional_"), slice=ast.Subscript( @@ -343,7 +354,7 @@ def test_generates_annotations_according_to_structure_type( slice=ast.Constant("Element"), ), simple=1, - value=ast.Constant(None), + value=build_field_with_alias("_property1"), ), ast.Expr(value=ast.Constant(value="test resource property 1")), ], @@ -418,13 +429,13 @@ def test_unrolls_required_polymorphic_into_class_union() -> None: ), ast.Expr(value=ast.Constant(value="monotype property definition")), ast.AnnAssign( - target=ast.Name(id="_monotype"), + target=ast.Name(id="monotype__ext"), annotation=ast.Subscript( value=ast.Name(id="Optional_"), slice=ast.Constant("Element"), ), simple=1, - value=ast.Constant(None), + value=build_field_with_alias("_monotype"), ), ast.Expr(value=ast.Constant(value="monotype property definition")), ast.AnnAssign( @@ -440,13 +451,13 @@ def test_unrolls_required_polymorphic_into_class_union() -> None: value=ast.Constant(value="polymorphic property definition") ), ast.AnnAssign( - target=ast.Name(id="_valueBoolean"), + target=ast.Name(id="valueBoolean__ext"), annotation=ast.Subscript( value=ast.Name(id="Optional_"), slice=ast.Constant("Element"), ), simple=1, - value=ast.Constant(None), + value=build_field_with_alias("_valueBoolean"), ), ast.Expr( value=ast.Constant(value="polymorphic property definition")