From 20619ea9017be07c4467e64517ae0ea980712e7d Mon Sep 17 00:00:00 2001 From: David Montague Date: Fri, 19 Jul 2019 00:26:15 -0700 Subject: [PATCH] Add type name to ValidationError error message --- pydantic/dataclasses.py | 2 +- pydantic/error_wrappers.py | 8 ++++++-- pydantic/main.py | 10 +++++----- tests/test_error_wrappers.py | 6 +++--- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/pydantic/dataclasses.py b/pydantic/dataclasses.py index a0d9ebc..96f8dc8 100644 --- a/pydantic/dataclasses.py +++ b/pydantic/dataclasses.py @@ -44,7 +44,7 @@ def setattr_validate_assignment(self: 'DataclassType', name: str, value: Any) -> d.pop(name) value, error_ = self.__pydantic_model__.__fields__[name].validate(value, d, loc=name, cls=self.__class__) if error_: - raise ValidationError([error_]) + raise ValidationError([error_], self) object.__setattr__(self, name, value) diff --git a/pydantic/error_wrappers.py b/pydantic/error_wrappers.py index daf0e53..59de2c0 100644 --- a/pydantic/error_wrappers.py +++ b/pydantic/error_wrappers.py @@ -51,8 +51,9 @@ ErrorList = Union[Sequence[Any], ErrorWrapper] class ValidationError(ValueError): __slots__ = ('raw_errors',) - def __init__(self, errors: Sequence[ErrorList]) -> None: + def __init__(self, errors: Sequence[ErrorList], obj_or_type: Any) -> None: self.raw_errors = errors + self.obj_type: Type[Any] = obj_or_type if isinstance(obj_or_type, type) else type(obj_or_type) @lru_cache() def errors(self) -> List[Dict[str, Any]]: @@ -64,7 +65,10 @@ class ValidationError(ValueError): def __str__(self) -> str: errors = self.errors() no_errors = len(errors) - return f'{no_errors} validation error{"" if no_errors == 1 else "s"}\n{display_errors(errors)}' + return ( + f'{no_errors} validation error{"" if no_errors == 1 else "s"} for {self.obj_type.__name__}\n' + f'{display_errors(errors)}' + ) def display_errors(errors: List[Dict[str, Any]]) -> str: diff --git a/pydantic/main.py b/pydantic/main.py index 624ba2a..6f58333 100644 --- a/pydantic/main.py +++ b/pydantic/main.py @@ -293,7 +293,7 @@ class BaseModel(metaclass=MetaModel): elif self.__config__.validate_assignment: value_, error_ = self.fields[name].validate(value, self.dict(exclude={name}), loc=name) if error_: - raise ValidationError([error_]) + raise ValidationError([error_], self) else: self.__values__[name] = value_ self.__fields_set__.add(name) @@ -372,7 +372,7 @@ class BaseModel(metaclass=MetaModel): obj = dict(obj) except (TypeError, ValueError) as e: exc = TypeError(f'{cls.__name__} expected dict not {type(obj).__name__}') - raise ValidationError([ErrorWrapper(exc, loc='__obj__')]) from e + raise ValidationError([ErrorWrapper(exc, loc='__obj__')], cls) from e return cls(**obj) @classmethod @@ -390,7 +390,7 @@ class BaseModel(metaclass=MetaModel): b, proto=proto, content_type=content_type, encoding=encoding, allow_pickle=allow_pickle ) except (ValueError, TypeError, UnicodeDecodeError) as e: - raise ValidationError([ErrorWrapper(e, loc='__obj__')]) + raise ValidationError([ErrorWrapper(e, loc='__obj__')], cls) return cls.parse_obj(obj) @classmethod @@ -784,8 +784,8 @@ def validate_model( # noqa: C901 (ignore complexity) errors.append(ErrorWrapper(ExtraError(), loc=f, config=config)) if not raise_exc: - return values, fields_set, ValidationError(errors) if errors else None + return values, fields_set, ValidationError(errors, model) if errors else None if errors: - raise ValidationError(errors) + raise ValidationError(errors, model) return values, fields_set, None diff --git a/tests/test_error_wrappers.py b/tests/test_error_wrappers.py index 9092d03..1738c2e 100644 --- a/tests/test_error_wrappers.py +++ b/tests/test_error_wrappers.py @@ -135,7 +135,7 @@ from pydantic.error_wrappers import ValidationError, flatten_errors, get_exc_typ ( '__str__', """\ -11 validation errors +11 validation errors for Model a value is not a valid integer (type=type_error.integer) b -> x @@ -227,7 +227,7 @@ def test_single_error(): Model(x='x') expected = """\ -1 validation error +1 validation error for Model x value is not a valid integer (type=type_error.integer)""" assert str(exc_info.value) == expected @@ -239,7 +239,7 @@ x assert ( str(exc_info.value) == """\ -1 validation error +1 validation error for Model x field required (type=value_error.missing)""" )