Runtime checking for extra keys in TypedDict

248 Views Asked by At

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_)
1

There are 1 best solutions below

0
Michael H On BEST ANSWER

My Answer

My Example

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'}]