Skip to content

Commit

Permalink
feat: pass down config to created models
Browse files Browse the repository at this point in the history
  • Loading branch information
PrettyWood committed Jan 12, 2021
1 parent 63f4a1e commit ebfd440
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
16 changes: 15 additions & 1 deletion docs/examples/annotated_types_typed_dict.py
@@ -1,6 +1,6 @@
from typing import TypedDict

from pydantic import BaseModel, ValidationError
from pydantic import BaseModel, Extra, ValidationError


# `total=False` means keys are non-required
Expand All @@ -17,6 +17,9 @@ class User(TypedDict):
class Model(BaseModel):
u: User

class Config:
extra = Extra.forbid


print(Model(u={'identity': {'name': 'Smith', 'surname': 'John'}, 'age': '37'}))

Expand All @@ -29,3 +32,14 @@ class Model(BaseModel):
Model(u={'identity': {'name': ['Smith'], 'surname': 'John'}, 'age': '24'})
except ValidationError as e:
print(e)

try:
Model(
u={
'identity': {'name': 'Smith', 'surname': 'John'},
'age': '37',
'email': 'john.smith@me.com',
}
)
except ValidationError as e:
print(e)
6 changes: 3 additions & 3 deletions pydantic/validators.py
Expand Up @@ -568,7 +568,7 @@ def named_tuple_validator(values: Tuple[Any, ...]) -> NamedTupleT:
return named_tuple_validator


def make_typed_dict_validator(type_: Type['TypedDict']) -> Callable[[Any], Dict[str, Any]]:
def make_typed_dict_validator(type_: Type['TypedDict'], config: Type['BaseConfig']) -> Callable[[Any], Dict[str, Any]]:
from .main import create_model

field_definitions: Dict[str, Any]
Expand All @@ -593,7 +593,7 @@ def make_typed_dict_validator(type_: Type['TypedDict']) -> Callable[[Any], Dict[
field_name: (field_type, default_value) for field_name, field_type in type_.__annotations__.items()
}

TypedDictModel: Type['BaseModel'] = create_model('TypedDictModel', **field_definitions)
TypedDictModel: Type['BaseModel'] = create_model('TypedDictModel', __config__=config, **field_definitions)

def typed_dict_validator(values: 'TypedDict') -> Dict[str, Any]:
return TypedDictModel(**values).dict(exclude_unset=True)
Expand Down Expand Up @@ -696,7 +696,7 @@ def find_validators( # noqa: C901 (ignore complexity)
yield make_named_tuple_validator(type_)
return
if is_typed_dict_type(type_):
yield make_typed_dict_validator(type_)
yield make_typed_dict_validator(type_, config)
return

class_ = get_class(type_)
Expand Down
19 changes: 19 additions & 0 deletions tests/test_annotated_types.py
Expand Up @@ -154,3 +154,22 @@ class Model(BaseModel):
'type': 'value_error.missing',
}
]


@pytest.mark.skipif(not TypedDict, reason='typing_extensions not installed')
def test_typed_dict_extra():
class User(TypedDict):
name: str
age: int

class Model(BaseModel):
u: User

class Config:
extra = 'forbid'

with pytest.raises(ValidationError) as exc_info:
Model(u={'name': 'pika', 'age': 7, 'rank': 1})
assert exc_info.value.errors() == [
{'loc': ('u', 'rank'), 'msg': 'extra fields not permitted', 'type': 'value_error.extra'},
]

0 comments on commit ebfd440

Please sign in to comment.