diff --git a/src/errors/validation_exception.rs b/src/errors/validation_exception.rs index d41a10e65..c93dfbab1 100644 --- a/src/errors/validation_exception.rs +++ b/src/errors/validation_exception.rs @@ -18,7 +18,7 @@ use crate::errors::LocItem; use crate::get_pydantic_version; use crate::input::InputType; use crate::serializers::{DuckTypingSerMode, Extra, SerMode, SerializationState}; -use crate::tools::{safe_repr, SchemaDict}; +use crate::tools::{get_type_name, safe_repr, SchemaDict}; use super::line_error::ValLineError; use super::location::Location; @@ -572,7 +572,7 @@ impl PyLineError { let input_str = safe_repr(input_value); truncate_input_value!(output, &input_str.to_cow()); - if let Ok(type_) = input_value.get_type().qualname() { + if let Ok(type_) = get_type_name(input_value.get_type()) { write!(output, ", input_type={type_}")?; } } diff --git a/src/tools.rs b/src/tools.rs index 28c661d8f..0c444ff9e 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use pyo3::exceptions::PyKeyError; use pyo3::prelude::*; -use pyo3::types::{PyDict, PyString}; +use pyo3::types::{PyDict, PyString, PyType}; use pyo3::{ffi, intern, FromPyObject}; use jiter::{cached_py_string, pystring_fast_new, StringCacheMode}; @@ -114,6 +114,18 @@ impl std::fmt::Display for ReprOutput<'_> { } } +pub fn get_type_name(t: Bound<'_, PyType>) -> Result { + if let Ok(repr) = t.repr() { + let repr = repr.to_string(); + if repr.starts_with("(v: &Bound<'py, PyAny>) -> ReprOutput<'py> { if let Ok(s) = v.repr() { ReprOutput::Python(s) diff --git a/tests/emscripten_runner.js b/tests/emscripten_runner.js index 054a88380..6469fb199 100644 --- a/tests/emscripten_runner.js +++ b/tests/emscripten_runner.js @@ -83,9 +83,9 @@ async function main() { const pyodide = await loadPyodide(); const FS = pyodide.FS; setupStreams(FS, pyodide._module.TTY); - FS.mkdir('/test_dir'); - FS.mount(FS.filesystems.NODEFS, {root: path.join(root_dir, 'tests')}, '/test_dir'); - FS.chdir('/test_dir'); + FS.mkdir('/tests'); + FS.mount(FS.filesystems.NODEFS, {root: path.join(root_dir, 'tests')}, '/tests'); + FS.chdir('/tests'); await pyodide.loadPackage(['micropip', 'pytest', 'pytz']); // language=python errcode = await pyodide.runPythonAsync(` diff --git a/tests/test_errors.py b/tests/test_errors.py index daabf04c6..7fd5e276b 100644 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -730,7 +730,7 @@ def test_error_on_repr(pydantic_version): assert str(exc_info.value) == ( '1 validation error for int\n' ' Input should be a valid integer ' - '[type=int_type, input_value=, input_type=BadRepr]\n' + '[type=int_type, input_value=, input_type=tests.test_errors.BadRepr]\n' f' For further information visit https://errors.pydantic.dev/{pydantic_version}/v/int_type' ) assert exc_info.value.errors(include_url=False) == [ diff --git a/tests/validators/test_arguments.py b/tests/validators/test_arguments.py index 45ade32e6..048d66ced 100644 --- a/tests/validators/test_arguments.py +++ b/tests/validators/test_arguments.py @@ -1018,7 +1018,7 @@ def test_error_display(pydantic_version): '1 validation error for arguments\n' 'b\n' ' Missing required argument [type=missing_argument, ' - "input_value=ArgsKwargs((), {'a': 1}), input_type=ArgsKwargs]\n" + "input_value=ArgsKwargs((), {'a': 1}), input_type=pydantic_core._pydantic_core.ArgsKwargs]\n" f' For further information visit https://errors.pydantic.dev/{pydantic_version}/v/missing_argument' ) # insert_assert(exc_info.value.json(include_url=False)) diff --git a/tests/validators/test_decimal.py b/tests/validators/test_decimal.py index 931fe6377..a0e204c98 100644 --- a/tests/validators/test_decimal.py +++ b/tests/validators/test_decimal.py @@ -358,7 +358,9 @@ def test_non_finite_json_values(py_and_json: PyAndJson, input_value, allow_inf_n ( Decimal('nan'), False, - Err("Input should be a finite number [type=finite_number, input_value=Decimal('NaN'), input_type=Decimal]"), + Err( + "Input should be a finite number [type=finite_number, input_value=Decimal('NaN'), input_type=decimal.Decimal]" + ), ), ], ) @@ -379,21 +381,21 @@ def test_non_finite_decimal_values(strict, input_value, allow_inf_nan, expected) Decimal('+inf'), False, Err( - "Input should be a finite number [type=finite_number, input_value=Decimal('Infinity'), input_type=Decimal]" + "Input should be a finite number [type=finite_number, input_value=Decimal('Infinity'), input_type=decimal.Decimal]" ), ), ( Decimal('-inf'), True, Err( - "Input should be greater than 0 [type=greater_than, input_value=Decimal('-Infinity'), input_type=Decimal]" + "Input should be greater than 0 [type=greater_than, input_value=Decimal('-Infinity'), input_type=decimal.Decimal]" ), ), ( Decimal('-inf'), False, Err( - "Input should be a finite number [type=finite_number, input_value=Decimal('-Infinity'), input_type=Decimal]" + "Input should be a finite number [type=finite_number, input_value=Decimal('-Infinity'), input_type=decimal.Decimal]" ), ), ], diff --git a/tests/validators/test_int.py b/tests/validators/test_int.py index 5732fe181..044bb99f8 100644 --- a/tests/validators/test_int.py +++ b/tests/validators/test_int.py @@ -119,7 +119,7 @@ def test_int_py_and_json(py_and_json: PyAndJson, input_value, expected): Decimal('1.001'), Err( 'Input should be a valid integer, got a number with a fractional part ' - "[type=int_from_float, input_value=Decimal('1.001'), input_type=Decimal]" + "[type=int_from_float, input_value=Decimal('1.001'), input_type=decimal.Decimal]" ), id='decimal-remainder', ), @@ -166,7 +166,7 @@ def test_int(input_value, expected): Decimal('1.001'), Err( 'Input should be a valid integer, got a number with a fractional part ' - "[type=int_from_float, input_value=Decimal('1.001'), input_type=Decimal]" + "[type=int_from_float, input_value=Decimal('1.001'), input_type=decimal.Decimal]" ), id='decimal-remainder', ), diff --git a/tests/validators/test_string.py b/tests/validators/test_string.py index f4f5f3888..072d87355 100644 --- a/tests/validators/test_string.py +++ b/tests/validators/test_string.py @@ -50,7 +50,9 @@ def test_str(py_and_json: PyAndJson, input_value, expected): (123, Err('Input should be a valid string [type=string_type, input_value=123, input_type=int]')), ( Decimal('123'), - Err("Input should be a valid string [type=string_type, input_value=Decimal('123'), input_type=Decimal]"), + Err( + "Input should be a valid string [type=string_type, input_value=Decimal('123'), input_type=decimal.Decimal]" + ), ), ], )