diff --git a/generate_self_schema.py b/generate_self_schema.py index 67808b536..bcc011dbb 100644 --- a/generate_self_schema.py +++ b/generate_self_schema.py @@ -197,26 +197,9 @@ def main() -> None: assert m, f'Unknown schema type: {type_}' key = m.group(1) value = get_schema(s) - if key == 'function': - mode = value['fields']['mode']['schema']['expected'] - if mode == ['plain']: - key = 'function-plain' - elif mode == ['wrap']: - key = 'function-wrap' - elif key == 'tuple': - if value['fields']['mode']['schema']['expected'] == ['positional']: - key = 'tuple-positional' - else: - key = 'tuple-variable' - choices[key] = value - schema = { - 'type': 'tagged-union', - 'ref': 'root-schema', - 'discriminator': 'self-schema-discriminator', - 'choices': choices, - } + schema = {'type': 'tagged-union', 'ref': 'root-schema', 'discriminator': 'type', 'choices': choices} python_code = ( f'# this file is auto-generated by generate_self_schema.py, DO NOT edit manually\nself_schema = {schema}\n' ) diff --git a/pydantic_core/core_schema.py b/pydantic_core/core_schema.py index e0df380cb..cdd135fd3 100644 --- a/pydantic_core/core_schema.py +++ b/pydantic_core/core_schema.py @@ -1139,8 +1139,7 @@ def list_schema( class TuplePositionalSchema(TypedDict, total=False): - type: Required[Literal['tuple']] - mode: Required[Literal['positional']] + type: Required[Literal['tuple-positional']] items_schema: Required[List[CoreSchema]] extra_schema: CoreSchema strict: bool @@ -1179,8 +1178,7 @@ def tuple_positional_schema( serialization: Custom serialization schema """ return dict_not_none( - type='tuple', - mode='positional', + type='tuple-positional', items_schema=list(items_schema), extra_schema=extra_schema, strict=strict, @@ -1191,8 +1189,7 @@ def tuple_positional_schema( class TupleVariableSchema(TypedDict, total=False): - type: Required[Literal['tuple']] - mode: Literal['variable'] + type: Required[Literal['tuple-variable']] items_schema: CoreSchema min_length: int max_length: int @@ -1232,8 +1229,7 @@ def tuple_variable_schema( serialization: Custom serialization schema """ return dict_not_none( - type='tuple', - mode='variable', + type='tuple-variable', items_schema=items_schema, min_length=min_length, max_length=max_length, @@ -1509,16 +1505,18 @@ class GeneralValidatorFunctionSchema(TypedDict): function: GeneralValidatorFunction -class FunctionSchema(TypedDict, total=False): - type: Required[Literal['function']] +class _FunctionSchema(TypedDict, total=False): function: Required[Union[FieldValidatorFunctionSchema, GeneralValidatorFunctionSchema]] - mode: Required[Literal['before', 'after']] schema: Required[CoreSchema] ref: str metadata: Any serialization: SerSchema +class FunctionBeforeSchema(_FunctionSchema, total=False): + type: Required[Literal['function-before']] + + def field_before_validation_function( function: FieldValidatorFunction, schema: CoreSchema, @@ -1526,7 +1524,7 @@ def field_before_validation_function( ref: str | None = None, metadata: Any = None, serialization: SerSchema | None = None, -) -> FunctionSchema: +) -> FunctionBeforeSchema: """ Returns a schema that calls a validator function before validating the provided **model field** schema, e.g.: @@ -1556,8 +1554,7 @@ def fn(v: bytes, info: core_schema.ModelFieldValidationInfo) -> str: serialization: Custom serialization schema """ return dict_not_none( - type='function', - mode='before', + type='function-before', function={'type': 'field', 'function': function}, schema=schema, ref=ref, @@ -1573,7 +1570,7 @@ def general_before_validation_function( ref: str | None = None, metadata: Any = None, serialization: SerSchema | None = None, -) -> FunctionSchema: +) -> FunctionBeforeSchema: """ Returns a schema that calls a validator function before validating the provided schema, e.g.: @@ -1599,8 +1596,7 @@ def fn(v: Any, info: core_schema.ValidationInfo) -> str: serialization: Custom serialization schema """ return dict_not_none( - type='function', - mode='before', + type='function-before', function={'type': 'general', 'function': function}, schema=schema, ref=ref, @@ -1609,6 +1605,10 @@ def fn(v: Any, info: core_schema.ValidationInfo) -> str: ) +class FunctionAfterSchema(_FunctionSchema, total=False): + type: Required[Literal['function-after']] + + def field_after_validation_function( function: FieldValidatorFunction, schema: CoreSchema, @@ -1616,7 +1616,7 @@ def field_after_validation_function( ref: str | None = None, metadata: Any = None, serialization: SerSchema | None = None, -) -> FunctionSchema: +) -> FunctionAfterSchema: """ Returns a schema that calls a validator function after validating the provided **model field** schema, e.g.: @@ -1646,8 +1646,7 @@ def fn(v: str, info: core_schema.ModelFieldValidationInfo) -> str: serialization: Custom serialization schema """ return dict_not_none( - type='function', - mode='after', + type='function-after', function={'type': 'field', 'function': function}, schema=schema, ref=ref, @@ -1663,7 +1662,7 @@ def general_after_validation_function( ref: str | None = None, metadata: Any = None, serialization: SerSchema | None = None, -) -> FunctionSchema: +) -> FunctionAfterSchema: """ Returns a schema that calls a validator function after validating the provided schema, e.g.: @@ -1687,8 +1686,7 @@ def fn(v: str, info: core_schema.ValidationInfo) -> str: serialization: Custom serialization schema """ return dict_not_none( - type='function', - mode='after', + type='function-after', function={'type': 'general', 'function': function}, schema=schema, ref=ref, @@ -1727,9 +1725,8 @@ class GeneralWrapValidatorFunctionSchema(TypedDict): class WrapFunctionSchema(TypedDict, total=False): - type: Required[Literal['function']] + type: Required[Literal['function-wrap']] function: Required[Union[GeneralWrapValidatorFunctionSchema, FieldWrapValidatorFunctionSchema]] - mode: Required[Literal['wrap']] schema: Required[CoreSchema] ref: str metadata: Any @@ -1768,8 +1765,7 @@ def fn(v: str, validator: core_schema.CallableValidator, info: core_schema.Valid serialization: Custom serialization schema """ return dict_not_none( - type='function', - mode='wrap', + type='function-wrap', function={'type': 'general', 'function': function}, schema=schema, ref=ref, @@ -1817,8 +1813,7 @@ def fn(v: bytes, validator: core_schema.CallableValidator, info: core_schema.Mod serialization: Custom serialization schema """ return dict_not_none( - type='function', - mode='wrap', + type='function-wrap', function={'type': 'field', 'function': function}, schema=schema, ref=ref, @@ -1828,8 +1823,7 @@ def fn(v: bytes, validator: core_schema.CallableValidator, info: core_schema.Mod class PlainFunctionSchema(TypedDict, total=False): - type: Required[Literal['function']] - mode: Required[Literal['plain']] + type: Required[Literal['function-plain']] function: Required[Union[FieldValidatorFunctionSchema, GeneralValidatorFunctionSchema]] ref: str metadata: Any @@ -1865,8 +1859,7 @@ def fn(v: str, info: core_schema.ValidationInfo) -> str: serialization: Custom serialization schema """ return dict_not_none( - type='function', - mode='plain', + type='function-plain', function={'type': 'general', 'function': function}, ref=ref, metadata=metadata, @@ -1909,8 +1902,7 @@ def fn(v: Any, info: core_schema.ModelFieldValidationInfo) -> str: serialization: Custom serialization schema """ return dict_not_none( - type='function', - mode='plain', + type='function-plain', function={'type': 'field', 'function': function}, ref=ref, metadata=metadata, @@ -3068,7 +3060,8 @@ def definition_reference_schema( FrozenSetSchema, GeneratorSchema, DictSchema, - FunctionSchema, + FunctionAfterSchema, + FunctionBeforeSchema, WrapFunctionSchema, PlainFunctionSchema, WithDefaultSchema, @@ -3109,12 +3102,16 @@ def definition_reference_schema( 'is-subclass', 'callable', 'list', - 'tuple', + 'tuple-positional', + 'tuple-variable', 'set', 'frozenset', 'generator', 'dict', - 'function', + 'function-after', + 'function-before', + 'function-wrap', + 'function-plain', 'default', 'nullable', 'union', diff --git a/src/serializers/shared.rs b/src/serializers/shared.rs index 1648a678a..d2f6b4b12 100644 --- a/src/serializers/shared.rs +++ b/src/serializers/shared.rs @@ -78,18 +78,12 @@ combined_serializer! { // hence they're here. Function: super::type_serializers::function::FunctionPlainSerializer; FunctionWrap: super::type_serializers::function::FunctionWrapSerializer; - // `TuplePositionalSerializer` & `TupleVariableSerializer` are created by - // `TupleBuilder` based on the `mode` parameter. - TuplePositional: super::type_serializers::tuple::TuplePositionalSerializer; - TupleVariable: super::type_serializers::tuple::TupleVariableSerializer; } // `find_only` is for type_serializers which are built directly via the `type` key and `find_serializer` // but aren't actually used for serialization, e.g. their `build` method must return another serializer find_only: { - super::type_serializers::tuple::TupleBuilder; super::type_serializers::union::TaggedUnionBuilder; super::type_serializers::other::ChainBuilder; - super::type_serializers::other::FunctionBuilder; super::type_serializers::other::CustomErrorBuilder; super::type_serializers::other::CallBuilder; super::type_serializers::other::LaxOrStrictBuilder; @@ -100,6 +94,10 @@ combined_serializer! { super::type_serializers::definitions::DefinitionsBuilder; super::type_serializers::dataclass::DataclassArgsBuilder; super::type_serializers::dataclass::DataclassBuilder; + super::type_serializers::function::FunctionBeforeSerializerBuilder; + super::type_serializers::function::FunctionAfterSerializerBuilder; + super::type_serializers::function::FunctionPlainSerializerBuilder; + super::type_serializers::function::FunctionWrapSerializerBuilder; } // `both` means the struct is added to both the `CombinedSerializer` enum and the match statement in // `find_serializer` so they can be used via a `type` str. @@ -132,6 +130,8 @@ combined_serializer! { Union: super::type_serializers::union::UnionSerializer; Literal: super::type_serializers::literal::LiteralSerializer; Recursive: super::type_serializers::definitions::DefinitionRefSerializer; + TuplePositional: super::type_serializers::tuple::TuplePositionalSerializer; + TupleVariable: super::type_serializers::tuple::TupleVariableSerializer; } } @@ -150,11 +150,15 @@ impl CombinedSerializer { Some("function-plain") => { // `function` is a special case, not included in `find_serializer` since it means something // different in `schema.type` - return super::type_serializers::function::FunctionPlainSerializer::new_combined(ser_schema) - .map_err(|err| py_error_type!("Error building `function-plain` serializer:\n {}", err)); + return super::type_serializers::function::FunctionPlainSerializer::build( + ser_schema, + config, + build_context, + ) + .map_err(|err| py_error_type!("Error building `function-plain` serializer:\n {}", err)); } Some("function-wrap") => { - return super::type_serializers::function::FunctionWrapSerializer::new_combined( + return super::type_serializers::function::FunctionWrapSerializer::build( ser_schema, config, build_context, diff --git a/src/serializers/type_serializers/function.rs b/src/serializers/type_serializers/function.rs index bb58f909c..1ca21c69e 100644 --- a/src/serializers/type_serializers/function.rs +++ b/src/serializers/type_serializers/function.rs @@ -21,6 +21,54 @@ use super::{ PydanticSerializationError, TypeSerializer, }; +pub struct FunctionBeforeSerializerBuilder; + +impl BuildSerializer for FunctionBeforeSerializerBuilder { + const EXPECTED_TYPE: &'static str = "function-before"; + + fn build( + schema: &PyDict, + config: Option<&PyDict>, + build_context: &mut BuildContext, + ) -> PyResult { + let py = schema.py(); + // `before` schemas will obviously have type from `schema` since the validator is called second + let schema = schema.get_as_req(intern!(py, "schema"))?; + CombinedSerializer::build(schema, config, build_context) + } +} + +pub struct FunctionAfterSerializerBuilder; + +impl BuildSerializer for FunctionAfterSerializerBuilder { + const EXPECTED_TYPE: &'static str = "function-after"; + fn build( + schema: &PyDict, + config: Option<&PyDict>, + build_context: &mut BuildContext, + ) -> PyResult { + let py = schema.py(); + // while `before` schemas have an obvious type, for + // `after` schemas it's less, clear but the default will be the same type, and the user/lib can always + // override the serializer + let schema = schema.get_as_req(intern!(py, "schema"))?; + CombinedSerializer::build(schema, config, build_context) + } +} + +pub struct FunctionPlainSerializerBuilder; + +impl BuildSerializer for FunctionPlainSerializerBuilder { + const EXPECTED_TYPE: &'static str = "function-plain"; + fn build( + schema: &PyDict, + config: Option<&PyDict>, + build_context: &mut BuildContext, + ) -> PyResult { + super::any::AnySerializer::build(schema, config, build_context) + } +} + #[derive(Debug, Clone)] pub struct FunctionPlainSerializer { func: PyObject, @@ -30,8 +78,13 @@ pub struct FunctionPlainSerializer { when_used: WhenUsed, } -impl FunctionPlainSerializer { - pub fn new_combined(schema: &PyDict) -> PyResult { +impl BuildSerializer for FunctionPlainSerializer { + const EXPECTED_TYPE: &'static str = "function-plain"; + fn build( + schema: &PyDict, + _config: Option<&PyDict>, + _build_context: &mut BuildContext, + ) -> PyResult { let py = schema.py(); let function = schema.get_as_req::<&PyAny>(intern!(py, "function"))?; let function_name = function_name(function)?; @@ -46,7 +99,9 @@ impl FunctionPlainSerializer { } .into()) } +} +impl FunctionPlainSerializer { fn call( &self, value: &PyAny, @@ -177,6 +232,19 @@ macro_rules! function_type_serializer { function_type_serializer!(FunctionPlainSerializer); +pub struct FunctionWrapSerializerBuilder; + +impl BuildSerializer for FunctionWrapSerializerBuilder { + const EXPECTED_TYPE: &'static str = "function-wrap"; + fn build( + schema: &PyDict, + config: Option<&PyDict>, + build_context: &mut BuildContext, + ) -> PyResult { + super::any::AnySerializer::build(schema, config, build_context) + } +} + #[derive(Debug, Clone)] pub struct FunctionWrapSerializer { serializer: Box, @@ -187,8 +255,9 @@ pub struct FunctionWrapSerializer { when_used: WhenUsed, } -impl FunctionWrapSerializer { - pub fn new_combined( +impl BuildSerializer for FunctionWrapSerializer { + const EXPECTED_TYPE: &'static str = "function-wrap"; + fn build( schema: &PyDict, config: Option<&PyDict>, build_context: &mut BuildContext, @@ -211,7 +280,9 @@ impl FunctionWrapSerializer { } .into()) } +} +impl FunctionWrapSerializer { fn call( &self, value: &PyAny, diff --git a/src/serializers/type_serializers/other.rs b/src/serializers/type_serializers/other.rs index b41802a68..116f2b2aa 100644 --- a/src/serializers/type_serializers/other.rs +++ b/src/serializers/type_serializers/other.rs @@ -29,30 +29,6 @@ impl BuildSerializer for ChainBuilder { } } -pub struct FunctionBuilder; - -impl BuildSerializer for FunctionBuilder { - const EXPECTED_TYPE: &'static str = "function"; - - fn build( - schema: &PyDict, - config: Option<&PyDict>, - build_context: &mut BuildContext, - ) -> PyResult { - let py = schema.py(); - let mode: &str = schema.get_as_req(intern!(py, "mode"))?; - // `before` schemas will obviously have type from `schema` since the validator is called second - // `after` schemas it's less, clear but the default will be the same type, and the user/lib can always - // override the serializer - if mode == "before" || mode == "after" { - let schema = schema.get_as_req(intern!(py, "schema"))?; - CombinedSerializer::build(schema, config, build_context) - } else { - AnySerializer::build(schema, config, build_context) - } - } -} - pub struct CustomErrorBuilder; impl BuildSerializer for CustomErrorBuilder { diff --git a/src/serializers/type_serializers/tuple.rs b/src/serializers/type_serializers/tuple.rs index d71fbc36a..525d4f01d 100644 --- a/src/serializers/type_serializers/tuple.rs +++ b/src/serializers/type_serializers/tuple.rs @@ -14,23 +14,6 @@ use super::{ PydanticSerializer, SchemaFilter, SerMode, TypeSerializer, }; -pub struct TupleBuilder; - -impl BuildSerializer for TupleBuilder { - const EXPECTED_TYPE: &'static str = "tuple"; - - fn build( - schema: &PyDict, - config: Option<&PyDict>, - build_context: &mut BuildContext, - ) -> PyResult { - match schema.get_as::<&str>(intern!(schema.py(), "mode"))? { - Some("positional") => TuplePositionalSerializer::build(schema, config, build_context), - _ => TupleVariableSerializer::build(schema, config, build_context), - } - } -} - #[derive(Debug, Clone)] pub struct TupleVariableSerializer { item_serializer: Box, @@ -38,7 +21,9 @@ pub struct TupleVariableSerializer { name: String, } -impl TupleVariableSerializer { +impl BuildSerializer for TupleVariableSerializer { + const EXPECTED_TYPE: &'static str = "tuple-variable"; + fn build( schema: &PyDict, config: Option<&PyDict>, @@ -159,7 +144,9 @@ pub struct TuplePositionalSerializer { name: String, } -impl TuplePositionalSerializer { +impl BuildSerializer for TuplePositionalSerializer { + const EXPECTED_TYPE: &'static str = "tuple-positional"; + fn build( schema: &PyDict, config: Option<&PyDict>, diff --git a/src/validators/custom_error.rs b/src/validators/custom_error.rs index 3a7dd5f0b..495ba2818 100644 --- a/src/validators/custom_error.rs +++ b/src/validators/custom_error.rs @@ -17,7 +17,11 @@ pub enum CustomError { } impl CustomError { - pub fn build(schema: &PyDict) -> PyResult> { + pub fn build( + schema: &PyDict, + _config: Option<&PyDict>, + _build_context: &mut BuildContext, + ) -> PyResult> { let py = schema.py(); let error_type: String = match schema.get_as(intern!(py, "custom_error_type"))? { Some(error_type) => error_type, @@ -66,7 +70,7 @@ impl BuildValidator for CustomErrorValidator { config: Option<&PyDict>, build_context: &mut BuildContext, ) -> PyResult { - let custom_error = CustomError::build(schema)?.unwrap(); + let custom_error = CustomError::build(schema, config, build_context)?.unwrap(); let schema: &PyAny = schema.get_as_req(intern!(schema.py(), "schema"))?; let validator = Box::new(build_validator(schema, config, build_context)?); let name = format!("{}[{}]", Self::EXPECTED_TYPE, validator.get_name()); diff --git a/src/validators/float.rs b/src/validators/float.rs index d607d2bd8..f51944f66 100644 --- a/src/validators/float.rs +++ b/src/validators/float.rs @@ -9,19 +9,14 @@ use crate::recursion_guard::RecursionGuard; use super::{BuildContext, BuildValidator, CombinedValidator, Extra, Validator}; -#[derive(Debug, Clone)] -pub struct FloatValidator { - strict: bool, - allow_inf_nan: bool, -} +pub struct FloatBuilder; -impl BuildValidator for FloatValidator { +impl BuildValidator for FloatBuilder { const EXPECTED_TYPE: &'static str = "float"; - fn build( schema: &PyDict, config: Option<&PyDict>, - _build_context: &mut BuildContext, + build_context: &mut BuildContext, ) -> PyResult { let py = schema.py(); let use_constrained = schema.get_item(intern!(py, "multiple_of")).is_some() @@ -30,9 +25,9 @@ impl BuildValidator for FloatValidator { || schema.get_item(intern!(py, "ge")).is_some() || schema.get_item(intern!(py, "gt")).is_some(); if use_constrained { - ConstrainedFloatValidator::build(schema, config) + ConstrainedFloatValidator::build(schema, config, build_context) } else { - Ok(Self { + Ok(FloatValidator { strict: is_strict(schema, config)?, allow_inf_nan: schema_or_config_same(schema, config, intern!(py, "allow_inf_nan"))?.unwrap_or(true), } @@ -41,6 +36,29 @@ impl BuildValidator for FloatValidator { } } +#[derive(Debug, Clone)] +pub struct FloatValidator { + strict: bool, + allow_inf_nan: bool, +} + +impl BuildValidator for FloatValidator { + const EXPECTED_TYPE: &'static str = "float"; + + fn build( + schema: &PyDict, + config: Option<&PyDict>, + _build_context: &mut BuildContext, + ) -> PyResult { + let py = schema.py(); + Ok(Self { + strict: is_strict(schema, config)?, + allow_inf_nan: schema_or_config_same(schema, config, intern!(py, "allow_inf_nan"))?.unwrap_or(true), + } + .into()) + } +} + impl Validator for FloatValidator { fn validate<'s, 'data>( &'s self, @@ -125,8 +143,13 @@ impl Validator for ConstrainedFloatValidator { } } -impl ConstrainedFloatValidator { - pub fn build(schema: &PyDict, config: Option<&PyDict>) -> PyResult { +impl BuildValidator for ConstrainedFloatValidator { + const EXPECTED_TYPE: &'static str = "float"; + fn build( + schema: &PyDict, + config: Option<&PyDict>, + _build_context: &mut BuildContext, + ) -> PyResult { let py = schema.py(); Ok(Self { strict: is_strict(schema, config)?, diff --git a/src/validators/function.rs b/src/validators/function.rs index fdbf5aff3..e2bbdec38 100644 --- a/src/validators/function.rs +++ b/src/validators/function.rs @@ -14,8 +14,6 @@ use crate::recursion_guard::RecursionGuard; use super::generator::InternalValidator; use super::{build_validator, BuildContext, BuildValidator, CombinedValidator, Extra, Validator}; -pub struct FunctionBuilder; - fn destructure_function_schema(schema: &PyDict) -> PyResult<(bool, &PyAny)> { let func_dict: &PyDict = schema.get_as_req(intern!(schema.py(), "function"))?; let function: &PyAny = func_dict.get_as_req(intern!(schema.py(), "function"))?; @@ -28,29 +26,11 @@ fn destructure_function_schema(schema: &PyDict) -> PyResult<(bool, &PyAny)> { Ok((is_field_validator, function)) } -impl BuildValidator for FunctionBuilder { - const EXPECTED_TYPE: &'static str = "function"; - - fn build( - schema: &PyDict, - config: Option<&PyDict>, - build_context: &mut BuildContext, - ) -> PyResult { - let mode: &str = schema.get_as_req(intern!(schema.py(), "mode"))?; - match mode { - "before" => FunctionBeforeValidator::build(schema, config, build_context), - "after" => FunctionAfterValidator::build(schema, config, build_context), - "wrap" => FunctionWrapValidator::build(schema, config, build_context), - // must be "plain" - _ => FunctionPlainValidator::build(schema, config), - } - } -} - macro_rules! impl_build { ($impl_name:ident, $name:literal) => { - impl $impl_name { - pub fn build( + impl BuildValidator for $impl_name { + const EXPECTED_TYPE: &'static str = $name; + fn build( schema: &PyDict, config: Option<&PyDict>, build_context: &mut BuildContext, @@ -169,8 +149,14 @@ pub struct FunctionPlainValidator { is_field_validator: bool, } -impl FunctionPlainValidator { - pub fn build(schema: &PyDict, config: Option<&PyDict>) -> PyResult { +impl BuildValidator for FunctionPlainValidator { + const EXPECTED_TYPE: &'static str = "function-plain"; + + fn build( + schema: &PyDict, + config: Option<&PyDict>, + _build_context: &mut BuildContext, + ) -> PyResult { let py = schema.py(); let (is_field_validator, function) = destructure_function_schema(schema)?; Ok(Self { diff --git a/src/validators/mod.rs b/src/validators/mod.rs index 806dcbf5a..5e5bde0b1 100644 --- a/src/validators/mod.rs +++ b/src/validators/mod.rs @@ -384,9 +384,10 @@ pub fn build_validator<'a>( // boolean bool::BoolValidator, // floats - float::FloatValidator, + float::FloatBuilder, // tuples - tuple::TupleBuilder, + tuple::TuplePositionalValidator, + tuple::TupleVariableValidator, // list/arrays list::ListValidator, // sets - unique lists @@ -396,7 +397,10 @@ pub fn build_validator<'a>( // None/null none::NoneValidator, // functions - before, after, plain & wrap - function::FunctionBuilder, + function::FunctionAfterValidator, + function::FunctionBeforeValidator, + function::FunctionPlainValidator, + function::FunctionWrapValidator, // function call - validation around a function call call::CallValidator, // literals diff --git a/src/validators/tuple.rs b/src/validators/tuple.rs index 8ae584295..04764df83 100644 --- a/src/validators/tuple.rs +++ b/src/validators/tuple.rs @@ -11,24 +11,6 @@ use super::list::{get_items_schema, length_check}; use super::with_default::get_default; use super::{build_validator, BuildContext, BuildValidator, CombinedValidator, Extra, Validator}; -#[derive(Debug)] -pub struct TupleBuilder; - -impl BuildValidator for TupleBuilder { - const EXPECTED_TYPE: &'static str = "tuple"; - - fn build( - schema: &PyDict, - config: Option<&PyDict>, - build_context: &mut BuildContext, - ) -> PyResult { - match schema.get_as::<&str>(intern!(schema.py(), "mode"))? { - Some("positional") => TuplePositionalValidator::build(schema, config, build_context), - _ => TupleVariableValidator::build(schema, config, build_context), - } - } -} - #[derive(Debug, Clone)] pub struct TupleVariableValidator { strict: bool, @@ -38,7 +20,8 @@ pub struct TupleVariableValidator { name: String, } -impl TupleVariableValidator { +impl BuildValidator for TupleVariableValidator { + const EXPECTED_TYPE: &'static str = "tuple-variable"; fn build( schema: &PyDict, config: Option<&PyDict>, @@ -114,7 +97,8 @@ pub struct TuplePositionalValidator { name: String, } -impl TuplePositionalValidator { +impl BuildValidator for TuplePositionalValidator { + const EXPECTED_TYPE: &'static str = "tuple-positional"; fn build( schema: &PyDict, config: Option<&PyDict>, diff --git a/src/validators/union.rs b/src/validators/union.rs index 324b7e3d8..b9495e39b 100644 --- a/src/validators/union.rs +++ b/src/validators/union.rs @@ -51,7 +51,7 @@ impl BuildValidator for UnionValidator { Ok(Self { choices, - custom_error: CustomError::build(schema)?, + custom_error: CustomError::build(schema, config, build_context)?, strict: is_strict(schema, config)?, name: format!("{}[{descr}]", Self::EXPECTED_TYPE), } @@ -326,7 +326,7 @@ impl BuildValidator for TaggedUnionValidator { discriminator, from_attributes, strict: is_strict(schema, config)?, - custom_error: CustomError::build(schema)?, + custom_error: CustomError::build(schema, config, build_context)?, tags_repr, discriminator_repr, name: format!("{}[{descr}]", Self::EXPECTED_TYPE), diff --git a/tests/benchmarks/complete_schema.py b/tests/benchmarks/complete_schema.py index 4ce8c8d70..f0dcfd604 100644 --- a/tests/benchmarks/complete_schema.py +++ b/tests/benchmarks/complete_schema.py @@ -54,15 +54,19 @@ def wrap_function(input_value, validator, info): 'max_length': 42, } }, - 'field_tuple_var_len_any': {'schema': {'type': 'tuple'}}, - 'field_tuple_var_len_float': {'schema': {'type': 'tuple', 'items_schema': {'type': 'float'}}}, + 'field_tuple_var_len_any': {'schema': {'type': 'tuple-variable'}}, + 'field_tuple_var_len_float': {'schema': {'type': 'tuple-variable', 'items_schema': {'type': 'float'}}}, 'field_tuple_var_len_float_con': { - 'schema': {'type': 'tuple', 'items_schema': {'type': 'float'}, 'min_length': 3, 'max_length': 42} + 'schema': { + 'type': 'tuple-variable', + 'items_schema': {'type': 'float'}, + 'min_length': 3, + 'max_length': 42, + } }, 'field_tuple_fix_len': { 'schema': { - 'type': 'tuple', - 'mode': 'positional', + 'type': 'tuple-positional', 'items_schema': [{'type': 'str'}, {'type': 'int'}, {'type': 'float'}, {'type': 'bool'}], } }, @@ -108,32 +112,28 @@ def wrap_function(input_value, validator, info): 'fields': { 'field_before': { 'schema': { - 'type': 'function', - 'mode': 'before', + 'type': 'function-before', 'function': {'type': 'general', 'function': append_func}, 'schema': {'type': 'str'}, } }, 'field_after': { 'schema': { - 'type': 'function', - 'mode': 'after', + 'type': 'function-after', 'function': {'type': 'general', 'function': append_func}, 'schema': {'type': 'str'}, } }, 'field_wrap': { 'schema': { - 'type': 'function', - 'mode': 'wrap', + 'type': 'function-wrap', 'function': {'type': 'general', 'function': wrap_function}, 'schema': {'type': 'str'}, } }, 'field_plain': { 'schema': { - 'type': 'function', - 'mode': 'plain', + 'type': 'function-plain', 'function': {'type': 'general', 'function': append_func}, } }, diff --git a/tests/benchmarks/test_micro_benchmarks.py b/tests/benchmarks/test_micro_benchmarks.py index b94ae1765..e65634cfb 100644 --- a/tests/benchmarks/test_micro_benchmarks.py +++ b/tests/benchmarks/test_micro_benchmarks.py @@ -910,7 +910,7 @@ def test_dont_raise_error(benchmark): def f(input_value, info): return input_value - v = SchemaValidator({'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f}}) + v = SchemaValidator({'type': 'function-plain', 'function': {'type': 'general', 'function': f}}) @benchmark def t(): @@ -922,7 +922,7 @@ def test_raise_error_value_error(benchmark): def f(input_value, info): raise ValueError('this is a custom error') - v = SchemaValidator({'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f}}) + v = SchemaValidator({'type': 'function-plain', 'function': {'type': 'general', 'function': f}}) @benchmark def t(): @@ -939,7 +939,7 @@ def test_raise_error_custom(benchmark): def f(input_value, info): raise PydanticCustomError('my_error', 'this is a custom error {foo}', {'foo': 'FOOBAR'}) - v = SchemaValidator({'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f}}) + v = SchemaValidator({'type': 'function-plain', 'function': {'type': 'general', 'function': f}}) @benchmark def t(): @@ -955,8 +955,7 @@ def t(): def test_positional_tuple(benchmark): v = SchemaValidator( { - 'type': 'tuple', - 'mode': 'positional', + 'type': 'tuple-positional', 'items_schema': [{'type': 'int'}, {'type': 'int'}, {'type': 'int'}, {'type': 'int'}, {'type': 'int'}], } ) @@ -967,7 +966,7 @@ def test_positional_tuple(benchmark): @pytest.mark.benchmark(group='tuple') def test_variable_tuple(benchmark): - v = SchemaValidator({'type': 'tuple', 'items_schema': {'type': 'int'}}) + v = SchemaValidator({'type': 'tuple-variable', 'items_schema': {'type': 'int'}}) assert v.validate_python((1, 2, 3, '4', 5)) == (1, 2, 3, 4, 5) benchmark(v.validate_python, (1, 2, 3, '4', 5)) @@ -975,7 +974,7 @@ def test_variable_tuple(benchmark): @pytest.mark.benchmark(group='tuple-many') def test_tuple_many_variable(benchmark): - v = SchemaValidator({'type': 'tuple', 'items_schema': {'type': 'int'}}) + v = SchemaValidator({'type': 'tuple-variable', 'items_schema': {'type': 'int'}}) assert v.validate_python(list(range(10))) == tuple(range(10)) benchmark(v.validate_python, list(range(10))) @@ -983,7 +982,7 @@ def test_tuple_many_variable(benchmark): @pytest.mark.benchmark(group='tuple-many') def test_tuple_many_positional(benchmark): - v = SchemaValidator({'type': 'tuple', 'mode': 'positional', 'items_schema': [], 'extra_schema': {'type': 'int'}}) + v = SchemaValidator({'type': 'tuple-positional', 'items_schema': [], 'extra_schema': {'type': 'int'}}) assert v.validate_python(list(range(10))) == tuple(range(10)) benchmark(v.validate_python, list(range(10))) @@ -1035,11 +1034,7 @@ def test_chain_list(benchmark): 'type': 'chain', 'steps': [ {'type': 'str'}, - { - 'type': 'function', - 'mode': 'plain', - 'function': {'type': 'general', 'function': lambda v, info: Decimal(v)}, - }, + {'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: Decimal(v)}}, ], } ) @@ -1052,8 +1047,7 @@ def test_chain_list(benchmark): def test_chain_function(benchmark): validator = SchemaValidator( { - 'type': 'function', - 'mode': 'after', + 'type': 'function-after', 'schema': {'type': 'str'}, 'function': {'type': 'general', 'function': lambda v, info: Decimal(v)}, } @@ -1070,16 +1064,8 @@ def test_chain_two_functions(benchmark): 'type': 'chain', 'steps': [ {'type': 'str'}, - { - 'type': 'function', - 'mode': 'plain', - 'function': {'type': 'general', 'function': lambda v, info: Decimal(v)}, - }, - { - 'type': 'function', - 'mode': 'plain', - 'function': {'type': 'general', 'function': lambda v, info: v * 2}, - }, + {'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: Decimal(v)}}, + {'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: v * 2}}, ], } ) @@ -1092,14 +1078,12 @@ def test_chain_two_functions(benchmark): def test_chain_nested_functions(benchmark): validator = SchemaValidator( { - 'type': 'function', + 'type': 'function-after', 'schema': { - 'type': 'function', + 'type': 'function-after', 'schema': {'type': 'str'}, - 'mode': 'after', 'function': {'type': 'general', 'function': lambda v, info: Decimal(v)}, }, - 'mode': 'after', 'function': {'type': 'general', 'function': lambda v, info: v * 2}, } ) diff --git a/tests/serializers/test_definitions.py b/tests/serializers/test_definitions.py index 6221248c7..7d18e4aba 100644 --- a/tests/serializers/test_definitions.py +++ b/tests/serializers/test_definitions.py @@ -37,7 +37,7 @@ def test_def_error(): ) assert exc_info.value.args[0].startswith( - "Invalid Schema:\ndefinitions -> definitions -> 1\n Input tag 'wrong' found using self-schema" + "Invalid Schema:\ndefinitions -> definitions -> 1\n Input tag 'wrong' found using 'type'" ) diff --git a/tests/serializers/test_list_tuple.py b/tests/serializers/test_list_tuple.py index ecfc0a55f..f7fa070d4 100644 --- a/tests/serializers/test_list_tuple.py +++ b/tests/serializers/test_list_tuple.py @@ -309,7 +309,7 @@ def test_filter_list_of_dicts(): def test_positional_tuple(): s = SchemaSerializer( - {'type': 'tuple', 'mode': 'positional', 'items_schema': [{'type': 'int'}, {'type': 'bytes'}, {'type': 'float'}]} + {'type': 'tuple-positional', 'items_schema': [{'type': 'int'}, {'type': 'bytes'}, {'type': 'float'}]} ) assert s.to_python((1, b'2', 3.0)) == (1, b'2', 3.0) assert s.to_python((1, b'2', 3.0, 123)) == (1, b'2', 3.0, 123) @@ -330,8 +330,7 @@ def f(prefix, value, _info): s = SchemaSerializer( { - 'type': 'tuple', - 'mode': 'positional', + 'type': 'tuple-positional', 'items_schema': [ core_schema.any_schema(serialization=core_schema.function_plain_ser_schema(partial(f, 'a'))), core_schema.any_schema(serialization=core_schema.function_plain_ser_schema(partial(f, 'b'))), diff --git a/tests/serializers/test_none.py b/tests/serializers/test_none.py index 6e0a3f846..6bbd49c46 100644 --- a/tests/serializers/test_none.py +++ b/tests/serializers/test_none.py @@ -16,7 +16,7 @@ 'url', 'multi-host-url', ) -all_types = all_scalars + ('list', 'tuple', 'dict', 'set', 'frozenset') +all_types = all_scalars + ('list', 'tuple-variable', 'dict', 'set', 'frozenset') @pytest.mark.parametrize('schema_type', all_types) diff --git a/tests/test_build.py b/tests/test_build.py index 6a3ff64b5..51195baba 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -6,7 +6,7 @@ def test_build_error_type(): - with pytest.raises(SchemaError, match="Input tag 'foobar' found using self-schema does not match any of the"): + with pytest.raises(SchemaError, match="Input tag 'foobar' found using 'type' does not match any of the"): SchemaValidator({'type': 'foobar', 'title': 'TestModel'}) @@ -35,7 +35,8 @@ def test_schema_wrong_type(): with pytest.raises(SchemaError) as exc_info: SchemaValidator(1) assert exc_info.value.args[0] == ( - 'Invalid Schema:\n Input should be a valid dictionary [type=dict_type, input_value=1, input_type=int]' + 'Invalid Schema:\n Input should be a valid dictionary or instance to' + ' extract fields from [type=dict_attributes_type, input_value=1, input_type=int]' ) @@ -66,17 +67,17 @@ def test_not_schema_definition_error(): def test_no_type(): - with pytest.raises(SchemaError, match='Unable to extract tag using discriminator self-schema'): + with pytest.raises(SchemaError, match="Unable to extract tag using discriminator 'type'"): SchemaValidator({}) def test_wrong_type(): - with pytest.raises(SchemaError, match="Input tag 'unknown' found using self-schema does not match any of the"): + with pytest.raises(SchemaError, match="Input tag 'unknown' found using 'type' does not match any of the"): SchemaValidator({'type': 'unknown'}) def test_function_no_mode(): - with pytest.raises(SchemaError, match='Unable to extract tag using discriminator self-schema'): + with pytest.raises(SchemaError, match="Input tag 'function' found using 'type' does not match any of the"): SchemaValidator({'type': 'function'}) diff --git a/tests/test_errors.py b/tests/test_errors.py index 6fcbbad5b..0bf6f7674 100644 --- a/tests/test_errors.py +++ b/tests/test_errors.py @@ -36,7 +36,7 @@ def test_pydantic_value_error_usage(): def f(input_value, info): raise PydanticCustomError('my_error', 'this is a custom error {foo} {bar}', {'foo': 'FOOBAR', 'bar': 42}) - v = SchemaValidator({'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f}}) + v = SchemaValidator({'type': 'function-plain', 'function': {'type': 'general', 'function': f}}) with pytest.raises(ValidationError) as exc_info: v.validate_python(42) @@ -56,7 +56,7 @@ def test_pydantic_value_error_invalid_dict(): def my_function(input_value, info): raise PydanticCustomError('my_error', 'this is a custom error {foo}', {(): 'foobar'}) - v = SchemaValidator({'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': my_function}}) + v = SchemaValidator({'type': 'function-plain', 'function': {'type': 'general', 'function': my_function}}) with pytest.raises(ValidationError) as exc_info: v.validate_python(42) @@ -74,7 +74,7 @@ def test_pydantic_value_error_invalid_type(): def f(input_value, info): raise PydanticCustomError('my_error', 'this is a custom error {foo}', [('foo', 123)]) - v = SchemaValidator({'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f}}) + v = SchemaValidator({'type': 'function-plain', 'function': {'type': 'general', 'function': f}}) with pytest.raises(TypeError, match="argument 'context': 'list' object cannot be converted to 'PyDict'"): v.validate_python(42) @@ -91,12 +91,7 @@ def validate(self, input_value, info): c = CustomValidator() v = SchemaValidator( - { - 'type': 'function', - 'mode': 'plain', - 'metadata': {'instance': c}, - 'function': {'type': 'general', 'function': c.validate}, - } + {'type': 'function-plain', 'metadata': {'instance': c}, 'function': {'type': 'general', 'function': c.validate}} ) c.foo += 1 @@ -117,8 +112,7 @@ def validate(self, input_value, info): c = CustomValidator() v = SchemaValidator( { - 'type': 'function', - 'mode': 'after', + 'type': 'function-after', 'metadata': {'instance': c}, 'function': {'type': 'general', 'function': c.validate}, 'schema': {'type': 'str'}, @@ -144,12 +138,7 @@ def f(input_value, info): raise PydanticKnownError('finite_number') v = SchemaValidator( - { - 'type': 'function', - 'mode': 'before', - 'function': {'type': 'general', 'function': f}, - 'schema': {'type': 'int'}, - } + {'type': 'function-before', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'int'}} ) with pytest.raises(ValidationError) as exc_info: @@ -165,12 +154,7 @@ def f(input_value, info): raise PydanticKnownError('greater_than', {'gt': 42}) v = SchemaValidator( - { - 'type': 'function', - 'mode': 'before', - 'function': {'type': 'general', 'function': f}, - 'schema': {'type': 'int'}, - } + {'type': 'function-before', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'int'}} ) with pytest.raises(ValidationError) as exc_info: @@ -320,7 +304,7 @@ def test_pydantic_value_error_plain(py_and_json: PyAndJson): def f(input_value, info): raise PydanticCustomError - v = py_and_json({'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f}}) + v = py_and_json({'type': 'function-plain', 'function': {'type': 'general', 'function': f}}) with pytest.raises(TypeError, match='missing 2 required positional arguments'): v.validate_test('4') @@ -336,9 +320,8 @@ def f(input_value, info): { 'type': 'list', 'items_schema': { - 'type': 'function', + 'type': 'function-after', 'schema': {'type': 'int'}, - 'mode': 'after', 'function': {'type': 'general', 'function': f}, }, } diff --git a/tests/test_schema_functions.py b/tests/test_schema_functions.py index 5c67e9894..ff692e3e3 100644 --- a/tests/test_schema_functions.py +++ b/tests/test_schema_functions.py @@ -60,13 +60,13 @@ def args(*args, **kwargs): ( core_schema.tuple_positional_schema, args({'type': 'int'}), - {'type': 'tuple', 'mode': 'positional', 'items_schema': [{'type': 'int'}]}, + {'type': 'tuple-positional', 'items_schema': [{'type': 'int'}]}, ), - (core_schema.tuple_positional_schema, args(), {'type': 'tuple', 'mode': 'positional', 'items_schema': []}), + (core_schema.tuple_positional_schema, args(), {'type': 'tuple-positional', 'items_schema': []}), ( core_schema.tuple_variable_schema, args({'type': 'int'}), - {'type': 'tuple', 'mode': 'variable', 'items_schema': {'type': 'int'}}, + {'type': 'tuple-variable', 'items_schema': {'type': 'int'}}, ), ( core_schema.set_schema, @@ -89,8 +89,7 @@ def args(*args, **kwargs): core_schema.general_before_validation_function, args(val_function, {'type': 'int'}), { - 'type': 'function', - 'mode': 'before', + 'type': 'function-before', 'function': {'type': 'general', 'function': val_function}, 'schema': {'type': 'int'}, }, @@ -99,8 +98,7 @@ def args(*args, **kwargs): core_schema.general_after_validation_function, args(val_function, {'type': 'int'}), { - 'type': 'function', - 'mode': 'after', + 'type': 'function-after', 'function': {'type': 'general', 'function': val_function}, 'schema': {'type': 'int'}, }, @@ -108,17 +106,12 @@ def args(*args, **kwargs): ( core_schema.general_wrap_validation_function, args(val_function, {'type': 'int'}), - { - 'type': 'function', - 'mode': 'wrap', - 'function': {'type': 'general', 'function': val_function}, - 'schema': {'type': 'int'}, - }, + {'type': 'function-wrap', 'function': {'type': 'general', 'function': val_function}, 'schema': {'type': 'int'}}, ), ( core_schema.general_plain_validation_function, args(val_function), - {'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': val_function}}, + {'type': 'function-plain', 'function': {'type': 'general', 'function': val_function}}, ), ( core_schema.with_default_schema, diff --git a/tests/test_typing.py b/tests/test_typing.py index 5953878f4..a780de49e 100644 --- a/tests/test_typing.py +++ b/tests/test_typing.py @@ -67,9 +67,9 @@ def test_schema_typing() -> None: SchemaValidator(schema) schema: CoreSchema = {'type': 'set', 'items_schema': {'type': 'str'}, 'max_length': 3} SchemaValidator(schema) - schema: CoreSchema = {'type': 'tuple', 'mode': 'variable', 'items_schema': {'type': 'str'}, 'max_length': 3} + schema: CoreSchema = {'type': 'tuple-variable', 'items_schema': {'type': 'str'}, 'max_length': 3} SchemaValidator(schema) - schema: CoreSchema = {'type': 'tuple', 'mode': 'positional', 'items_schema': [{'type': 'str'}, {'type': 'int'}]} + schema: CoreSchema = {'type': 'tuple-positional', 'items_schema': [{'type': 'str'}, {'type': 'int'}]} SchemaValidator(schema) schema: CoreSchema = {'type': 'frozenset', 'items_schema': {'type': 'str'}, 'max_length': 3} SchemaValidator(schema) @@ -92,13 +92,12 @@ def test_schema_typing() -> None: } SchemaValidator(schema) schema: CoreSchema = { - 'type': 'function', - 'mode': 'wrap', + 'type': 'function-wrap', 'function': {'type': 'general', 'function': wrap_validator}, 'schema': {'type': 'str'}, } SchemaValidator(schema) - schema: CoreSchema = {'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': validator}} + schema: CoreSchema = {'type': 'function-plain', 'function': {'type': 'general', 'function': validator}} SchemaValidator(schema) schema: CoreSchema = { 'ref': 'Branch', diff --git a/tests/test_validation_context.py b/tests/test_validation_context.py index 526b55680..6ecd14c55 100644 --- a/tests/test_validation_context.py +++ b/tests/test_validation_context.py @@ -10,7 +10,7 @@ def f(input_value, info): return input_value + f'| context: {info.context}' v = py_and_json( - {'type': 'function', 'mode': 'after', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} + {'type': 'function-after', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) assert v.validate_test('foobar') == 'foobar| context: None' @@ -24,12 +24,7 @@ def f(input_value, info): return input_value v = py_and_json( - { - 'type': 'function', - 'mode': 'before', - 'function': {'type': 'general', 'function': f}, - 'schema': {'type': 'str'}, - } + {'type': 'function-before', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) mutable_context = {} assert v.validate_test('foobar', None, mutable_context) == 'foobar' @@ -49,12 +44,8 @@ def f2(input_value, info): { 'type': 'typed-dict', 'fields': { - 'f1': { - 'schema': {'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f1}} - }, - 'f2': { - 'schema': {'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f2}} - }, + 'f1': {'schema': {'type': 'function-plain', 'function': {'type': 'general', 'function': f1}}}, + 'f2': {'schema': {'type': 'function-plain', 'function': {'type': 'general', 'function': f2}}}, }, } ) @@ -70,7 +61,7 @@ def f(input_value, validator, info): return validator(input_value) + f'| context: {info.context}' v = py_and_json( - {'type': 'function', 'mode': 'wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} + {'type': 'function-wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) assert v.validate_test('foobar') == 'foobar| context: None' @@ -85,7 +76,7 @@ def f(input_value, validator, info): return validator(input_value) v = py_and_json( - {'type': 'function', 'mode': 'wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} + {'type': 'function-wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) assert v.validate_python('foobar', None, {}) == 'foobar' @@ -121,12 +112,8 @@ def f2(input_value, info): { 'type': 'typed-dict', 'fields': { - 'f1': { - 'schema': {'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f1}} - }, - 'f2': { - 'schema': {'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f2}} - }, + 'f1': {'schema': {'type': 'function-plain', 'function': {'type': 'general', 'function': f1}}}, + 'f2': {'schema': {'type': 'function-plain', 'function': {'type': 'general', 'function': f2}}}, }, } ) diff --git a/tests/validators/test_arguments.py b/tests/validators/test_arguments.py index 93cb6c78a..84949ec65 100644 --- a/tests/validators/test_arguments.py +++ b/tests/validators/test_arguments.py @@ -620,11 +620,7 @@ def test_internal_error(py_and_json: PyAndJson): { 'name': 'b', 'mode': 'positional_only', - 'schema': { - 'type': 'function', - 'mode': 'plain', - 'function': {'type': 'general', 'function': double_or_bust}, - }, + 'schema': {'type': 'function-plain', 'function': {'type': 'general', 'function': double_or_bust}}, }, ], } diff --git a/tests/validators/test_chain.py b/tests/validators/test_chain.py index 121b6d0b4..cfeb2f6b4 100644 --- a/tests/validators/test_chain.py +++ b/tests/validators/test_chain.py @@ -14,11 +14,7 @@ def test_chain(): 'type': 'chain', 'steps': [ {'type': 'str'}, - { - 'type': 'function', - 'mode': 'plain', - 'function': {'type': 'general', 'function': lambda v, info: Decimal(v)}, - }, + {'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: Decimal(v)}}, ], } ) @@ -32,26 +28,10 @@ def test_chain_many(): { 'type': 'chain', 'steps': [ - { - 'type': 'function', - 'mode': 'plain', - 'function': {'type': 'general', 'function': lambda v, info: f'{v}-1'}, - }, - { - 'type': 'function', - 'mode': 'plain', - 'function': {'type': 'general', 'function': lambda v, info: f'{v}-2'}, - }, - { - 'type': 'function', - 'mode': 'plain', - 'function': {'type': 'general', 'function': lambda v, info: f'{v}-3'}, - }, - { - 'type': 'function', - 'mode': 'plain', - 'function': {'type': 'general', 'function': lambda v, info: f'{v}-4'}, - }, + {'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: f'{v}-1'}}, + {'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: f'{v}-2'}}, + {'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: f'{v}-3'}}, + {'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: f'{v}-4'}}, ], } ) @@ -87,11 +67,7 @@ def test_json(py_and_json: PyAndJson, input_value, expected): 'type': 'chain', 'steps': [ {'type': 'union', 'choices': [{'type': 'str'}, {'type': 'float'}]}, - { - 'type': 'function', - 'mode': 'plain', - 'function': {'type': 'general', 'function': lambda v, info: Decimal(v)}, - }, + {'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: Decimal(v)}}, ], } ) @@ -105,22 +81,16 @@ def test_flatten(): { 'type': 'chain', 'steps': [ - { - 'type': 'function', - 'mode': 'plain', - 'function': {'type': 'general', 'function': lambda v, info: f'{v}-1'}, - }, + {'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: f'{v}-1'}}, { 'type': 'chain', 'steps': [ { - 'type': 'function', - 'mode': 'plain', + 'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: f'{v}-2'}, }, { - 'type': 'function', - 'mode': 'plain', + 'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: f'{v}-3'}, }, ], @@ -143,11 +113,7 @@ def test_chain_one(): { 'type': 'chain', 'steps': [ - { - 'type': 'function', - 'mode': 'plain', - 'function': {'type': 'general', 'function': lambda v, info: f'{v}-1'}, - } + {'type': 'function-plain', 'function': {'type': 'general', 'function': lambda v, info: f'{v}-1'}} ], } ) @@ -177,7 +143,7 @@ def f(input_value, info): 'return_fields_set': True, 'fields': {'field_a': {'schema': {'type': 'str'}}}, }, - {'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f}}, + {'type': 'function-plain', 'function': {'type': 'general', 'function': f}}, ], }, } diff --git a/tests/validators/test_definitions.py b/tests/validators/test_definitions.py index abd1e599a..358af3eac 100644 --- a/tests/validators/test_definitions.py +++ b/tests/validators/test_definitions.py @@ -42,7 +42,7 @@ def test_def_error(): ) ) assert exc_info.value.args[0].startswith( - "Invalid Schema:\ndefinitions -> definitions -> 1\n Input tag 'wrong' found using self-schema" + "Invalid Schema:\ndefinitions -> definitions -> 1\n Input tag 'wrong' found using 'type'" ) diff --git a/tests/validators/test_definitions_recursive.py b/tests/validators/test_definitions_recursive.py index 46716e99e..b4460d34e 100644 --- a/tests/validators/test_definitions_recursive.py +++ b/tests/validators/test_definitions_recursive.py @@ -305,8 +305,7 @@ def test_outside_parent(): 'fields': { 'tuple1': { 'schema': { - 'type': 'tuple', - 'mode': 'positional', + 'type': 'tuple-positional', 'items_schema': [{'type': 'int'}, {'type': 'int'}, {'type': 'str'}], 'ref': 'tuple-iis', } @@ -413,8 +412,7 @@ def multiple_tuple_schema() -> SchemaValidator: 'fields': { 'f1': { 'schema': { - 'type': 'tuple', - 'mode': 'positional', + 'type': 'tuple-positional', 'items_schema': [ {'type': 'int'}, {'type': 'nullable', 'schema': {'type': 'definition-ref', 'schema_ref': 't'}}, @@ -517,13 +515,11 @@ def wrap_func(input_value, validator, info): v = SchemaValidator( { - 'type': 'function', + 'type': 'function-wrap', 'ref': 'wrapper', - 'mode': 'wrap', 'function': {'type': 'general', 'function': wrap_func}, 'schema': { - 'type': 'tuple', - 'mode': 'positional', + 'type': 'tuple-positional', 'items_schema': [ {'type': 'int'}, {'type': 'nullable', 'schema': {'type': 'definition-ref', 'schema_ref': 'wrapper'}}, @@ -643,8 +639,7 @@ def f(input_value, info): { 'choices': [ { - 'type': 'function', - 'mode': 'after', + 'type': 'function-after', 'function': {'type': 'general', 'function': f}, 'schema': {'schema_ref': 'root-schema', 'type': 'definition-ref'}, }, @@ -686,8 +681,7 @@ def f(input_value, info): { 'choices': [ { - 'type': 'function', - 'mode': 'before', + 'type': 'function-before', 'function': {'type': 'general', 'function': f}, 'schema': {'schema_ref': 'root-schema', 'type': 'definition-ref'}, } diff --git a/tests/validators/test_frozenset.py b/tests/validators/test_frozenset.py index 4ca92f2d6..bab8797f2 100644 --- a/tests/validators/test_frozenset.py +++ b/tests/validators/test_frozenset.py @@ -277,13 +277,13 @@ def gen(error: bool): [ pytest.param( {1: 10, 2: 20, '3': '30'}.items(), - {'type': 'tuple', 'items_schema': {'type': 'any'}}, + {'type': 'tuple-variable', 'items_schema': {'type': 'any'}}, frozenset(((1, 10), (2, 20), ('3', '30'))), id='Tuple[Any, Any]', ), pytest.param( {1: 10, 2: 20, '3': '30'}.items(), - {'type': 'tuple', 'items_schema': {'type': 'int'}}, + {'type': 'tuple-variable', 'items_schema': {'type': 'int'}}, frozenset(((1, 10), (2, 20), (3, 30))), id='Tuple[int, int]', ), diff --git a/tests/validators/test_function.py b/tests/validators/test_function.py index 8f086946a..e76bbcbd6 100644 --- a/tests/validators/test_function.py +++ b/tests/validators/test_function.py @@ -24,12 +24,7 @@ def f(input_value, info): return input_value + ' Changed' v = SchemaValidator( - { - 'type': 'function', - 'mode': 'before', - 'function': {'type': 'general', 'function': f}, - 'schema': {'type': 'str'}, - } + {'type': 'function-before', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) assert v.validate_python('input value') == 'input value Changed' @@ -40,12 +35,7 @@ def f(input_value, info): raise ValueError('foobar') v = SchemaValidator( - { - 'type': 'function', - 'mode': 'before', - 'function': {'type': 'general', 'function': f}, - 'schema': {'type': 'str'}, - } + {'type': 'function-before', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) with pytest.raises(ValidationError) as exc_info: @@ -68,8 +58,7 @@ def my_function(input_value, info): v = SchemaValidator( { - 'type': 'function', - 'mode': 'before', + 'type': 'function-before', 'function': {'type': 'general', 'function': my_function}, 'schema': {'type': 'str', 'max_length': 5}, } @@ -98,8 +87,7 @@ def f(input_value, info): v = SchemaValidator( { - 'type': 'function', - 'mode': 'before', + 'type': 'function-before', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'typed-dict', 'fields': {'my_field': {'schema': {'type': 'str', 'max_length': 5}}}}, } @@ -124,7 +112,7 @@ def f(input_value, validator, info): return validator(input_value=input_value) + ' Changed' v = SchemaValidator( - {'type': 'function', 'mode': 'wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} + {'type': 'function-wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) assert v.validate_python('input value') == 'input value Changed' @@ -136,7 +124,7 @@ def f(input_value, validator, info): return plain_repr(validator) v = SchemaValidator( - {'type': 'function', 'mode': 'wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} + {'type': 'function-wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) assert v.validate_python('input value') == 'ValidatorCallable(Str(StrValidator{strict:false}))' @@ -147,7 +135,7 @@ def f(input_value, validator, info): return plain_repr(validator) v = SchemaValidator( - {'type': 'function', 'mode': 'wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} + {'type': 'function-wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) assert v.validate_python('input value') == 'ValidatorCallable(Str(StrValidator{strict:false}))' @@ -158,16 +146,11 @@ def test_function_wrap_not_callable(): SchemaError, match='function-wrap -> function -> typed-dict -> function\n Input should be callable' ): SchemaValidator( - { - 'type': 'function', - 'mode': 'wrap', - 'function': {'type': 'general', 'function': []}, - 'schema': {'type': 'str'}, - } + {'type': 'function-wrap', 'function': {'type': 'general', 'function': []}, 'schema': {'type': 'str'}} ) with pytest.raises(SchemaError, match='function-wrap -> function\n Field required'): - SchemaValidator({'type': 'function', 'mode': 'wrap', 'schema': {'type': 'str'}}) + SchemaValidator({'type': 'function-wrap', 'schema': {'type': 'str'}}) def test_wrap_error(): @@ -180,7 +163,7 @@ def f(input_value, validator, info): raise e v = SchemaValidator( - {'type': 'function', 'mode': 'wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'int'}} + {'type': 'function-wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'int'}} ) assert v.validate_python('42') == 84 @@ -201,7 +184,7 @@ def f(input_value, validator, info): return validator(input_value, outer_location='foo') + 2 v = SchemaValidator( - {'type': 'function', 'mode': 'wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'int'}} + {'type': 'function-wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'int'}} ) assert v.validate_python(4) == 6 @@ -223,18 +206,13 @@ def f(input_value, validator, info): return validator(input_value, ('4',)) + 2 v = SchemaValidator( - {'type': 'function', 'mode': 'wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'int'}} + {'type': 'function-wrap', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'int'}} ) with pytest.raises(TypeError, match='^ValidatorCallable outer_location must be a str or int$'): v.validate_python(4) -def test_wrong_mode(): - with pytest.raises(SchemaError, match=r"function -> mode\s+Input should be 'before' or 'after'"): - SchemaValidator({'type': 'function', 'mode': 'foobar', 'schema': {'type': 'str'}}) - - def test_function_after_config(): f_kwargs = None @@ -249,8 +227,7 @@ def f(input_value, info): 'fields': { 'test_field': { 'schema': { - 'type': 'function', - 'mode': 'after', + 'type': 'function-after', 'function': {'type': 'field', 'function': f}, 'schema': {'type': 'str'}, } @@ -278,7 +255,7 @@ def f(input_value, info: core_schema.ValidationInfo): return input_value + ' Changed' v = SchemaValidator( - {'type': 'function', 'mode': 'after', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} + {'type': 'function-after', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) assert v.validate_python(b'abc') == 'abc Changed' @@ -289,7 +266,7 @@ def test_function_plain(): def f(input_value, info): return input_value * 2 - v = SchemaValidator({'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f}}) + v = SchemaValidator({'type': 'function-plain', 'function': {'type': 'general', 'function': f}}) assert v.validate_python(1) == 2 assert v.validate_python('x') == 'xx' @@ -299,8 +276,7 @@ def test_plain_with_schema(): with pytest.raises(SchemaError, match='function-plain -> schema\n Extra inputs are not permitted'): SchemaValidator( { - 'type': 'function', - 'mode': 'plain', + 'type': 'function-plain', 'function': {'type': 'general', 'function': lambda x: x}, 'schema': {'type': 'str'}, } @@ -314,8 +290,7 @@ def f(input_value, info): v = SchemaValidator( { - 'type': 'function', - 'mode': 'after', + 'type': 'function-after', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'typed-dict', 'fields': {'field_a': {'schema': {'type': 'str'}}}}, } @@ -331,12 +306,7 @@ def f(input_value): return input_value + ' Changed' v = SchemaValidator( - { - 'type': 'function', - 'mode': 'before', - 'function': {'type': 'general', 'function': f}, - 'schema': {'type': 'str'}, - } + {'type': 'function-before', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) # exception messages differ between python and pypy @@ -362,8 +332,7 @@ def __validate__(cls, input_value, info): v = SchemaValidator( { - 'type': 'function', - 'mode': 'after', + 'type': 'function-after', 'function': {'type': 'general', 'function': Foobar.__validate__}, 'schema': {'type': 'str'}, } @@ -390,12 +359,7 @@ def f(input_value, info): raise AssertionError('foobar') v = SchemaValidator( - { - 'type': 'function', - 'mode': 'before', - 'function': {'type': 'general', 'function': f}, - 'schema': {'type': 'str'}, - } + {'type': 'function-before', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) with pytest.raises(ValidationError) as exc_info: @@ -417,12 +381,7 @@ def f(input_value, info): raise AssertionError v = SchemaValidator( - { - 'type': 'function', - 'mode': 'before', - 'function': {'type': 'general', 'function': f}, - 'schema': {'type': 'str'}, - } + {'type': 'function-before', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) with pytest.raises(ValidationError) as exc_info: @@ -449,12 +408,7 @@ def f(input_value, info): raise MyError() v = SchemaValidator( - { - 'type': 'function', - 'mode': 'before', - 'function': {'type': 'general', 'function': f}, - 'schema': {'type': 'str'}, - } + {'type': 'function-before', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) with pytest.raises(RuntimeError, match='internal error'): @@ -466,12 +420,7 @@ def f(input_value, info): raise TypeError('foobar') v = SchemaValidator( - { - 'type': 'function', - 'mode': 'before', - 'function': {'type': 'general', 'function': f}, - 'schema': {'type': 'str'}, - } + {'type': 'function-before', 'function': {'type': 'general', 'function': f}, 'schema': {'type': 'str'}} ) with pytest.raises(TypeError, match='^foobar$'): @@ -709,7 +658,7 @@ def test_method_function_no_model(): def f(*args: Any, **kwargs: Any) -> Any: # pragma: no cover raise AssertionError('Should not be called') - v = SchemaValidator({'type': 'function', 'mode': 'plain', 'function': {'type': 'field', 'function': f}}) + v = SchemaValidator({'type': 'function-plain', 'function': {'type': 'field', 'function': f}}) with pytest.raises( RuntimeError, diff --git a/tests/validators/test_list.py b/tests/validators/test_list.py index 89fb2eb56..aaf8c10fa 100644 --- a/tests/validators/test_list.py +++ b/tests/validators/test_list.py @@ -207,10 +207,7 @@ def f(input_value, info): return input_value * 2 v = SchemaValidator( - { - 'type': 'list', - 'items_schema': {'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f}}, - } + {'type': 'list', 'items_schema': {'type': 'function-plain', 'function': {'type': 'general', 'function': f}}} ) assert v.validate_python([1, 2, 3]) == [2, 4, 6] @@ -221,10 +218,7 @@ def f(input_value, info): raise ValueError(f'error {input_value}') v = SchemaValidator( - { - 'type': 'list', - 'items_schema': {'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f}}, - } + {'type': 'list', 'items_schema': {'type': 'function-plain', 'function': {'type': 'general', 'function': f}}} ) with pytest.raises(ValidationError) as exc_info: @@ -240,10 +234,7 @@ def f(input_value, info): raise RuntimeError(f'error {input_value}') v = SchemaValidator( - { - 'type': 'list', - 'items_schema': {'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f}}, - } + {'type': 'list', 'items_schema': {'type': 'function-plain', 'function': {'type': 'general', 'function': f}}} ) with pytest.raises(RuntimeError, match='^error 1$') as exc_info: @@ -279,13 +270,13 @@ def gen(error: bool): [ pytest.param( {1: 10, 2: 20, '3': '30'}.items(), - {'type': 'tuple', 'items_schema': {'type': 'any'}}, + {'type': 'tuple-variable', 'items_schema': {'type': 'any'}}, [(1, 10), (2, 20), ('3', '30')], id='Tuple[Any, Any]', ), pytest.param( {1: 10, 2: 20, '3': '30'}.items(), - {'type': 'tuple', 'items_schema': {'type': 'int'}}, + {'type': 'tuple-variable', 'items_schema': {'type': 'int'}}, [(1, 10), (2, 20), (3, 30)], id='Tuple[int, int]', ), diff --git a/tests/validators/test_model.py b/tests/validators/test_model.py index 211ce2d72..c76f37dc5 100644 --- a/tests/validators/test_model.py +++ b/tests/validators/test_model.py @@ -93,8 +93,7 @@ def f(input_value, validator, info): v = SchemaValidator( { - 'type': 'function', - 'mode': 'wrap', + 'type': 'function-wrap', 'function': {'type': 'general', 'function': f}, 'schema': { 'type': 'model', @@ -127,8 +126,7 @@ def f(input_value, info): 'type': 'model', 'cls': MyModel, 'schema': { - 'type': 'function', - 'mode': mode, + 'type': f'function-{mode}', 'function': {'type': 'general', 'function': f}, 'schema': { 'type': 'typed-dict', @@ -153,7 +151,7 @@ def f(input_value, info): { 'type': 'model', 'cls': MyModel, - 'schema': {'type': 'function', 'mode': 'plain', 'function': {'type': 'general', 'function': f}}, + 'schema': {'type': 'function-plain', 'function': {'type': 'general', 'function': f}}, } ) assert 'expect_fields_set:false' in plain_repr(v) @@ -253,8 +251,7 @@ def f(input_value, info): 'type': 'model', 'cls': MyModel, 'schema': { - 'type': 'function', - 'mode': 'after', + 'type': 'function-after', 'function': {'type': 'general', 'function': f}, 'schema': { 'type': 'typed-dict', diff --git a/tests/validators/test_set.py b/tests/validators/test_set.py index bd74776ef..6998b9740 100644 --- a/tests/validators/test_set.py +++ b/tests/validators/test_set.py @@ -248,13 +248,13 @@ def gen(error: bool): [ pytest.param( {1: 10, 2: 20, '3': '30'}.items(), - {'type': 'tuple', 'items_schema': {'type': 'any'}}, + {'type': 'tuple-variable', 'items_schema': {'type': 'any'}}, {(1, 10), (2, 20), ('3', '30')}, id='Tuple[Any, Any]', ), pytest.param( {1: 10, 2: 20, '3': '30'}.items(), - {'type': 'tuple', 'items_schema': {'type': 'int'}}, + {'type': 'tuple-variable', 'items_schema': {'type': 'int'}}, {(1, 10), (2, 20), (3, 30)}, id='Tuple[int, int]', ), diff --git a/tests/validators/test_tuple.py b/tests/validators/test_tuple.py index 4ef866d17..6c5737af7 100644 --- a/tests/validators/test_tuple.py +++ b/tests/validators/test_tuple.py @@ -31,7 +31,7 @@ ids=repr, ) def test_tuple_json(py_and_json: PyAndJson, mode, items, input_value, expected): - v = py_and_json({'type': 'tuple', 'mode': mode, 'items_schema': items}) + v = py_and_json({'type': f'tuple-{mode}', 'items_schema': items}) if isinstance(expected, Err): with pytest.raises(ValidationError, match=re.escape(expected.message)): v.validate_test(input_value) @@ -40,7 +40,7 @@ def test_tuple_json(py_and_json: PyAndJson, mode, items, input_value, expected): def test_any_no_copy(): - v = SchemaValidator({'type': 'tuple'}) + v = SchemaValidator({'type': 'tuple-variable'}) input_value = (1, '2', b'3') output = v.validate_python(input_value) assert output == input_value @@ -57,12 +57,12 @@ def test_any_no_copy(): ], ) def test_tuple_strict_passes_with_tuple(mode, items, input_value, expected): - v = SchemaValidator({'type': 'tuple', 'mode': mode, 'items_schema': items, 'strict': True}) + v = SchemaValidator({'type': f'tuple-{mode}', 'items_schema': items, 'strict': True}) assert v.validate_python(input_value) == expected def test_empty_positional_tuple(): - v = SchemaValidator({'type': 'tuple', 'mode': 'positional', 'items_schema': []}) + v = SchemaValidator({'type': 'tuple-positional', 'items_schema': []}) assert v.validate_python(()) == () assert v.validate_python([]) == () with pytest.raises(ValidationError) as exc_info: @@ -85,7 +85,7 @@ def test_empty_positional_tuple(): ) @pytest.mark.parametrize('wrong_coll_type', [list, set, frozenset]) def test_tuple_strict_fails_without_tuple(wrong_coll_type: Type[Any], mode, items): - v = SchemaValidator({'type': 'tuple', 'mode': mode, 'items_schema': items, 'strict': True}) + v = SchemaValidator({'type': f'tuple-{mode}', 'items_schema': items, 'strict': True}) with pytest.raises(ValidationError) as exc_info: v.validate_python(wrong_coll_type([1, 2, '33'])) assert exc_info.value.errors() == [ @@ -124,7 +124,7 @@ def test_tuple_strict_fails_without_tuple(wrong_coll_type: Type[Any], mode, item ids=repr, ) def test_tuple_var_len_kwargs(kwargs: Dict[str, Any], input_value, expected): - v = SchemaValidator({'type': 'tuple', 'mode': 'variable', **kwargs}) + v = SchemaValidator({'type': 'tuple-variable', **kwargs}) if isinstance(expected, Err): with pytest.raises(ValidationError, match=re.escape(expected.message)): v.validate_python(input_value) @@ -150,7 +150,7 @@ def test_tuple_var_len_kwargs(kwargs: Dict[str, Any], input_value, expected): ids=repr, ) def test_tuple_validate(input_value, expected, mode, items): - v = SchemaValidator({'type': 'tuple', 'mode': mode, 'items_schema': items}) + v = SchemaValidator({'type': f'tuple-{mode}', 'items_schema': items}) if isinstance(expected, Err): with pytest.raises(ValidationError, match=re.escape(expected.message)): v.validate_python(input_value) @@ -165,7 +165,7 @@ def test_tuple_validate(input_value, expected, mode, items): 'mode,items', [('variable', {'type': 'int'}), ('positional', [{'type': 'int'}, {'type': 'int'}, {'type': 'int'}])] ) def test_tuple_validate_iterator(mode, items): - v = SchemaValidator({'type': 'tuple', 'mode': mode, 'items_schema': items}) + v = SchemaValidator({'type': f'tuple-{mode}', 'items_schema': items}) assert v.validate_python((x for x in [1, 2, '3'])) == (1, 2, 3) @@ -180,7 +180,7 @@ def test_tuple_validate_iterator(mode, items): ], ) def test_tuple_var_len_errors(input_value, index): - v = SchemaValidator({'type': 'tuple', 'mode': 'variable', 'items_schema': {'type': 'int'}}) + v = SchemaValidator({'type': 'tuple-variable', 'items_schema': {'type': 'int'}}) with pytest.raises(ValidationError) as exc_info: assert v.validate_python(input_value) assert exc_info.value.errors() == [ @@ -208,7 +208,7 @@ def test_tuple_var_len_errors(input_value, index): ], ) def test_tuple_fix_len_errors(input_value, items, index): - v = SchemaValidator({'type': 'tuple', 'mode': 'positional', 'items_schema': items}) + v = SchemaValidator({'type': 'tuple-positional', 'items_schema': items}) with pytest.raises(ValidationError) as exc_info: assert v.validate_python(input_value) assert exc_info.value.errors() == [ @@ -224,8 +224,7 @@ def test_tuple_fix_len_errors(input_value, items, index): def test_multiple_missing(py_and_json: PyAndJson): v = py_and_json( { - 'type': 'tuple', - 'mode': 'positional', + 'type': 'tuple-positional', 'items_schema': [{'type': 'int'}, {'type': 'int'}, {'type': 'int'}, {'type': 'int'}], } ) @@ -243,7 +242,7 @@ def test_multiple_missing(py_and_json: PyAndJson): def test_extra_arguments(py_and_json: PyAndJson): - v = py_and_json({'type': 'tuple', 'mode': 'positional', 'items_schema': [{'type': 'int'}, {'type': 'int'}]}) + v = py_and_json({'type': 'tuple-positional', 'items_schema': [{'type': 'int'}, {'type': 'int'}]}) assert v.validate_test([1, 2]) == (1, 2) with pytest.raises(ValidationError) as exc_info: v.validate_test([1, 2, 3, 4]) @@ -260,7 +259,7 @@ def test_extra_arguments(py_and_json: PyAndJson): def test_positional_empty(py_and_json: PyAndJson): - v = py_and_json({'type': 'tuple', 'mode': 'positional', 'items_schema': []}) + v = py_and_json({'type': 'tuple-positional', 'items_schema': []}) assert v.validate_test([]) == () assert v.validate_python(()) == () with pytest.raises(ValidationError, match='type=too_long,'): @@ -268,7 +267,7 @@ def test_positional_empty(py_and_json: PyAndJson): def test_positional_empty_extra(py_and_json: PyAndJson): - v = py_and_json({'type': 'tuple', 'mode': 'positional', 'items_schema': [], 'extra_schema': {'type': 'int'}}) + v = py_and_json({'type': 'tuple-positional', 'items_schema': [], 'extra_schema': {'type': 'int'}}) assert v.validate_test([]) == () assert v.validate_python(()) == () assert v.validate_test([1]) == (1,) @@ -277,7 +276,7 @@ def test_positional_empty_extra(py_and_json: PyAndJson): @pytest.mark.parametrize('input_value,expected', [((1, 2, 3), (1, 2, 3)), ([1, 2, 3], [1, 2, 3])]) def test_union_tuple_list(input_value, expected): - v = SchemaValidator({'type': 'union', 'choices': [{'type': 'tuple', 'mode': 'variable'}, {'type': 'list'}]}) + v = SchemaValidator({'type': 'union', 'choices': [{'type': 'tuple-variable'}, {'type': 'list'}]}) assert v.validate_python(input_value) == expected @@ -317,8 +316,8 @@ def test_union_tuple_var_len(input_value, expected): { 'type': 'union', 'choices': [ - {'type': 'tuple', 'mode': 'variable', 'items_schema': {'type': 'int'}, 'strict': True}, - {'type': 'tuple', 'mode': 'variable', 'items_schema': {'type': 'str'}, 'strict': True}, + {'type': 'tuple-variable', 'items_schema': {'type': 'int'}, 'strict': True}, + {'type': 'tuple-variable', 'items_schema': {'type': 'str'}, 'strict': True}, ], } ) @@ -365,14 +364,12 @@ def test_union_tuple_fix_len(input_value, expected): 'type': 'union', 'choices': [ { - 'type': 'tuple', - 'mode': 'positional', + 'type': 'tuple-positional', 'items_schema': [{'type': 'int'}, {'type': 'int'}, {'type': 'int'}], 'strict': True, }, { - 'type': 'tuple', - 'mode': 'positional', + 'type': 'tuple-positional', 'items_schema': [{'type': 'str'}, {'type': 'str'}, {'type': 'str'}], 'strict': True, }, @@ -389,7 +386,7 @@ def test_union_tuple_fix_len(input_value, expected): def test_tuple_fix_error(): - v = SchemaValidator({'type': 'tuple', 'mode': 'positional', 'items_schema': [{'type': 'int'}, {'type': 'str'}]}) + v = SchemaValidator({'type': 'tuple-positional', 'items_schema': [{'type': 'int'}, {'type': 'str'}]}) with pytest.raises(ValidationError) as exc_info: v.validate_python([1]) @@ -410,8 +407,7 @@ def test_tuple_fix_error(): def test_tuple_fix_extra(input_value, expected, cache): v = SchemaValidator( { - 'type': 'tuple', - 'mode': 'positional', + 'type': 'tuple-positional', 'items_schema': [{'type': 'int'}, {'type': 'str'}], 'extra_schema': {'type': 'str'}, } @@ -427,7 +423,7 @@ def test_tuple_fix_extra(input_value, expected, cache): def test_tuple_fix_extra_any(): v = SchemaValidator( - {'type': 'tuple', 'mode': 'positional', 'items_schema': [{'type': 'str'}], 'extra_schema': {'type': 'any'}} + {'type': 'tuple-positional', 'items_schema': [{'type': 'str'}], 'extra_schema': {'type': 'any'}} ) assert v.validate_python([b'1']) == ('1',) assert v.validate_python([b'1', 2]) == ('1', 2) @@ -446,7 +442,7 @@ def gen(error: bool): raise RuntimeError('error') yield 3 - v = SchemaValidator({'type': 'tuple', 'items_schema': {'type': 'int'}}) + v = SchemaValidator({'type': 'tuple-variable', 'items_schema': {'type': 'int'}}) assert v.validate_python(gen(False)) == (1, 2, 3) msg = r'Error iterating over object, error: RuntimeError: error \[type=iteration_error,' @@ -459,13 +455,13 @@ def gen(error: bool): [ pytest.param( {1: 10, 2: 20, '3': '30'}.items(), - {'type': 'tuple', 'items_schema': {'type': 'any'}}, + {'type': 'tuple-variable', 'items_schema': {'type': 'any'}}, ((1, 10), (2, 20), ('3', '30')), id='Tuple[Any, Any]', ), pytest.param( {1: 10, 2: 20, '3': '30'}.items(), - {'type': 'tuple', 'items_schema': {'type': 'int'}}, + {'type': 'tuple-variable', 'items_schema': {'type': 'int'}}, ((1, 10), (2, 20), (3, 30)), id='Tuple[int, int]', ), @@ -473,7 +469,7 @@ def gen(error: bool): ], ) def test_frozenset_from_dict_items(input_value, items_schema, expected): - v = SchemaValidator({'type': 'tuple', 'items_schema': items_schema}) + v = SchemaValidator({'type': 'tuple-variable', 'items_schema': items_schema}) output = v.validate_python(input_value) assert isinstance(output, tuple) assert output == expected @@ -490,7 +486,7 @@ def test_frozenset_from_dict_items(input_value, items_schema, expected): def test_length_constraints_omit(input_value, expected): v = SchemaValidator( { - 'type': 'tuple', + 'type': 'tuple-variable', 'items_schema': {'type': 'default', 'schema': {'type': 'int'}, 'on_error': 'omit'}, 'max_length': 4, } diff --git a/tests/validators/test_typed_dict.py b/tests/validators/test_typed_dict.py index 731e3a372..4b321f852 100644 --- a/tests/validators/test_typed_dict.py +++ b/tests/validators/test_typed_dict.py @@ -292,16 +292,14 @@ def func_b(input_value, info): 'fields': { 'field_a': { 'schema': { - 'type': 'function', - 'mode': 'after', + 'type': 'function-after', 'function': {'type': 'general', 'function': func_a}, 'schema': {'type': 'str'}, } }, 'field_b': { 'schema': { - 'type': 'function', - 'mode': 'after', + 'type': 'function-after', 'function': {'type': 'general', 'function': func_b}, 'schema': {'type': 'int'}, } @@ -1397,8 +1395,7 @@ def wrap_function(input_value, validator, info): 'type': 'default', 'on_error': 'raise', 'schema': { - 'type': 'function', - 'mode': 'wrap', + 'type': 'function-wrap', 'function': {'type': 'general', 'function': wrap_function}, 'schema': {'type': 'str'}, }, diff --git a/tests/validators/test_with_default.py b/tests/validators/test_with_default.py index 5730d7fea..928b60a28 100644 --- a/tests/validators/test_with_default.py +++ b/tests/validators/test_with_default.py @@ -143,7 +143,7 @@ def test_dict_keys(): def test_tuple_variable(py_and_json: PyAndJson): v = py_and_json( - {'type': 'tuple', 'items_schema': {'type': 'default', 'schema': {'type': 'int'}, 'on_error': 'omit'}} + {'type': 'tuple-variable', 'items_schema': {'type': 'default', 'schema': {'type': 'int'}, 'on_error': 'omit'}} ) assert v.validate_python((1, 2, 3)) == (1, 2, 3) assert v.validate_python([1, '2', 3]) == (1, 2, 3) @@ -153,8 +153,7 @@ def test_tuple_variable(py_and_json: PyAndJson): def test_tuple_positional(): v = SchemaValidator( { - 'type': 'tuple', - 'mode': 'positional', + 'type': 'tuple-positional', 'items_schema': [{'type': 'int'}, {'type': 'default', 'schema': {'type': 'int'}, 'default': 42}], } ) @@ -167,8 +166,7 @@ def test_tuple_positional(): def test_tuple_positional_omit(): v = SchemaValidator( { - 'type': 'tuple', - 'mode': 'positional', + 'type': 'tuple-positional', 'items_schema': [{'type': 'int'}, {'type': 'int'}], 'extra_schema': {'type': 'default', 'schema': {'type': 'int'}, 'on_error': 'omit'}, }