mirror of
https://github.com/kennethreitz/pydantic.git
synced 2026-06-05 23:00:18 +00:00
fix: smart union with typeddict (#3543)
This commit is contained in:
+2
-1
@@ -50,6 +50,7 @@ from .utils import (
|
||||
ValueItems,
|
||||
get_discriminator_alias_and_values,
|
||||
get_unique_discriminator_alias,
|
||||
lenient_isinstance,
|
||||
lenient_issubclass,
|
||||
sequence_like,
|
||||
smart_deepcopy,
|
||||
@@ -1048,7 +1049,7 @@ class ModelField(Representation):
|
||||
return v, None
|
||||
except TypeError:
|
||||
# compound type
|
||||
if isinstance(v, get_origin(field.outer_type_)):
|
||||
if lenient_isinstance(v, get_origin(field.outer_type_)):
|
||||
value, error = field.validate(v, values, loc=loc, cls=cls)
|
||||
if not error:
|
||||
return value, None
|
||||
|
||||
@@ -53,6 +53,7 @@ __all__ = (
|
||||
'import_string',
|
||||
'sequence_like',
|
||||
'validate_field_name',
|
||||
'lenient_isinstance',
|
||||
'lenient_issubclass',
|
||||
'in_ipython',
|
||||
'deep_update',
|
||||
@@ -163,6 +164,13 @@ def validate_field_name(bases: List[Type['BaseModel']], field_name: str) -> None
|
||||
)
|
||||
|
||||
|
||||
def lenient_isinstance(o: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...]]) -> bool:
|
||||
try:
|
||||
return isinstance(o, class_or_tuple)
|
||||
except TypeError:
|
||||
return False
|
||||
|
||||
|
||||
def lenient_issubclass(cls: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...]]) -> bool:
|
||||
try:
|
||||
return isinstance(cls, type) and issubclass(cls, class_or_tuple)
|
||||
|
||||
+17
-1
@@ -27,7 +27,7 @@ from typing import (
|
||||
from uuid import UUID
|
||||
|
||||
import pytest
|
||||
from typing_extensions import Literal
|
||||
from typing_extensions import Literal, TypedDict
|
||||
|
||||
from pydantic import (
|
||||
UUID1,
|
||||
@@ -3120,6 +3120,22 @@ def test_smart_union_compouned_types_edge_case():
|
||||
assert Model(x=[1, '2']).x == ['1', '2']
|
||||
|
||||
|
||||
def test_smart_union_typeddict():
|
||||
class Dict1(TypedDict):
|
||||
foo: str
|
||||
|
||||
class Dict2(TypedDict):
|
||||
bar: str
|
||||
|
||||
class M(BaseModel):
|
||||
d: Union[Dict2, Dict1]
|
||||
|
||||
class Config:
|
||||
smart_union = True
|
||||
|
||||
assert M(d=dict(foo='baz')).d == {'foo': 'baz'}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'value,result',
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user