@@ -208,14 +208,18 @@ def construct( # pyright: ignore[reportIncompatibleMethodOverride]
208208 else :
209209 fields_values [name ] = field_get_default (field )
210210
211+ extra_field_type = _get_extra_fields_type (__cls )
212+
211213 _extra = {}
212214 for key , value in values .items ():
213215 if key not in model_fields :
216+ parsed = construct_type (value = value , type_ = extra_field_type ) if extra_field_type is not None else value
217+
214218 if PYDANTIC_V2 :
215- _extra [key ] = value
219+ _extra [key ] = parsed
216220 else :
217221 _fields_set .add (key )
218- fields_values [key ] = value
222+ fields_values [key ] = parsed
219223
220224 object .__setattr__ (m , "__dict__" , fields_values )
221225
@@ -370,6 +374,23 @@ def _construct_field(value: object, field: FieldInfo, key: str) -> object:
370374 return construct_type (value = value , type_ = type_ , metadata = getattr (field , "metadata" , None ))
371375
372376
377+ def _get_extra_fields_type (cls : type [pydantic .BaseModel ]) -> type | None :
378+ if not PYDANTIC_V2 :
379+ # TODO
380+ return None
381+
382+ schema = cls .__pydantic_core_schema__
383+ if schema ["type" ] == "model" :
384+ fields = schema ["schema" ]
385+ if fields ["type" ] == "model-fields" :
386+ extras = fields .get ("extras_schema" )
387+ if extras and "cls" in extras :
388+ # mypy can't narrow the type
389+ return extras ["cls" ] # type: ignore[no-any-return]
390+
391+ return None
392+
393+
373394def is_basemodel (type_ : type ) -> bool :
374395 """Returns whether or not the given type is either a `BaseModel` or a union of `BaseModel`"""
375396 if is_union (type_ ):
0 commit comments