This answer tells how to validated a TypedDict at runtime, but it won't catch the case of an extra key being present.
For example, this doesn't throw. How can I make it throw?
from typing import Any, TypeVar
from pydantic import TypeAdapter
from typing_extensions import TypedDict
T = TypeVar('T')
def runtime_check_typed_dict(TypedDictClass: type[T], object_: Any) -> T:
TypedDictValidator = TypeAdapter(TypedDictClass)
return TypedDictValidator.validate_python(object_, strict=True)
class MyThing(TypedDict):
key: str
obj_: Any = {'key': 'stuff', 'extra': 'this should throw!'}
runtime_check_typed_dict(MyThing, obj_)
You should set extra='forbid'
.
(Documentation) How to config typing_extensions.TypedDict
for pydantic
: https://docs.pydantic.dev/2.4/usage/strict_mode/#dataclasses-and-typeddict
Here's the example for both typing_extensions.TypedDict
and pydantic.BaseModel
.
from pprint import pprint
from typing import Any, TypeVar
from pydantic import BaseModel, ConfigDict, TypeAdapter, ValidationError
from typing_extensions import TypedDict
T = TypeVar('T')
def runtime_check_typed_dict(TypedDictClass: type[T], object_: Any) -> T:
TypedDictValidator = TypeAdapter(TypedDictClass)
return TypedDictValidator.validate_python(object_, strict=True)
class MyThing(TypedDict):
key: str
obj_ = {'key': 'stuff', 'extra': 'this should throw!'}
### 1: TypedDict
# https://docs.pydantic.dev/2.4/usage/strict_mode/#dataclasses-and-typeddict
MyThing.__pydantic_config__ = ConfigDict(extra='forbid')
try:
runtime_check_typed_dict(MyThing, obj_)
except ValidationError as exc:
pprint(exc.errors())
# > [{'input': 'this should throw!',
# > 'loc': ('extra',),
# > 'msg': 'Extra inputs are not permitted',
# > 'type': 'extra_forbidden',
# > 'url': 'https://errors.pydantic.dev/2.4/v/extra_forbidden'}]
### 2: BaseModel
class MyThing2(BaseModel):
model_config = ConfigDict(extra='forbid')
key: str
try:
runtime_check_typed_dict(MyThing2, obj_)
except ValidationError as exc:
pprint(exc.errors())
# >[{'input': 'this should throw!',
# > 'loc': ('extra',),
# > 'msg': 'Extra inputs are not permitted',
# > 'type': 'extra_forbidden',
# > 'url': 'https://errors.pydantic.dev/2.4/v/extra_forbidden'}]