@@ -37,9 +37,9 @@ def type_to_python_helper(type_, schema, alternative_name=None, in_list=False):
37
37
elif type_ == "boolean" :
38
38
return "bool"
39
39
elif type_ == "array" :
40
- subtype = type_to_python (schema ["items" ], in_list = True )
40
+ subtype = type_to_python (schema ["items" ], alternative_name = alternative_name + "Item" if alternative_name else None , in_list = True )
41
41
if schema ["items" ].get ("nullable" ):
42
- subtype += ", none_type"
42
+ subtype += ", none_type"
43
43
return "[{}]" .format (subtype )
44
44
elif type_ == "object" :
45
45
if "additionalProperties" in schema :
@@ -51,7 +51,7 @@ def type_to_python_helper(type_, schema, alternative_name=None, in_list=False):
51
51
return (
52
52
alternative_name
53
53
if alternative_name
54
- and ("properties" in schema or "oneOf" in schema or "anyOf" in schema or "allOf" in schema )
54
+ and ("properties" in schema or "oneOf" in schema )
55
55
else "dict"
56
56
)
57
57
elif type_ == "null" :
@@ -63,12 +63,15 @@ def type_to_python_helper(type_, schema, alternative_name=None, in_list=False):
63
63
def type_to_python (schema , alternative_name = None , in_list = False ):
64
64
"""Return Python type name for the type."""
65
65
name = formatter .get_name (schema )
66
- if name :
66
+ if name and "items" not in schema :
67
67
if "enum" in schema :
68
68
return name
69
- if schema .get ("type" , "object" ) in ( "object" , "array" ) :
69
+ if schema .get ("type" , "object" ) == "object" :
70
70
return name
71
71
72
+ if name :
73
+ alternative_name = name
74
+
72
75
type_ = schema .get ("type" )
73
76
if type_ is None :
74
77
if "oneOf" in schema and in_list :
@@ -111,7 +114,7 @@ def typing_to_python_helper(type_, schema, alternative_name=None, in_list=False)
111
114
elif type_ == "boolean" :
112
115
return "bool"
113
116
elif type_ == "array" :
114
- return "List[{}]" .format (typing_to_python (schema ["items" ], in_list = True ))
117
+ return "List[{}]" .format (typing_to_python (schema ["items" ], alternative_name = alternative_name + "Item" if alternative_name else None , in_list = True ))
115
118
elif type_ == "object" :
116
119
if "additionalProperties" in schema :
117
120
nested_schema = schema ["additionalProperties" ]
@@ -122,7 +125,7 @@ def typing_to_python_helper(type_, schema, alternative_name=None, in_list=False)
122
125
return (
123
126
alternative_name
124
127
if alternative_name
125
- and ("properties" in schema or "oneOf" in schema or "anyOf" in schema or "allOf" in schema )
128
+ and ("properties" in schema or "oneOf" in schema )
126
129
else "dict"
127
130
)
128
131
elif type_ == "null" :
@@ -137,13 +140,16 @@ def typing_to_python(schema, alternative_name=None, in_list=False):
137
140
if name :
138
141
if "enum" in schema :
139
142
return name
140
- if schema .get ("type" , "object" ) in ( "object" , "array" ) :
143
+ if schema .get ("type" , "object" ) == "object" :
141
144
if "oneOf" in schema :
142
145
types = [name ]
143
- types .extend (get_oneof_types (schema ))
146
+ types .extend (get_oneof_types (schema , typing = True ))
144
147
return f"Union[{ ',' .join (types )} ]"
145
148
return name
146
149
150
+ if name :
151
+ alternative_name = name
152
+
147
153
type_ = schema .get ("type" )
148
154
if type_ is None :
149
155
if "oneOf" in schema and in_list :
@@ -154,7 +160,7 @@ def typing_to_python(schema, alternative_name=None, in_list=False):
154
160
type_ += f"{ typing_to_python_helper (child .get ('type' ), child , in_list = in_list )} ,"
155
161
else :
156
162
type_ += f"{ typing_to_python (child , in_list = in_list )} ,"
157
- return type_
163
+ return f"Union[ { type_ } ]"
158
164
if "items" in schema :
159
165
type_ = "array"
160
166
@@ -227,21 +233,18 @@ def child_models(schema, alternative_name=None, seen=None, in_list=False):
227
233
name = current_name or alternative_name
228
234
229
235
has_sub_models = False
230
- if "allOf" in schema :
231
- has_sub_models = True
232
- for child in schema ["allOf" ]:
233
- yield from child_models (child , seen = seen )
234
236
if "oneOf" in schema :
235
- has_sub_models = True
237
+ has_sub_models = not in_list
236
238
for child in schema ["oneOf" ]:
237
- yield from child_models (child , seen = seen )
238
- if "anyOf" in schema :
239
- has_sub_models = True
240
- for child in schema ["anyOf" ]:
241
- yield from child_models (child , seen = seen )
239
+ sub_models = list (child_models (child , seen = seen ))
240
+ if sub_models :
241
+ has_sub_models = True
242
+ yield from sub_models
243
+ if in_list and not has_sub_models :
244
+ return
242
245
243
246
if "items" in schema :
244
- yield from child_models (schema ["items" ], None , seen = seen , in_list = True )
247
+ yield from child_models (schema ["items" ], alternative_name = name + "Item" if name is not None else None , seen = seen , in_list = True )
245
248
246
249
if schema .get ("type" ) == "object" or "properties" in schema or has_sub_models :
247
250
if not has_sub_models and name is None :
@@ -265,13 +268,6 @@ def child_models(schema, alternative_name=None, seen=None, in_list=False):
265
268
for key , child in schema .get ("properties" , {}).items ():
266
269
yield from child_models (child , alternative_name = name + formatter .camel_case (key ), seen = seen )
267
270
268
- if current_name and schema .get ("type" ) == "array" :
269
- if name in seen :
270
- return
271
-
272
- seen .add (name )
273
- yield name , schema
274
-
275
271
if "enum" in schema :
276
272
if name is None :
277
273
raise ValueError (f"Schema { schema } has no name" )
@@ -315,6 +311,17 @@ def models(spec):
315
311
return name_to_schema
316
312
317
313
314
+ def find_non_primitive_type (schema ):
315
+ if schema .get ("enum" ):
316
+ return True
317
+ sub_type = schema .get ("type" )
318
+ if sub_type == "array" :
319
+ return find_non_primitive_type (schema ["items" ])
320
+ if sub_type not in PRIMITIVE_TYPES :
321
+ return True
322
+ return False
323
+
324
+
318
325
def get_references_for_model (model , model_name ):
319
326
result = {}
320
327
top_name = formatter .get_name (model ) or model_name
@@ -330,13 +337,12 @@ def get_references_for_model(model, model_name):
330
337
if name :
331
338
result [name ] = None
332
339
elif definition .get ("type" ) == "array" :
333
- name = formatter .get_name (definition )
334
- if name :
340
+ name = formatter .get_name (definition . get ( "items" ) )
341
+ if name and find_non_primitive_type ( definition [ "items" ]) :
335
342
result [name ] = None
336
- else :
337
- name = formatter .get_name (definition .get ("items" ))
338
- if name :
339
- result [name ] = None
343
+ elif formatter .get_name (definition ) and definition ["items" ].get ("type" ) not in PRIMITIVE_TYPES :
344
+ result [formatter .get_name (definition ) + "Item" ] = None
345
+
340
346
elif definition .get ("properties" ) and top_name :
341
347
result [top_name + formatter .camel_case (key )] = None
342
348
if model .get ("additionalProperties" ):
@@ -365,8 +371,12 @@ def get_oneof_references_for_model(model, model_name, seen=None):
365
371
if model .get ("oneOf" ):
366
372
for schema in model ["oneOf" ]:
367
373
type_ = schema .get ("type" , "object" )
368
- if type_ in ( "array" , " object") :
374
+ if type_ == " object" :
369
375
result [formatter .get_name (schema )] = None
376
+ elif type_ == "array" :
377
+ sub_name = formatter .get_name (schema ["items" ])
378
+ if sub_name :
379
+ result [sub_name ] = None
370
380
371
381
for key , definition in model .get ("properties" , {}).items ():
372
382
result .update ({k : None for k in get_oneof_references_for_model (definition , model_name , seen )})
@@ -389,11 +399,18 @@ def get_oneof_parameters(model):
389
399
yield attr , definition , schema
390
400
391
401
392
- def get_oneof_types (model ):
402
+ def get_oneof_types (model , typing = False ):
393
403
for schema in model ["oneOf" ]:
394
404
type_ = schema .get ("type" , "object" )
395
- if type_ in ( "array" , " object") :
405
+ if type_ == " object" :
396
406
yield formatter .get_name (schema )
407
+ elif type_ == "array" :
408
+ name = formatter .get_name (schema ["items" ])
409
+ if name :
410
+ if typing :
411
+ yield f"List[{ name } ]"
412
+ else :
413
+ yield f"[{ name } ]"
397
414
elif type_ == "integer" :
398
415
yield "int"
399
416
elif type_ == "string" :
@@ -409,8 +426,13 @@ def get_oneof_types(model):
409
426
def get_oneof_models (model ):
410
427
result = []
411
428
for schema in model ["oneOf" ]:
412
- if schema .get ("type" , "object" ) in ("array" , "object" ):
429
+ type_ = schema .get ("type" , "object" )
430
+ if type_ == "object" :
413
431
result .append (formatter .get_name (schema ))
432
+ elif type_ == "array" :
433
+ name = formatter .get_name (schema ["items" ])
434
+ if name :
435
+ result .append (name )
414
436
return result
415
437
416
438
@@ -464,12 +486,17 @@ def get_api_models(operations):
464
486
yield name
465
487
if "oneOf" in content ["schema" ]:
466
488
for schema in content ["schema" ]["oneOf" ]:
467
- type_ = schema .get ("type" , "object" )
468
- if type_ in ("array" , "object" ):
489
+ if schema .get ("type" , "object" ) == "object" :
469
490
name = formatter .get_name (schema )
470
491
if name and name not in seen :
471
492
seen .add (name )
472
493
yield name
494
+ if "items" in content ["schema" ]:
495
+ name = formatter .get_name (content ["schema" ]["items" ])
496
+ if name and name not in seen :
497
+ seen .add (name )
498
+ yield name
499
+
473
500
if "x-pagination" in operation :
474
501
name = get_type_at_path (operation , operation ["x-pagination" ]["resultsPath" ])
475
502
if name and name not in seen :
0 commit comments