pydantic: Unable to trace full error location when calling super().__init__() from custom model

Initial Checks

  • I confirm that I’m using Pydantic V2

Description

Im trying to reassign annotation of the field “g” to locate the exact field that causes ValidationError. But when i spot the final field, im only able to trace error back up to last init call.

Errors i get:

{ ‘input’: ‘654f’, ‘loc’: (‘g’, 0, ‘e’, ‘a’), < -------- no ‘h’ in location ‘msg’: ‘Input should be a valid integer, unable to parse string as an integer’, ‘type’: ‘int_parsing’, ‘url’: ‘https://errors.pydantic.dev/2.3/v/int_parsing’ }, { ‘input’: ‘tr’, ‘loc’: (‘g’, 0, ‘e’, ‘c’), ‘msg’: ‘Extra inputs are not permitted’, ‘type’: ‘extra_forbidden’, ‘url’: ‘https://errors.pydantic.dev/2.3/v/extra_forbidden’ }, { ‘input’: {}, ‘loc’: (‘g’, 0, ‘e’, ‘d’), ‘msg’: ‘Extra inputs are not permitted’, ‘type’: ‘extra_forbidden’, ‘url’: ‘https://errors.pydantic.dev/2.3/v/extra_forbidden’ }

Expected errors

{ ‘input’: ‘654f’, ‘loc’: (‘h’, ‘g’, 0, ‘e’, ‘a’), ‘msg’: ‘Input should be a valid integer, unable to parse string as an integer’, ‘type’: ‘int_parsing’, ‘url’: ‘https://errors.pydantic.dev/2.3/v/int_parsing’ }, { ‘input’: ‘tr’, ‘loc’: (‘h’, ‘g’, 0, ‘e’, ‘c’), ‘msg’: ‘Extra inputs are not permitted’, ‘type’: ‘extra_forbidden’, ‘url’: ‘https://errors.pydantic.dev/2.3/v/extra_forbidden’ }, { ‘input’: {}, ‘loc’: (‘h’, ‘g’, 0, ‘e’, ‘d’), ‘msg’: ‘Extra inputs are not permitted’, ‘type’: ‘extra_forbidden’, ‘url’: ‘https://errors.pydantic.dev/2.3/v/extra_forbidden’ }

Example Code

from pprint import pprint

from pydantic import BaseModel as BM, ConfigDict


class BaseModel(BM):
    model_config = ConfigDict(extra='forbid')


class A(BaseModel):
    a: int = 1
    b: str = "12345"


class B(BaseModel):
    c: int = 2
    d: str = "qwe"


class C(BaseModel):
    e: A


class D(BaseModel):
    f: C


class F(BaseModel):
    g: list[A | C]

    def __init__(self, *args, **kwargs):
        try:
            super().__init__(*args, **kwargs)
        except ValidationError:

            class _F(BaseModel):
                g: list[C]

            _F(*args, **kwargs)


class G(BaseModel):
    h: F


try:
    f = G(**{"h": {"g": [{"e": {"a": "654f", "c": "tr", "d": {}}}]}})
except Exception as e:
    pprint(e.errors())

Python, Pydantic & OS Version

pydantic version: 2.3.0
pydantic-core version: 2.6.3
pydantic-core build: profile=release pgo=false
install path: /[location]/lib/python3.11/site-packages/pydantic
python version: 3.11.4 (v3.11.4:d2340ef257, Jun  6 2023, 19:15:51) [Clang 13.0.0 (clang-1300.0.29.30)]
platform: macOS-13.5.2-arm64-arm-64bit
optional deps. installed: ['typing-extensions']

About this issue

  • Original URL
  • State: closed
  • Created 9 months ago
  • Comments: 16 (9 by maintainers)

Most upvoted comments

Thank you for reply @sydney-runkle! I will look closer into related issues, hopefully functional discriminators will be the key

Just checking, have you tried using @pydantic.model_validator as an alternative to overriding __init__? It can accomplish the same in most cases.

@alice-luc would you mind explaining what you are actually trying to do? We generally discourage trying to override BaseModel.__init__, it can lead to a lot of problems.