feat: pass config to NamedTuple fields (#4225)

* feat: pass config to create_model_from_namedtuple

* feat: tests for arbitrary_types_allowed in NamedTuple fields

* misc: add changelog file for the PR
This commit is contained in:
Rory Byrne
2022-08-08 20:33:30 +01:00
committed by GitHub
parent d90def3c4e
commit f6c74a55d5
3 changed files with 29 additions and 2 deletions
+1
View File
@@ -0,0 +1 @@
Use parent model's `Config` when validating nested `NamedTuple` fields.
+5 -2
View File
@@ -567,11 +567,14 @@ def pattern_validator(v: Any) -> Pattern[str]:
NamedTupleT = TypeVar('NamedTupleT', bound=NamedTuple)
def make_namedtuple_validator(namedtuple_cls: Type[NamedTupleT]) -> Callable[[Tuple[Any, ...]], NamedTupleT]:
def make_namedtuple_validator(
namedtuple_cls: Type[NamedTupleT], config: Type['BaseConfig']
) -> Callable[[Tuple[Any, ...]], NamedTupleT]:
from .annotated_types import create_model_from_namedtuple
NamedTupleModel = create_model_from_namedtuple(
namedtuple_cls,
__config__=config,
__module__=namedtuple_cls.__module__,
)
namedtuple_cls.__pydantic_model__ = NamedTupleModel # type: ignore[attr-defined]
@@ -704,7 +707,7 @@ def find_validators( # noqa: C901 (ignore complexity)
return
if is_namedtuple(type_):
yield tuple_validator
yield make_namedtuple_validator(type_)
yield make_namedtuple_validator(type_, config)
return
if is_typeddict(type_):
yield make_typeddict_validator(type_, config)
+23
View File
@@ -151,6 +151,29 @@ def test_namedtuple_postponed_annotation():
Model.parse_obj({'t': [-1]})
def test_namedtuple_arbitrary_type():
class CustomClass:
pass
class Tup(NamedTuple):
c: CustomClass
class Model(BaseModel):
x: Tup
class Config:
arbitrary_types_allowed = True
data = {'x': Tup(c=CustomClass())}
model = Model.parse_obj(data)
assert isinstance(model.x.c, CustomClass)
with pytest.raises(RuntimeError):
class ModelNoArbitraryTypes(BaseModel):
x: Tup
def test_typeddict():
class TD(TypedDict):
a: int