@@ -79,11 +79,13 @@ def format_identifier(
79
79
def uppercamelcase (s : str ) -> str :
80
80
return s [:1 ].upper () + s [1 :]
81
81
82
- return (
83
- identifier + uppercamelcase (type_ .code )
84
- if is_polymorphic (definition )
85
- else identifier
86
- )
82
+ if is_polymorphic (definition ):
83
+ # TODO: it's fast hack
84
+ if type_ .code [0 ].islower ():
85
+ return identifier + uppercamelcase (clear_primitive_id (type_ .code ))
86
+ return identifier + uppercamelcase (type_ .code )
87
+
88
+ return identifier
87
89
88
90
89
91
def remap_type (
@@ -94,8 +96,8 @@ def remap_type(
94
96
case "Resource" :
95
97
# Different contexts use 'Resource' type to refer to any
96
98
# resource differentiated by its 'resourceType' (tagged union).
97
- # 'AnyResource' is not defined by the spec but rather
98
- # generated as a union of all defined resource types.
99
+ # 'AnyResource' is defined in header as a special type
100
+ # that dynamically replaced with a right type in run-time
99
101
type_ = replace (type_ , code = "AnyResource" )
100
102
101
103
if is_polymorphic (definition ):
@@ -106,6 +108,12 @@ def remap_type(
106
108
# with a custom validator that will enforce single required property rule.
107
109
type_ = replace (type_ , required = False )
108
110
111
+ if is_primitive_type (type_ ):
112
+ # Primitive types defined from the small letter (like code)
113
+ # and it might overlap with model fields
114
+ # e.g. QuestionnaireItem has attribute code and linkId has type code
115
+ type_ = replace (type_ , code = make_primitive_id (type_ .code ))
116
+
109
117
return type_
110
118
111
119
@@ -116,9 +124,8 @@ def zip_identifier_type(
116
124
117
125
for t in [remap_type (definition , t ) for t in definition .type ]:
118
126
result .append ((format_identifier (definition , identifier , t ), t ))
119
- if (
120
- definition .kind != StructureDefinitionKind .PRIMITIVE
121
- and is_primitive_type (t )
127
+ if definition .kind != StructureDefinitionKind .PRIMITIVE and is_primitive_type (
128
+ t
122
129
):
123
130
result .append (
124
131
(
@@ -201,11 +208,6 @@ def define_class_object(
201
208
keywords = [],
202
209
type_params = [],
203
210
),
204
- ast .Call (
205
- ast .Attribute (value = ast .Name (definition .id ), attr = "update_forward_refs" ),
206
- args = [],
207
- keywords = [],
208
- ),
209
211
]
210
212
211
213
@@ -214,48 +216,22 @@ def define_class(definition: StructureDefinition) -> Iterable[ast.stmt | ast.exp
214
216
215
217
216
218
def define_alias (definition : StructureDefinition ) -> Iterable [ast .stmt ]:
217
- return type_annotate (definition , definition .id , AnnotationForm .TypeAlias )
218
-
219
-
220
- def define_tagged_union (
221
- name : str , components : Iterable [StructureDefinition ], distinct_by : str
222
- ) -> ast .stmt :
223
- annotation = functools .reduce (
224
- lambda acc , n : ast .BinOp (left = acc , right = n , op = ast .BitOr ()),
225
- (cast (ast .expr , ast .Name (d .id )) for d in components ),
219
+ # Primitive types are renamed to another name to avoid overlapping with model fields
220
+ return type_annotate (
221
+ definition , make_primitive_id (definition .id ), AnnotationForm .TypeAlias
226
222
)
227
223
228
- return ast .Assign (
229
- targets = [ast .Name (name )],
230
- value = ast .Subscript (
231
- value = ast .Name ("Annotated_" ),
232
- slice = ast .Tuple (
233
- elts = [
234
- annotation ,
235
- ast .Call (
236
- ast .Name ("Field" ),
237
- args = [ast .Constant (...)],
238
- keywords = [
239
- ast .keyword (
240
- arg = "discriminator" , value = ast .Constant (distinct_by )
241
- ),
242
- ],
243
- ),
244
- ]
245
- ),
246
- ),
247
- )
248
224
225
+ def make_primitive_id (name : str ) -> str :
226
+ if name in ("str" , "int" , "float" , "bool" ):
227
+ return name
228
+ return f"{ name } Type"
249
229
250
- def select_tagged_resources (
251
- definitions : Iterable [StructureDefinition ], key : str
252
- ) -> Iterable [StructureDefinition ]:
253
- return (
254
- definition
255
- for definition in definitions
256
- if definition .kind == StructureDefinitionKind .RESOURCE
257
- and key in definition .elements
258
- )
230
+
231
+ def clear_primitive_id (name : str ) -> str :
232
+ if name .endswith ("Type" ):
233
+ return name [:- 4 ]
234
+ return name
259
235
260
236
261
237
def select_nested_definitions (
@@ -301,14 +277,6 @@ def build_ast(
301
277
f"Unsupported definition { definition .id } of kind { definition .kind } , skipping"
302
278
)
303
279
304
- resources = list (select_tagged_resources (structure_definitions , key = "resourceType" ))
305
- if resources :
306
- typedefinitions .append (
307
- define_tagged_union (
308
- name = "AnyResource" , components = resources , distinct_by = "resourceType"
309
- )
310
- )
311
-
312
280
return sorted (
313
281
typedefinitions ,
314
282
# Defer any postprocessing until after the structure tree is defined.
0 commit comments