@@ -783,21 +783,57 @@ def load_engine_object(expected_type: Any, v: Any) -> Any:
783783 # Drop auxiliary discriminator "kind" if present
784784 dc_init_kwargs : dict [str , Any ] = {}
785785 field_types = {f .name : f .type for f in dataclasses .fields (struct_type )}
786+ dataclass_fields = {f .name : f for f in dataclasses .fields (struct_type )}
787+
786788 for name , f_type in field_types .items ():
787789 if name in v :
788790 dc_init_kwargs [name ] = load_engine_object (f_type , v [name ])
791+ else :
792+ # Field is missing from input, check if it has a default or can use auto-default
793+ field = dataclass_fields [name ]
794+ if field .default is not dataclasses .MISSING :
795+ # Field has an explicit default value
796+ dc_init_kwargs [name ] = field .default
797+ elif field .default_factory is not dataclasses .MISSING :
798+ # Field has a default factory
799+ dc_init_kwargs [name ] = field .default_factory ()
800+ else :
801+ # No explicit default, try to get auto-default
802+ type_info = analyze_type_info (f_type )
803+ auto_default , is_supported = _get_auto_default_for_type (
804+ type_info
805+ )
806+ if is_supported :
807+ dc_init_kwargs [name ] = auto_default
808+ # If not supported, skip the field (let dataclass constructor handle the error)
789809 return struct_type (** dc_init_kwargs )
790810 elif is_namedtuple_type (struct_type ):
791811 if not isinstance (v , Mapping ):
792812 raise ValueError (f"Expected dict for NamedTuple, got { type (v )} " )
793813 # Dict format (from dump/load functions)
794814 annotations = getattr (struct_type , "__annotations__" , {})
795815 field_names = list (getattr (struct_type , "_fields" , ()))
816+ field_defaults = getattr (struct_type , "_field_defaults" , {})
796817 nt_init_kwargs : dict [str , Any ] = {}
818+
797819 for name in field_names :
798820 f_type = annotations .get (name , Any )
799821 if name in v :
800822 nt_init_kwargs [name ] = load_engine_object (f_type , v [name ])
823+ else :
824+ # Field is missing from input, check if it has a default or can use auto-default
825+ if name in field_defaults :
826+ # Field has an explicit default value
827+ nt_init_kwargs [name ] = field_defaults [name ]
828+ else :
829+ # No explicit default, try to get auto-default
830+ type_info = analyze_type_info (f_type )
831+ auto_default , is_supported = _get_auto_default_for_type (
832+ type_info
833+ )
834+ if is_supported :
835+ nt_init_kwargs [name ] = auto_default
836+ # If not supported, skip the field (let NamedTuple constructor handle the error)
801837 return struct_type (** nt_init_kwargs )
802838 elif is_pydantic_model (struct_type ):
803839 if not isinstance (v , Mapping ):
@@ -812,9 +848,33 @@ def load_engine_object(expected_type: Any, v: Any) -> Any:
812848 field_types = {
813849 name : field .annotation for name , field in model_fields .items ()
814850 }
851+
815852 for name , f_type in field_types .items ():
816853 if name in v :
817854 pydantic_init_kwargs [name ] = load_engine_object (f_type , v [name ])
855+ else :
856+ # Field is missing from input, check if it has a default or can use auto-default
857+ field = model_fields [name ]
858+ if (
859+ hasattr (field , "default" ) and field .default is not ...
860+ ): # ... is Pydantic's sentinel for no default
861+ # Field has an explicit default value
862+ pydantic_init_kwargs [name ] = field .default
863+ elif (
864+ hasattr (field , "default_factory" )
865+ and field .default_factory is not None
866+ ):
867+ # Field has a default factory
868+ pydantic_init_kwargs [name ] = field .default_factory ()
869+ else :
870+ # No explicit default, try to get auto-default
871+ type_info = analyze_type_info (f_type )
872+ auto_default , is_supported = _get_auto_default_for_type (
873+ type_info
874+ )
875+ if is_supported :
876+ pydantic_init_kwargs [name ] = auto_default
877+ # If not supported, skip the field (let Pydantic constructor handle the error)
818878 return struct_type (** pydantic_init_kwargs )
819879 return v
820880
0 commit comments