I'm using Pydantic and there's something that makes me curious, exceptions raised from Pydantic hides the line raising the exception.
For example with this code:
from typing import Any
from pydantic import BaseModel
from pydantic.error_wrappers import ErrorWrapper, ValidationError
from pydantic.utils import ROOT_KEY
class MyModel(BaseModel):
def __init__(self, **data: Any) -> None:
exc = TypeError(f"My TypeError")
raise ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], self.__class__)
super().__init__(**data)
class Foo(MyModel):
a: int
class Bar(BaseModel):
a: int
The exception raised from my custom model will print the line raising the exception:
Foo(a=42)
# Traceback (most recent call last):
# File "D:\_exc.py", line 23, in <module>
# Foo(a=42)
# File "D:\_exc.py", line 11, in __init__
# raise ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], self.__class__)
# pydantic.error_wrappers.ValidationError: 1 validation error for Foo
# __root__
# My TypeError (type=type_error)
But exceptions raised from Pydantic's default BaseModel
will hide the line raising the exception:
Bar(a="foo")
# Traceback (most recent call last):
# File "D:\_exc.py", line 25, in <module>
# Bar(a="foo")
# File "pydantic\main.py", line 331, in pydantic.main.BaseModel.__init__
# pydantic.error_wrappers.ValidationError: 1 validation error for Bar
# a
# value is not a valid integer (type=type_error.integer)
Bar.parse_obj(42)
# File "D:\_exc.py", line 42, in <module>
# Bar.parse_obj(42)
# File "pydantic\main.py", line 510, in pydantic.main.BaseModel.parse_obj
# pydantic.error_wrappers.ValidationError: 1 validation error for Bar
# __root__
# Bar expected dict not int (type=type_error)
Is this some kind of default behavior for external Python libraries? I tried to look through Pydantic's codebase, but it doesn't seem to do anything special when raising the exception.