Initial Checks
Description
When validating a discriminated Union of a "type statement", the errors are far worse than when not using a "type statement", making it very difficult to understand why the value failed validation.
It seems like pydantic is duplicating/nesting the type, since the (undesirable) output contains "tagged-union[union[A,B],union[A,B]]", rather than "tagged-union[A,B]" (as found in the output when not using a type statement). Additionally, we see A.A.extra_field instead of A.extra_field.
Possibly related to #6352.
Example Code
from typing import Annotated, Literal
import pydantic
class _Base(pydantic.BaseModel):
model_config = pydantic.ConfigDict(extra="forbid")
class A(_Base):
type: Literal["A"] = "A"
val: int
class B(_Base):
type: Literal["B"] = "B"
val: str
type _U = A | B
U = Annotated[_U, pydantic.Field(discriminator="type")]
U_ADAPTER = pydantic.TypeAdapter[U](U)
U_ADAPTER.validate_python({"type": "A", "val": 1, "extra_field": "oops!"})
Output:
Traceback (most recent call last):
File "<REDACTED_PATH>/pydantic_playground.py", line 23, in <module>
U_ADAPTER.validate_python({"type": "A", "val": 1, "extra_field": "oops!"})
File "<REDACTED_PATH>/.venv/lib/python3.12/site-packages/pydantic/type_adapter.py", line 144, in wrapped
return func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<REDACTED_PATH>/.venv/lib/python3.12/site-packages/pydantic/type_adapter.py", line 375, in validate_python
return self.validator.validate_python(object, strict=strict, from_attributes=from_attributes, context=context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 4 validation errors for tagged-union[union[A,B],union[A,B]]
A.A.extra_field
Extra inputs are not permitted [type=extra_forbidden, input_value='oops!', input_type=str]
For further information visit https://errors.pydantic.dev/2.9/v/extra_forbidden
A.B.type
Input should be 'B' [type=literal_error, input_value='A', input_type=str]
For further information visit https://errors.pydantic.dev/2.9/v/literal_error
A.B.val
Input should be a valid string [type=string_type, input_value=1, input_type=int]
For further information visit https://errors.pydantic.dev/2.9/v/string_type
A.B.extra_field
Extra inputs are not permitted [type=extra_forbidden, input_value='oops!', input_type=str]
For further information visit https://errors.pydantic.dev/2.9/v/extra_forbid
Replacing type _U = A | B with _U = A | B, the error is much improved:
Traceback (most recent call last):
File "<REDACTED_PATH>/pydantic_playground.py", line 21, in <module>
U_ADAPTER.validate_python({"type": "A", "val": 1, "extra_field": "oops!"})
File "<REDACTED_PATH>/.venv/lib/python3.12/site-packages/pydantic/type_adapter.py", line 144, in wrapped
return func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<REDACTED_PATH>/.venv/lib/python3.12/site-packages/pydantic/type_adapter.py", line 375, in validate_python
return self.validator.validate_python(object, strict=strict, from_attributes=from_attributes, context=context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 1 validation error for tagged-union[A,B]
A.extra_field
Extra inputs are not permitted [type=extra_forbidden, input_value='oops!', input_type=str]
For further information visit https://errors.pydantic.dev/2.9/v/extra_forbidden
Python, Pydantic & OS Version
pydantic version: 2.9.0
pydantic-core version: 2.23.2
pydantic-core build: profile=release pgo=false
install path: <REDACTED_PATH>/.venv/lib/python3.12/site-packages/pydantic
python version: 3.12.7 (main, Oct 2 2024, 16:35:10) [Clang 18.1.8 ]
platform: Linux-5.4.0-131-generic-x86_64-with-glibc2.31
related packages: fastapi-0.115.2 mypy-1.13.0 typing_extensions-4.12.2
commit: unknown
Initial Checks
Description
When validating a discriminated Union of a "type statement", the errors are far worse than when not using a "type statement", making it very difficult to understand why the value failed validation.
It seems like
pydanticis duplicating/nesting thetype, since the (undesirable) output contains "tagged-union[union[A,B],union[A,B]]", rather than "tagged-union[A,B]" (as found in the output when not using a type statement). Additionally, we seeA.A.extra_fieldinstead ofA.extra_field.Possibly related to #6352.
Example Code
Output:
Replacing
type _U = A | Bwith_U = A | B, the error is much improved:Python, Pydantic & OS Version