@@ -230,47 +230,17 @@ def _model_flatten_map(self, model: TModel, prefix: str) -> Generator:
230230 if get_origin (model ) in UNION_TYPES :
231231 # If the model is a union type, process each type in the union
232232 for arg in get_args (model ):
233- if arg is type (None ):
234- continue # Skip NoneType
235233 yield from self ._model_flatten_map (arg , prefix )
236234 else :
237235 for attr , field in model .model_fields .items ():
238236 field_name = field .alias or attr
239237 name = f"{ prefix } { self .FLATTEN_PATH_SEP } { field_name } "
240238
241- # Check if this is a union type field
242- if get_origin (field .annotation ) in UNION_TYPES :
243- union_args = get_args (field .annotation )
244- has_none = type (None ) in union_args
245- non_none_args = [arg for arg in union_args if arg is not type (None )]
246-
247- # If it's an optional field (Union with None) and has a default value,
248- # don't flatten it - treat it as a single optional field
249- if has_none and field .default is not PydanticUndefined :
250- yield field_name , name
251- continue
252-
253- # For non-optional unions or unions without defaults,
254- # check if any of the union args are pydantic models
255- pydantic_args = [
256- arg for arg in non_none_args if is_pydantic_model (arg )
257- ]
258- if pydantic_args :
259- # This branch is unreachable because union fields with pydantic models
260- # are flattened during earlier processing stages
261- for arg in pydantic_args : # pragma: no cover
262- yield from self ._model_flatten_map (
263- arg , name
264- ) # pragma: no cover
265- else :
266- # No pydantic models in union, treat as simple field
267- yield field_name , name
268- # This else branch is unreachable because union fields are always processed above.
269- # Any field that reaches this point would have been handled by the union logic.
270- elif is_pydantic_model (field .annotation ): # pragma: no cover
271- yield from self ._model_flatten_map (field .annotation , name ) # type: ignore # pragma: no cover
272- else :
273- yield field_name , name
239+ if get_origin (
240+ field .annotation
241+ ) not in UNION_TYPES and is_pydantic_model (field .annotation ):
242+ yield from self ._model_flatten_map (field .annotation , name ) # type: ignore
243+ yield field_name , name
274244
275245 def _get_param_type (self , name : str , arg : inspect .Parameter ) -> FuncParam :
276246 # _EMPTY = self.signature.empty
@@ -332,9 +302,9 @@ def _get_param_type(self, name: str, arg: inspect.Parameter) -> FuncParam:
332302
333303 # 2) if param name is a part of the path parameter
334304 elif name in self .path_params_names :
335- assert (
336- default == self . signature . empty
337- ), f"' { name } ' is a path param, default not allowed"
305+ assert default == self . signature . empty , (
306+ f"' { name } ' is a path param, default not allowed"
307+ )
338308 param_source = Path (...)
339309
340310 # 3) if param is a collection, or annotation is part of pydantic model:
@@ -426,11 +396,11 @@ def detect_collection_fields(
426396 found = False
427397 # This for loop is unreachable in practice because union types with missing fields
428398 # should be handled earlier in the validation process
429- for arg in get_args (annotation_or_field ): # pragma: no cover
399+ for arg in get_args (annotation_or_field ):
430400 # This continue path is unreachable because NoneType handling is done earlier in union processing
431- if arg is type (None ): # pragma: no cover
432- continue # Skip NoneType # pragma: no cover
433- if hasattr (arg , "model_fields" ): # pragma: no cover
401+ if arg is type (None ):
402+ continue # Skip NoneType
403+ if hasattr (arg , "model_fields" ):
434404 found_field = next (
435405 (
436406 a
@@ -445,10 +415,10 @@ def detect_collection_fields(
445415 break
446416 # This error condition is unreachable because union fields are pre-validated
447417 # and all union members should have compatible field structures
448- if not found : # pragma: no cover
449- # No suitable field found in any union member, skip this path # pragma: no cover
450- annotation_or_field = None # pragma: no cover
451- break # Break out of the attr loop # pragma: no cover
418+ if not found :
419+ # No suitable field found in any union member, skip this path
420+ annotation_or_field = None
421+ break # Break out of the attr loop
452422 else :
453423 annotation_or_field = next (
454424 (
@@ -457,21 +427,21 @@ def detect_collection_fields(
457427 if a .alias == attr
458428 ),
459429 annotation_or_field .model_fields .get (attr ),
460- ) # pragma: no cover
430+ )
461431
462432 annotation_or_field = getattr (
463433 annotation_or_field , "outer_type_" , annotation_or_field
464434 )
465435
466436 # This condition is unreachable because union processing failures are handled above
467437 # and annotation_or_field should never be None at this point in normal operation
468- if annotation_or_field is None : # pragma: no cover
469- continue # pragma: no cover
438+ if annotation_or_field is None :
439+ continue
470440
471441 # This condition is unreachable because annotation access is handled in the union processing
472442 # and should not require additional annotation unwrapping at this point
473- if hasattr (annotation_or_field , "annotation" ): # pragma: no cover
474- annotation_or_field = annotation_or_field .annotation # pragma: no cover
443+ if hasattr (annotation_or_field , "annotation" ):
444+ annotation_or_field = annotation_or_field .annotation
475445
476446 if is_collection_type (annotation_or_field ):
477447 result .append (path [- 1 ])
0 commit comments