Skip to content

Change JSON schema (and maybe config) default for extra for dataclasses and TypedDicts #10785

@samuelcolvin

Description

@samuelcolvin

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

Run the code below with:

# with pydantic 2.9.2
uv run --with devtools --with 'pydantic==2.9.2' additional_props.py
# with the 2.10 beta
uv run --with devtools --with 'pydantic==2.10.0b1' additional_props.py

You'll see that 'additionalProperties': False is included in 2.9.2, but missing with 2.10.0b1. I think this change comes from #10675.

Note: With both versions 'additionalProperties': False is omitted if you omit extra_behavior='forbid' in the core-schema, even though extra_behavior='forbid' is the default behaviour.

JSON Schema is clear that unless you set 'additionalProperties': False, additional properties are allowed:

By default any additional properties are allowed.

TypeDict's don't allow extra keys, and pydantic-core errors if you include additional keys (unless you set extra_behaviour=' allow').

So really we should set 'additionalProperties': False on TypedDict JSON Schema:

  • if extra_behavior='forbid' (including via config)
  • or, if extra_behaviour is not set, and will therefore default to forbid in the schema validator — note this is a change to previous behavior, but I think we could argue it's a bug fix

Note, we need to make sure the behaviour is right for dataclasses and pydantic models too:

  • dataclasses should have the same logic as TypedDict
  • BaseModel I think have a default of extra_behavior='allow' so the current behaviour is right

Example Code

from pydantic import __version__ as pydantic_version, ValidationError
from devtools import debug
from pydantic.json_schema import GenerateJsonSchema
from pydantic_core import SchemaValidator, core_schema, __version__ as pydantic_core_version


debug(pydantic_version, pydantic_core_version)

schema = core_schema.typed_dict_schema(
    {
        'a': core_schema.typed_dict_field(core_schema.int_schema()),
        'b': core_schema.typed_dict_field(core_schema.int_schema()),
    },
    extra_behavior='forbid',
)

json_schema = GenerateJsonSchema().generate(schema)
debug(json_schema)

v = SchemaValidator(schema)
try:
    v.validate_python({'a': 1, 'b': 2, 'c': 3})
except ValidationError as e:
    debug(e.errors())
else:
    raise RuntimeError('Expected a validation error')

Python, Pydantic & OS Version

2.9.2 vs 2.10.0b1

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug V2Bug related to Pydantic V2topic-pep728Related to PEP 728 support

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions