22
33import os
44import inspect
5- from typing import TYPE_CHECKING , Any , Type , Union , Generic , TypeVar , Callable , cast
5+ from typing import TYPE_CHECKING , Any , Type , Union , Generic , TypeVar , Callable , Optional , cast
66from datetime import date , datetime
77from typing_extensions import (
8+ List ,
89 Unpack ,
910 Literal ,
1011 ClassVar ,
@@ -366,7 +367,7 @@ def _construct_field(value: object, field: FieldInfo, key: str) -> object:
366367 if type_ is None :
367368 raise RuntimeError (f"Unexpected field type is None for { key } " )
368369
369- return construct_type (value = value , type_ = type_ )
370+ return construct_type (value = value , type_ = type_ , metadata = getattr ( field , "metadata" , None ) )
370371
371372
372373def is_basemodel (type_ : type ) -> bool :
@@ -420,7 +421,7 @@ def construct_type_unchecked(*, value: object, type_: type[_T]) -> _T:
420421 return cast (_T , construct_type (value = value , type_ = type_ ))
421422
422423
423- def construct_type (* , value : object , type_ : object ) -> object :
424+ def construct_type (* , value : object , type_ : object , metadata : Optional [ List [ Any ]] = None ) -> object :
424425 """Loose coercion to the expected type with construction of nested values.
425426
426427 If the given value does not match the expected type then it is returned as-is.
@@ -438,8 +439,10 @@ def construct_type(*, value: object, type_: object) -> object:
438439 type_ = type_ .__value__ # type: ignore[unreachable]
439440
440441 # unwrap `Annotated[T, ...]` -> `T`
441- if is_annotated_type (type_ ):
442- meta : tuple [Any , ...] = get_args (type_ )[1 :]
442+ if metadata is not None :
443+ meta : tuple [Any , ...] = tuple (metadata )
444+ elif is_annotated_type (type_ ):
445+ meta = get_args (type_ )[1 :]
443446 type_ = extract_type_arg (type_ , 0 )
444447 else :
445448 meta = tuple ()
0 commit comments