18
18
DateSchema ,
19
19
EnumSchema ,
20
20
FileSchema ,
21
+ ListSchema ,
21
22
NoneSchema ,
22
23
SchemaData ,
23
24
FloatSchema ,
@@ -109,11 +110,13 @@ def _is_string_subset(
109
110
def _is_model_merge (
110
111
source : Source , name : str , prefix : str , first : SchemaData , second : SchemaData
111
112
) -> Optional [ModelSchema ]:
112
- if isinstance (first , ModelSchema ) and isinstance (second , ModelSchema ):
113
- properties = {prop .name : prop for prop in first .properties }
113
+ if (first_model := _find_schema (first , ModelSchema )) and (
114
+ second_model := _find_schema (second , ModelSchema )
115
+ ):
116
+ properties = {prop .name : prop for prop in first_model .properties }
114
117
class_name = build_class_name (prefix )
115
118
116
- for prop in second .properties :
119
+ for prop in second_model .properties :
117
120
if prop .name in properties :
118
121
# try merge
119
122
try :
@@ -133,12 +136,42 @@ def _is_model_merge(
133
136
schema = ModelSchema (
134
137
class_name = class_name ,
135
138
properties = list (properties .values ()),
136
- allow_extra = first .allow_extra and second .allow_extra ,
139
+ allow_extra = first_model .allow_extra and second_model .allow_extra ,
137
140
)
138
141
add_schema ((source / "allof" / "merged" / name ).uri , schema )
139
142
return schema
140
143
141
144
145
+ def _is_list_merge (
146
+ source : Source , name : str , prefix : str , first : SchemaData , second : SchemaData
147
+ ) -> Optional [ListSchema ]:
148
+ if isinstance (first , ListSchema ) and isinstance (second , ListSchema ):
149
+ return ListSchema (
150
+ title = first .title ,
151
+ description = first .description ,
152
+ default = first .default ,
153
+ examples = first .examples ,
154
+ item_schema = _merge_schema (
155
+ source , name , prefix , first .item_schema , second .item_schema
156
+ ),
157
+ )
158
+
159
+
160
+ def _merge_schema (
161
+ source : Source , name : str , prefix : str , first : SchemaData , second : SchemaData
162
+ ):
163
+ if schema := (
164
+ _is_union_subset (first , second )
165
+ or _is_string_subset (first , second )
166
+ or _is_string_subset (second , first )
167
+ or _is_enum_subset (first , second )
168
+ or _is_model_merge (source , name , prefix , first , second )
169
+ or _is_list_merge (source , name , prefix , first , second )
170
+ ):
171
+ return schema
172
+ raise RuntimeError (f"Cannot merge schema { first !r} { second !r} " )
173
+
174
+
142
175
def _merge_property (
143
176
source : Source , first : Property , second : Property , prefix : str
144
177
) -> Property :
@@ -148,31 +181,23 @@ def _merge_property(
148
181
required = first .required or second .required
149
182
nullable = _is_nullable (first .schema_data ) and _is_nullable (second .schema_data )
150
183
151
- if schema := (
152
- _is_union_subset (first .schema_data , second .schema_data )
153
- or _is_string_subset (first .schema_data , second .schema_data )
154
- or _is_string_subset (second .schema_data , first .schema_data )
155
- or _is_enum_subset (first .schema_data , second .schema_data )
156
- or _is_model_merge (
157
- source , first .name , prefix , first .schema_data , second .schema_data
158
- )
159
- ):
160
- if nullable :
161
- schema = UnionSchema (
162
- title = schema .title ,
163
- description = schema .description ,
164
- default = schema .default ,
165
- examples = schema .examples ,
166
- schemas = [schema , NoneSchema ()],
167
- )
168
- return Property (
169
- name = second .name ,
170
- prop_name = second .prop_name ,
171
- required = required ,
172
- schema_data = schema ,
184
+ schema = _merge_schema (
185
+ source , first .name , prefix , first .schema_data , second .schema_data
186
+ )
187
+ if nullable :
188
+ schema = UnionSchema (
189
+ title = schema .title ,
190
+ description = schema .description ,
191
+ default = schema .default ,
192
+ examples = schema .examples ,
193
+ schemas = [schema , NoneSchema ()],
173
194
)
174
-
175
- raise RuntimeError (f"Cannot merge property { first !r} { second !r} " )
195
+ return Property (
196
+ name = second .name ,
197
+ prop_name = second .prop_name ,
198
+ required = required ,
199
+ schema_data = schema ,
200
+ )
176
201
177
202
178
203
def _process_properties (
@@ -247,7 +272,6 @@ def _add_if_no_conflict(prop: Property):
247
272
schema_data = prop_schema ,
248
273
)
249
274
)
250
-
251
275
return list (properties .values ())
252
276
253
277
0 commit comments