2
2
3
3
import os
4
4
import 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
6
6
from datetime import date , datetime
7
7
from typing_extensions import (
8
+ List ,
8
9
Unpack ,
9
10
Literal ,
10
11
ClassVar ,
@@ -366,7 +367,7 @@ def _construct_field(value: object, field: FieldInfo, key: str) -> object:
366
367
if type_ is None :
367
368
raise RuntimeError (f"Unexpected field type is None for { key } " )
368
369
369
- return construct_type (value = value , type_ = type_ )
370
+ return construct_type (value = value , type_ = type_ , metadata = getattr ( field , "metadata" , None ) )
370
371
371
372
372
373
def is_basemodel (type_ : type ) -> bool :
@@ -420,7 +421,7 @@ def construct_type_unchecked(*, value: object, type_: type[_T]) -> _T:
420
421
return cast (_T , construct_type (value = value , type_ = type_ ))
421
422
422
423
423
- def construct_type (* , value : object , type_ : object ) -> object :
424
+ def construct_type (* , value : object , type_ : object , metadata : Optional [ List [ Any ]] = None ) -> object :
424
425
"""Loose coercion to the expected type with construction of nested values.
425
426
426
427
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:
438
439
type_ = type_ .__value__ # type: ignore[unreachable]
439
440
440
441
# 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 :]
443
446
type_ = extract_type_arg (type_ , 0 )
444
447
else :
445
448
meta = tuple ()
0 commit comments