From b9a45baf2807e8a03bcf6e76d8b650bf0c7a3345 Mon Sep 17 00:00:00 2001 From: Samuel Colvin Date: Sun, 21 Jan 2024 12:59:07 +0000 Subject: [PATCH 1/2] remove AsLocItem trait --- Cargo.toml | 1 + src/errors/line_error.rs | 7 +++-- src/errors/location.rs | 23 +++++++++------ src/errors/mod.rs | 2 +- src/input/input_abstract.rs | 4 +-- src/input/input_json.rs | 40 ++++++++++---------------- src/input/input_python.rs | 51 +++++++++++++++++----------------- src/input/input_string.rs | 14 +++++----- src/input/return_enums.rs | 4 +-- src/lookup_key.rs | 4 +-- src/validators/arguments.rs | 12 ++++---- src/validators/call.rs | 2 +- src/validators/dataclass.rs | 14 ++++------ src/validators/dict.rs | 16 ++++++----- src/validators/function.rs | 6 ++-- src/validators/model_fields.rs | 12 ++++---- src/validators/tuple.rs | 6 ++-- src/validators/typed_dict.rs | 12 ++++---- src/validators/union.rs | 6 ++-- src/validators/with_default.rs | 2 +- 20 files changed, 116 insertions(+), 122 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c26c91419..c840b85f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ num-bigint = "0.4.4" python3-dll-a = "0.2.7" uuid = "1.6.1" jiter = {version = "0.0.6", features = ["python"]} +#jiter = {path = "../jiter", features = ["python"]} [lib] name = "_pydantic_core" diff --git a/src/errors/line_error.rs b/src/errors/line_error.rs index f5fa11b70..2a48bfaf4 100644 --- a/src/errors/line_error.rs +++ b/src/errors/line_error.rs @@ -61,7 +61,8 @@ impl ValError { } /// helper function to call with_outer on line items if applicable - pub fn with_outer_location(self, loc_item: LocItem) -> Self { + pub fn with_outer_location(self, into_loc_item: impl Into) -> Self { + let loc_item = into_loc_item.into(); match self { Self::LineErrors(mut line_errors) => { for line_error in &mut line_errors { @@ -120,8 +121,8 @@ impl ValLineError { /// location is stored reversed so it's quicker to add "outer" items as that's what we always do /// hence `push` here instead of `insert` - pub fn with_outer_location(mut self, loc_item: LocItem) -> Self { - self.location.with_outer(loc_item); + pub fn with_outer_location(mut self, into_loc_item: impl Into) -> Self { + self.location.with_outer(into_loc_item.into()); self } diff --git a/src/errors/location.rs b/src/errors/location.rs index 8acc2a039..afa6971c1 100644 --- a/src/errors/location.rs +++ b/src/errors/location.rs @@ -1,5 +1,6 @@ use pyo3::exceptions::PyTypeError; use pyo3::once_cell::GILOnceCell; +use std::borrow::Cow; use std::fmt; use pyo3::prelude::*; @@ -34,24 +35,30 @@ impl fmt::Display for LocItem { } } -// TODO rename to ToLocItem -pub trait AsLocItem { - // TODO rename to to_loc_item - fn as_loc_item(&self) -> LocItem; -} - impl From for LocItem { fn from(s: String) -> Self { Self::S(s) } } +impl From<&String> for LocItem { + fn from(s: &String) -> Self { + Self::S(s.to_string()) + } +} + impl From<&str> for LocItem { fn from(s: &str) -> Self { Self::S(s.to_string()) } } +impl From> for LocItem { + fn from(s: Cow<'_, str>) -> Self { + Self::S(s.to_string()) + } +} + impl From for LocItem { fn from(i: i64) -> Self { Self::I(i) @@ -201,9 +208,9 @@ impl TryFrom> for Location { fn try_from(location: Option<&PyAny>) -> PyResult { if let Some(location) = location { let mut loc_vec: Vec = if let Ok(tuple) = location.downcast::() { - tuple.iter().map(AsLocItem::as_loc_item).collect() + tuple.iter().map(Into::into).collect() } else if let Ok(list) = location.downcast::() { - list.iter().map(AsLocItem::as_loc_item).collect() + list.iter().map(Into::into).collect() } else { return Err(PyTypeError::new_err( "Location must be a list or tuple of strings and ints", diff --git a/src/errors/mod.rs b/src/errors/mod.rs index 131e54177..de6650527 100644 --- a/src/errors/mod.rs +++ b/src/errors/mod.rs @@ -7,7 +7,7 @@ mod validation_exception; mod value_exception; pub use self::line_error::{AsErrorValue, InputValue, ValError, ValLineError, ValResult}; -pub use self::location::{AsLocItem, LocItem}; +pub use self::location::LocItem; pub use self::types::{list_all_errors, ErrorType, ErrorTypeDefaults, Number}; pub use self::validation_exception::ValidationError; pub use self::value_exception::{PydanticCustomError, PydanticKnownError, PydanticOmit, PydanticUseDefault}; diff --git a/src/input/input_abstract.rs b/src/input/input_abstract.rs index 8229677b6..6ce1479f6 100644 --- a/src/input/input_abstract.rs +++ b/src/input/input_abstract.rs @@ -4,7 +4,7 @@ use pyo3::exceptions::PyValueError; use pyo3::types::{PyDict, PyType}; use pyo3::{intern, prelude::*}; -use crate::errors::{AsLocItem, ErrorTypeDefaults, InputValue, ValError, ValResult}; +use crate::errors::{ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult}; use crate::tools::py_err; use crate::{PyMultiHostUrl, PyUrl}; @@ -46,7 +46,7 @@ impl TryFrom<&str> for InputType { /// the convention is to either implement: /// * `strict_*` & `lax_*` if they have different behavior /// * or, `validate_*` and `strict_*` to just call `validate_*` if the behavior for strict and lax is the same -pub trait Input<'a>: fmt::Debug + ToPyObject + AsLocItem + Sized { +pub trait Input<'a>: fmt::Debug + ToPyObject + Into + Sized { fn as_error_value(&self) -> InputValue; fn identity(&self) -> Option { diff --git a/src/input/input_json.rs b/src/input/input_json.rs index 195f9caba..cd4ac919c 100644 --- a/src/input/input_json.rs +++ b/src/input/input_json.rs @@ -6,7 +6,7 @@ use pyo3::types::{PyDict, PyString}; use speedate::MicrosecondsPrecisionOverflowBehavior; use strum::EnumMessage; -use crate::errors::{AsLocItem, ErrorType, ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult}; +use crate::errors::{ErrorType, ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult}; use crate::validators::decimal::create_decimal; use super::datetime::{ @@ -21,9 +21,9 @@ use super::{ }; /// This is required but since JSON object keys are always strings, I don't think it can be called -impl AsLocItem for JsonValue { - fn as_loc_item(&self) -> LocItem { - match self { +impl From<&JsonValue> for LocItem { + fn from(json_value: &JsonValue) -> Self { + match json_value { JsonValue::Int(i) => (*i).into(), JsonValue::Str(s) => s.as_str().into(), v => format!("{v:?}").into(), @@ -31,9 +31,9 @@ impl AsLocItem for JsonValue { } } -impl AsLocItem for &JsonValue { - fn as_loc_item(&self) -> LocItem { - AsLocItem::as_loc_item(*self) +impl From for LocItem { + fn from(json_value: JsonValue) -> Self { + (&json_value).into() } } @@ -84,13 +84,6 @@ impl<'a> Input<'a> for JsonValue { } } - fn exact_str(&'a self) -> ValResult> { - match self { - JsonValue::Str(s) => Ok(s.as_str().into()), - _ => Err(ValError::new(ErrorTypeDefaults::StringType, self)), - } - } - fn validate_str( &'a self, strict: bool, @@ -144,6 +137,13 @@ impl<'a> Input<'a> for JsonValue { } } + fn exact_str(&'a self) -> ValResult> { + match self { + JsonValue::Str(s) => Ok(s.as_str().into()), + _ => Err(ValError::new(ErrorTypeDefaults::StringType, self)), + } + } + fn validate_float(&'a self, strict: bool) -> ValResult>> { match self { JsonValue::Float(f) => Ok(ValidationMatch::exact(EitherFloat::F64(*f))), @@ -319,18 +319,6 @@ impl BorrowInput for &'_ JsonValue { } } -impl AsLocItem for String { - fn as_loc_item(&self) -> LocItem { - self.to_string().into() - } -} - -impl AsLocItem for &String { - fn as_loc_item(&self) -> LocItem { - AsLocItem::as_loc_item(*self) - } -} - /// Required for JSON Object keys so the string can behave like an Input impl<'a> Input<'a> for String { fn as_error_value(&self) -> InputValue { diff --git a/src/input/input_python.rs b/src/input/input_python.rs index 2eaaebe10..edd13728e 100644 --- a/src/input/input_python.rs +++ b/src/input/input_python.rs @@ -12,7 +12,7 @@ use pyo3::{intern, PyTypeInfo}; use speedate::MicrosecondsPrecisionOverflowBehavior; -use crate::errors::{AsLocItem, ErrorType, ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult}; +use crate::errors::{ErrorType, ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult}; use crate::tools::{extract_i64, safe_repr}; use crate::validators::decimal::{create_decimal, get_decimal_type}; use crate::validators::Exactness; @@ -92,21 +92,20 @@ macro_rules! extract_dict_items { }; } -impl AsLocItem for PyAny { - fn as_loc_item(&self) -> LocItem { - if let Ok(py_str) = self.downcast::() { +impl From<&PyAny> for LocItem { + fn from(py_any: &PyAny) -> Self { + if let Ok(py_str) = py_any.downcast::() { py_str.to_string_lossy().as_ref().into() - } else if let Some(key_int) = extract_i64(self) { + } else if let Some(key_int) = extract_i64(py_any) { key_int.into() } else { - safe_repr(self).to_string().into() + safe_repr(py_any).to_string().into() } } } - -impl AsLocItem for &'_ PyAny { - fn as_loc_item(&self) -> LocItem { - AsLocItem::as_loc_item(*self) +impl From for LocItem { + fn from(py_any: PyAny) -> Self { + (&py_any).into() } } @@ -244,22 +243,6 @@ impl<'a> Input<'a> for PyAny { Err(ValError::new(ErrorTypeDefaults::StringType, self)) } - fn exact_str(&'a self) -> ValResult> { - if let Ok(py_str) = ::try_from_exact(self) { - Ok(EitherString::Py(py_str)) - } else { - Err(ValError::new(ErrorTypeDefaults::IntType, self)) - } - } - - fn exact_int(&'a self) -> ValResult> { - if PyInt::is_exact_type_of(self) { - Ok(EitherInt::Py(self)) - } else { - Err(ValError::new(ErrorTypeDefaults::IntType, self)) - } - } - fn validate_bytes(&'a self, strict: bool) -> ValResult>> { if let Ok(py_bytes) = self.downcast_exact::() { return Ok(ValidationMatch::exact(py_bytes.into())); @@ -347,6 +330,22 @@ impl<'a> Input<'a> for PyAny { Err(ValError::new(ErrorTypeDefaults::IntType, self)) } + fn exact_int(&'a self) -> ValResult> { + if PyInt::is_exact_type_of(self) { + Ok(EitherInt::Py(self)) + } else { + Err(ValError::new(ErrorTypeDefaults::IntType, self)) + } + } + + fn exact_str(&'a self) -> ValResult> { + if let Ok(py_str) = ::try_from_exact(self) { + Ok(EitherString::Py(py_str)) + } else { + Err(ValError::new(ErrorTypeDefaults::IntType, self)) + } + } + fn validate_float(&'a self, strict: bool) -> ValResult>> { if let Ok(float) = self.downcast_exact::() { return Ok(ValidationMatch::exact(EitherFloat::Py(float))); diff --git a/src/input/input_string.rs b/src/input/input_string.rs index 0c2c9a8ca..cd5931b24 100644 --- a/src/input/input_string.rs +++ b/src/input/input_string.rs @@ -3,7 +3,7 @@ use pyo3::types::{PyDict, PyString}; use speedate::MicrosecondsPrecisionOverflowBehavior; -use crate::errors::{AsLocItem, ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult}; +use crate::errors::{ErrorTypeDefaults, InputValue, LocItem, ValError, ValResult}; use crate::input::py_string_str; use crate::tools::safe_repr; use crate::validators::decimal::create_decimal; @@ -17,7 +17,7 @@ use super::{ GenericIterator, GenericMapping, Input, ValidationMatch, }; -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum StringMapping<'py> { String(&'py PyString), Mapping(&'py PyDict), @@ -52,11 +52,11 @@ impl<'py> StringMapping<'py> { } } -impl AsLocItem for StringMapping<'_> { - fn as_loc_item(&self) -> LocItem { - match self { - Self::String(s) => s.to_string_lossy().as_ref().into(), - Self::Mapping(d) => safe_repr(d).to_string().into(), +impl From> for LocItem { + fn from(string_mapping: StringMapping<'_>) -> Self { + match string_mapping { + StringMapping::String(s) => s.to_string_lossy().as_ref().into(), + StringMapping::Mapping(d) => safe_repr(d).to_string().into(), } } } diff --git a/src/input/return_enums.rs b/src/input/return_enums.rs index 905b895f9..b323383b7 100644 --- a/src/input/return_enums.rs +++ b/src/input/return_enums.rs @@ -205,7 +205,7 @@ fn validate_iter_to_vec<'a, 's>( } Err(ValError::LineErrors(line_errors)) => { max_length_check.incr()?; - errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index.into()))); + errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index))); } Err(ValError::Omit) => (), Err(err) => return Err(err), @@ -284,7 +284,7 @@ fn validate_iter_to_set<'a, 's>( } } Err(ValError::LineErrors(line_errors)) => { - errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index.into()))); + errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index))); } Err(ValError::Omit) => (), Err(err) => return Err(err), diff --git a/src/lookup_key.rs b/src/lookup_key.rs index e4d2dcce7..3f26b4b15 100644 --- a/src/lookup_key.rs +++ b/src/lookup_key.rs @@ -366,11 +366,11 @@ impl LookupPath { pub fn apply_error_loc(&self, mut line_error: ValLineError, loc_by_alias: bool, field_name: &str) -> ValLineError { if loc_by_alias { for path_item in self.iter().rev() { - line_error = line_error.with_outer_location(path_item.clone().into()); + line_error = line_error.with_outer_location(path_item.clone()); } line_error } else { - line_error.with_outer_location(field_name.to_string().into()) + line_error.with_outer_location(field_name.to_string()) } } diff --git a/src/validators/arguments.rs b/src/validators/arguments.rs index a605ff999..661aaf1e4 100644 --- a/src/validators/arguments.rs +++ b/src/validators/arguments.rs @@ -6,7 +6,7 @@ use ahash::AHashSet; use crate::build_tools::py_schema_err; use crate::build_tools::{schema_or_config_same, ExtraBehavior}; -use crate::errors::{AsLocItem, ErrorTypeDefaults, ValError, ValLineError, ValResult}; +use crate::errors::{ErrorTypeDefaults, ValError, ValLineError, ValResult}; use crate::input::{GenericArguments, Input, ValidationMatch}; use crate::lookup_key::LookupKey; @@ -209,7 +209,7 @@ impl Validator for ArgumentsValidator { { Ok(value) => output_args.push(value), Err(ValError::LineErrors(line_errors)) => { - errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index.into()))); + errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index))); } Err(err) => return Err(err), } @@ -263,7 +263,7 @@ impl Validator for ArgumentsValidator { errors.extend( line_errors .into_iter() - .map(|err| err.with_outer_location((index + self.positional_params_count).into())), + .map(|err| err.with_outer_location(index + self.positional_params_count)), ); } Err(err) => return Err(err), @@ -289,7 +289,7 @@ impl Validator for ArgumentsValidator { Err(ValError::LineErrors(line_errors)) => { for err in line_errors { errors.push( - err.with_outer_location(raw_key.as_loc_item()) + err.with_outer_location(raw_key) .with_type(ErrorTypeDefaults::InvalidKey), ); } @@ -303,7 +303,7 @@ impl Validator for ArgumentsValidator { Ok(value) => output_kwargs.set_item(either_str.as_py_string(py), value)?, Err(ValError::LineErrors(line_errors)) => { for err in line_errors { - errors.push(err.with_outer_location(raw_key.as_loc_item())); + errors.push(err.with_outer_location(raw_key)); } } Err(err) => return Err(err), @@ -313,7 +313,7 @@ impl Validator for ArgumentsValidator { errors.push(ValLineError::new_with_loc( ErrorTypeDefaults::UnexpectedKeywordArgument, value, - raw_key.as_loc_item(), + raw_key, )); } } diff --git a/src/validators/call.rs b/src/validators/call.rs index bf80415af..32b76f582 100644 --- a/src/validators/call.rs +++ b/src/validators/call.rs @@ -93,7 +93,7 @@ impl Validator for CallValidator { if let Some(return_validator) = &self.return_validator { return_validator .validate(py, return_value.into_ref(py), state) - .map_err(|e| e.with_outer_location("return".into())) + .map_err(|e| e.with_outer_location("return")) } else { Ok(return_value.to_object(py)) } diff --git a/src/validators/dataclass.rs b/src/validators/dataclass.rs index 3161541f0..bfeac2115 100644 --- a/src/validators/dataclass.rs +++ b/src/validators/dataclass.rs @@ -7,7 +7,7 @@ use ahash::AHashSet; use crate::build_tools::py_schema_err; use crate::build_tools::{is_strict, schema_or_config_same, ExtraBehavior}; -use crate::errors::{AsLocItem, ErrorType, ErrorTypeDefaults, ValError, ValLineError, ValResult}; +use crate::errors::{ErrorType, ErrorTypeDefaults, ValError, ValLineError, ValResult}; use crate::input::InputType; use crate::input::{BorrowInput, GenericArguments, Input, ValidationMatch}; use crate::lookup_key::LookupKey; @@ -231,7 +231,7 @@ impl Validator for DataclassArgsValidator { errors.extend( line_errors .into_iter() - .map(|err| err.with_outer_location(index.into())), + .map(|err| err.with_outer_location(index)), ); } Err(err) => return Err(err), @@ -310,7 +310,7 @@ impl Validator for DataclassArgsValidator { ValLineError::new_with_loc( ErrorTypeDefaults::UnexpectedKeywordArgument, value, - raw_key.as_loc_item(), + raw_key, ), ); } @@ -322,9 +322,7 @@ impl Validator for DataclassArgsValidator { .set_item(either_str.as_py_string(py), value)?, Err(ValError::LineErrors(line_errors)) => { for err in line_errors { - errors.push(err.with_outer_location( - raw_key.as_loc_item(), - )); + errors.push(err.with_outer_location(raw_key)); } } Err(err) => return Err(err), @@ -339,7 +337,7 @@ impl Validator for DataclassArgsValidator { Err(ValError::LineErrors(line_errors)) => { for err in line_errors { errors.push( - err.with_outer_location(raw_key.as_loc_item()) + err.with_outer_location(raw_key) .with_type(ErrorTypeDefaults::InvalidKey), ); } @@ -430,7 +428,7 @@ impl Validator for DataclassArgsValidator { Err(ValError::LineErrors(line_errors)) => { let errors = line_errors .into_iter() - .map(|e| e.with_outer_location(field_name.into())) + .map(|e| e.with_outer_location(field_name)) .collect(); Err(ValError::LineErrors(errors)) } diff --git a/src/validators/dict.rs b/src/validators/dict.rs index d6507e8e9..3f8ff820b 100644 --- a/src/validators/dict.rs +++ b/src/validators/dict.rs @@ -3,7 +3,7 @@ use pyo3::prelude::*; use pyo3::types::PyDict; use crate::build_tools::is_strict; -use crate::errors::{AsLocItem, ValError, ValLineError, ValResult}; +use crate::errors::{LocItem, ValError, ValLineError, ValResult}; use crate::input::BorrowInput; use crate::input::{ DictGenericIterator, GenericMapping, Input, JsonObjectGenericIterator, MappingGenericIterator, @@ -103,7 +103,12 @@ impl DictValidator { &'s self, py: Python<'data>, input: &'data impl Input<'data>, - mapping_iter: impl Iterator>, + mapping_iter: impl Iterator< + Item = ValResult<( + impl BorrowInput + Clone + Into + 'data, + impl BorrowInput + 'data, + )>, + >, state: &mut ValidationState, ) -> ValResult { let output = PyDict::new(py); @@ -118,10 +123,7 @@ impl DictValidator { Err(ValError::LineErrors(line_errors)) => { for err in line_errors { // these are added in reverse order so [key] is shunted along by the second call - errors.push( - err.with_outer_location("[key]".into()) - .with_outer_location(key.as_loc_item()), - ); + errors.push(err.with_outer_location("[key]").with_outer_location(key.clone())); } None } @@ -132,7 +134,7 @@ impl DictValidator { Ok(value) => Some(value), Err(ValError::LineErrors(line_errors)) => { for err in line_errors { - errors.push(err.with_outer_location(key.as_loc_item())); + errors.push(err.with_outer_location(key.clone())); } None } diff --git a/src/validators/function.rs b/src/validators/function.rs index e7134ab29..34e0b6327 100644 --- a/src/validators/function.rs +++ b/src/validators/function.rs @@ -6,7 +6,7 @@ use pyo3::types::{PyAny, PyDict, PyString}; use pyo3::{intern, PyTraverseError, PyVisit}; use crate::errors::{ - AsLocItem, ErrorType, PydanticCustomError, PydanticKnownError, PydanticOmit, ValError, ValResult, ValidationError, + ErrorType, PydanticCustomError, PydanticKnownError, PydanticOmit, ValError, ValResult, ValidationError, }; use crate::input::Input; use crate::py_gc::PyGcTraverse; @@ -371,7 +371,7 @@ struct ValidatorCallable { #[pymethods] impl ValidatorCallable { fn __call__(&mut self, py: Python, input_value: &PyAny, outer_location: Option<&PyAny>) -> PyResult { - let outer_location = outer_location.map(AsLocItem::as_loc_item); + let outer_location = outer_location.map(Into::into); self.validator.validate(py, input_value, outer_location) } @@ -399,7 +399,7 @@ struct AssignmentValidatorCallable { #[pymethods] impl AssignmentValidatorCallable { fn __call__(&mut self, py: Python, input_value: &PyAny, outer_location: Option<&PyAny>) -> PyResult { - let outer_location = outer_location.map(AsLocItem::as_loc_item); + let outer_location = outer_location.map(Into::into); self.validator.validate_assignment( py, input_value, diff --git a/src/validators/model_fields.rs b/src/validators/model_fields.rs index c73a2821d..192d1ba8f 100644 --- a/src/validators/model_fields.rs +++ b/src/validators/model_fields.rs @@ -7,7 +7,7 @@ use ahash::AHashSet; use crate::build_tools::py_schema_err; use crate::build_tools::{is_strict, schema_or_config_same, ExtraBehavior}; -use crate::errors::{AsLocItem, ErrorType, ErrorTypeDefaults, ValError, ValLineError, ValResult}; +use crate::errors::{ErrorType, ErrorTypeDefaults, ValError, ValLineError, ValResult}; use crate::input::{ AttributesGenericIterator, BorrowInput, DictGenericIterator, GenericMapping, Input, JsonObjectGenericIterator, MappingGenericIterator, StringMappingGenericIterator, ValidationMatch, @@ -183,7 +183,7 @@ impl Validator for ModelFieldsValidator { Ok(v) => v, Err(ValError::LineErrors(line_errors)) => { for err in line_errors { - errors.push(err.with_outer_location(field.name.as_loc_item())); + errors.push(err.with_outer_location(&field.name)); } continue; } @@ -256,7 +256,7 @@ impl Validator for ModelFieldsValidator { Err(ValError::LineErrors(line_errors)) => { for err in line_errors { errors.push( - err.with_outer_location(raw_key.as_loc_item()) + err.with_outer_location(raw_key.clone()) .with_type(ErrorTypeDefaults::InvalidKey) ); @@ -278,7 +278,7 @@ impl Validator for ModelFieldsValidator { ValLineError::new_with_loc( ErrorTypeDefaults::ExtraForbidden, value, - raw_key.as_loc_item(), + raw_key, ) ); @@ -294,7 +294,7 @@ impl Validator for ModelFieldsValidator { } Err(ValError::LineErrors(line_errors)) => { for err in line_errors { - errors.push(err.with_outer_location(raw_key.as_loc_item())); + errors.push(err.with_outer_location(raw_key.clone())); } } Err(err) => return Err(err), @@ -355,7 +355,7 @@ impl Validator for ModelFieldsValidator { Err(ValError::LineErrors(line_errors)) => { let errors = line_errors .into_iter() - .map(|e| e.with_outer_location(field_name.to_string().into())) + .map(|e| e.with_outer_location(field_name)) .collect(); Err(ValError::LineErrors(errors)) } diff --git a/src/validators/tuple.rs b/src/validators/tuple.rs index db9c57953..6cad26073 100644 --- a/src/validators/tuple.rs +++ b/src/validators/tuple.rs @@ -76,7 +76,7 @@ impl TupleValidator { Some((index, input_item)) => match validator.validate(py, input_item, state) { Ok(item) => self.push_output_item(input, output, item, actual_length)?, Err(ValError::LineErrors(line_errors)) => { - errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index.into()))); + errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index))); } Err(ValError::Omit) => (), Err(err) => return Err(err), @@ -136,7 +136,7 @@ impl TupleValidator { match variable_validator.validate(py, input_item, state) { Ok(item) => self.push_output_item(input, &mut output, item, actual_length)?, Err(ValError::LineErrors(line_errors)) => { - errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index.into()))); + errors.extend(line_errors.into_iter().map(|err| err.with_outer_location(index))); } Err(ValError::Omit) => (), Err(err) => return Err(err), @@ -167,7 +167,7 @@ impl TupleValidator { errors.extend( line_errors .into_iter() - .map(|err| err.with_outer_location(buffer_item_index.into())), + .map(|err| err.with_outer_location(buffer_item_index)), ); } Err(ValError::Omit) => (), diff --git a/src/validators/typed_dict.rs b/src/validators/typed_dict.rs index d2fc00ec7..ec0cc07cf 100644 --- a/src/validators/typed_dict.rs +++ b/src/validators/typed_dict.rs @@ -8,7 +8,7 @@ use ahash::AHashSet; use crate::build_tools::py_schema_err; use crate::build_tools::{is_strict, schema_or_config, schema_or_config_same, ExtraBehavior}; -use crate::errors::{AsLocItem, ErrorTypeDefaults, ValError, ValLineError, ValResult}; +use crate::errors::{ErrorTypeDefaults, ValError, ValLineError, ValResult}; use crate::input::{ AttributesGenericIterator, BorrowInput, DictGenericIterator, GenericMapping, Input, JsonObjectGenericIterator, MappingGenericIterator, StringMappingGenericIterator, ValidationMatch, @@ -183,7 +183,7 @@ impl Validator for TypedDictValidator { Ok(v) => v, Err(ValError::LineErrors(line_errors)) => { for err in line_errors { - errors.push(err.with_outer_location(field.name.as_loc_item())); + errors.push(err.with_outer_location(&field.name)); } continue; } @@ -256,7 +256,7 @@ impl Validator for TypedDictValidator { Err(ValError::LineErrors(line_errors)) => { for err in line_errors { errors.push( - err.with_outer_location(raw_key.as_loc_item()) + err.with_outer_location(raw_key.clone()) .with_type(ErrorTypeDefaults::InvalidKey) ); @@ -278,7 +278,7 @@ impl Validator for TypedDictValidator { ValLineError::new_with_loc( ErrorTypeDefaults::ExtraForbidden, value, - raw_key.as_loc_item(), + raw_key, ) ); @@ -294,9 +294,7 @@ impl Validator for TypedDictValidator { Err(ValError::LineErrors(line_errors)) => { for err in line_errors { errors.push( - err - .with_outer_location(raw_key.as_loc_item()) - + err.with_outer_location(raw_key.clone()) ); } } diff --git a/src/validators/union.rs b/src/validators/union.rs index e010348af..0a5bd0c65 100644 --- a/src/validators/union.rs +++ b/src/validators/union.rs @@ -8,7 +8,7 @@ use smallvec::SmallVec; use crate::build_tools::py_schema_err; use crate::build_tools::{is_strict, schema_or_config}; -use crate::errors::{AsLocItem, ErrorType, ValError, ValLineError, ValResult}; +use crate::errors::{ErrorType, ValError, ValLineError, ValResult}; use crate::input::{GenericMapping, Input}; use crate::lookup_key::LookupKey; use crate::py_gc::PyGcTraverse; @@ -263,7 +263,7 @@ impl<'a> MaybeErrors<'a> { }| { line_errors.into_iter().map(move |err| { let case_label = label.unwrap_or(choice.get_name()); - err.with_outer_location(case_label.into()) + err.with_outer_location(case_label) }) }, ) @@ -486,7 +486,7 @@ impl TaggedUnionValidator { if let Ok(Some((tag, validator))) = self.lookup.validate(py, tag) { return match validator.validate(py, input, state) { Ok(res) => Ok(res), - Err(err) => Err(err.with_outer_location(tag.as_loc_item())), + Err(err) => Err(err.with_outer_location(tag)), }; } match self.custom_error { diff --git a/src/validators/with_default.rs b/src/validators/with_default.rs index a17c2cefc..f520eaf38 100644 --- a/src/validators/with_default.rs +++ b/src/validators/with_default.rs @@ -170,7 +170,7 @@ impl Validator for WithDefaultValidator { Ok(v) => Ok(Some(v)), Err(e) => { if let Some(outer_loc) = outer_loc { - Err(e.with_outer_location(outer_loc.into())) + Err(e.with_outer_location(outer_loc)) } else { Err(e) } From a36d615643e141e677beb8a0d61f8c3d3c5c4209 Mon Sep 17 00:00:00 2001 From: Samuel Colvin Date: Sun, 21 Jan 2024 13:07:04 +0000 Subject: [PATCH 2/2] cleanup --- Cargo.toml | 1 - src/errors/location.rs | 9 +-------- src/input/input_python.rs | 1 + src/lookup_key.rs | 2 +- 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c840b85f2..c26c91419 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,6 @@ num-bigint = "0.4.4" python3-dll-a = "0.2.7" uuid = "1.6.1" jiter = {version = "0.0.6", features = ["python"]} -#jiter = {path = "../jiter", features = ["python"]} [lib] name = "_pydantic_core" diff --git a/src/errors/location.rs b/src/errors/location.rs index afa6971c1..55bab0017 100644 --- a/src/errors/location.rs +++ b/src/errors/location.rs @@ -1,6 +1,5 @@ use pyo3::exceptions::PyTypeError; use pyo3::once_cell::GILOnceCell; -use std::borrow::Cow; use std::fmt; use pyo3::prelude::*; @@ -43,7 +42,7 @@ impl From for LocItem { impl From<&String> for LocItem { fn from(s: &String) -> Self { - Self::S(s.to_string()) + s.to_string().into() } } @@ -53,12 +52,6 @@ impl From<&str> for LocItem { } } -impl From> for LocItem { - fn from(s: Cow<'_, str>) -> Self { - Self::S(s.to_string()) - } -} - impl From for LocItem { fn from(i: i64) -> Self { Self::I(i) diff --git a/src/input/input_python.rs b/src/input/input_python.rs index edd13728e..fd93820ef 100644 --- a/src/input/input_python.rs +++ b/src/input/input_python.rs @@ -103,6 +103,7 @@ impl From<&PyAny> for LocItem { } } } + impl From for LocItem { fn from(py_any: PyAny) -> Self { (&py_any).into() diff --git a/src/lookup_key.rs b/src/lookup_key.rs index 3f26b4b15..d4fba403f 100644 --- a/src/lookup_key.rs +++ b/src/lookup_key.rs @@ -370,7 +370,7 @@ impl LookupPath { } line_error } else { - line_error.with_outer_location(field_name.to_string()) + line_error.with_outer_location(field_name) } }