@@ -54,6 +54,12 @@ def __lt__(self, other: Any) -> bool:
5454
5555
5656def get_comparable_type (value : Any ) -> Optional [ComparableType ]:
57+ if isinstance (value , list ):
58+ non_null_types = [item for item in value if item != "null" ]
59+ if non_null_types :
60+ return get_comparable_type (non_null_types [0 ])
61+ else :
62+ return ComparableType .NULL
5763 if value == "null" :
5864 return ComparableType .NULL
5965 if value == "boolean" :
@@ -121,14 +127,42 @@ def merge_schemas(schema1: SchemaType, schema2: SchemaType) -> SchemaType:
121127
122128
123129def _is_valid_type (t : JsonSchemaSupportedType ) -> bool :
130+ if isinstance (t , list ):
131+ return all (get_comparable_type (item ) is not None for item in t )
124132 return t == "array" or get_comparable_type (t ) is not None
125133
126134
127135def _choose_wider_type (key : str , t1 : Mapping [str , Any ], t2 : Mapping [str , Any ]) -> Mapping [str , Any ]:
128136 t1_type = t1 ["type" ]
129137 t2_type = t2 ["type" ]
130138
131- if (t1_type == "array" or t2_type == "array" ) and t1 != t2 :
139+ if isinstance (t1_type , list ) and isinstance (t2_type , list ):
140+ if set (t1_type ).issubset (set (t2_type )):
141+ return t2
142+ elif set (t2_type ).issubset (set (t1_type )):
143+ return t1
144+ else :
145+ combined_types = list (set (t1_type ).union (set (t2_type )))
146+ result = dict (t1 )
147+ result ["type" ] = combined_types
148+ return result
149+ elif isinstance (t1_type , list ):
150+ if t2_type in t1_type :
151+ return t1
152+ else :
153+ combined_types = list (set (t1_type + [t2_type ]))
154+ result = dict (t1 )
155+ result ["type" ] = combined_types
156+ return result
157+ elif isinstance (t2_type , list ):
158+ if t1_type in t2_type :
159+ return t2
160+ else :
161+ combined_types = list (set (t2_type + [t1_type ]))
162+ result = dict (t2 )
163+ result ["type" ] = combined_types
164+ return result
165+ elif (t1_type == "array" or t2_type == "array" ) and t1 != t2 :
132166 raise SchemaInferenceError (
133167 FileBasedSourceError .SCHEMA_INFERENCE_ERROR ,
134168 details = "Cannot merge schema for unequal array types." ,
@@ -149,20 +183,36 @@ def _choose_wider_type(key: str, t1: Mapping[str, Any], t2: Mapping[str, Any]) -
149183 detected_types = f"{ t1 } ,{ t2 } " ,
150184 )
151185 else :
152- comparable_t1 = get_comparable_type (
153- TYPE_PYTHON_MAPPING [t1_type ][0 ]
154- ) # accessing the type_mapping value
155- comparable_t2 = get_comparable_type (
156- TYPE_PYTHON_MAPPING [t2_type ][0 ]
157- ) # accessing the type_mapping value
158- if not comparable_t1 and comparable_t2 :
159- raise SchemaInferenceError (
160- FileBasedSourceError .UNRECOGNIZED_TYPE , key = key , detected_types = f"{ t1 } ,{ t2 } "
161- )
162- return max (
163- [t1 , t2 ],
164- key = lambda x : ComparableType (get_comparable_type (TYPE_PYTHON_MAPPING [x ["type" ]][0 ])),
165- ) # accessing the type_mapping value
186+ if not isinstance (t1_type , list ) and not isinstance (t2_type , list ):
187+ comparable_t1 = get_comparable_type (
188+ TYPE_PYTHON_MAPPING [t1_type ][0 ]
189+ ) # accessing the type_mapping value
190+ comparable_t2 = get_comparable_type (
191+ TYPE_PYTHON_MAPPING [t2_type ][0 ]
192+ ) # accessing the type_mapping value
193+ if not comparable_t1 and comparable_t2 :
194+ raise SchemaInferenceError (
195+ FileBasedSourceError .UNRECOGNIZED_TYPE , key = key , detected_types = f"{ t1 } ,{ t2 } "
196+ )
197+ return max (
198+ [t1 , t2 ],
199+ key = lambda x : ComparableType (get_comparable_type (TYPE_PYTHON_MAPPING [x ["type" ]][0 ])),
200+ ) # accessing the type_mapping value
201+
202+ combined_types = []
203+ if isinstance (t1_type , list ):
204+ combined_types .extend (t1_type )
205+ else :
206+ combined_types .append (t1_type )
207+
208+ if isinstance (t2_type , list ):
209+ combined_types .extend (t2_type )
210+ else :
211+ combined_types .append (t2_type )
212+
213+ result = dict (t1 )
214+ result ["type" ] = list (set (combined_types ))
215+ return result
166216
167217
168218def is_equal_or_narrower_type (value : Any , expected_type : str ) -> bool :
0 commit comments