Skip to content

Commit

Permalink
Rename validation and serialization schema types to be unique
Browse files Browse the repository at this point in the history
`validator-` or `serializer-` is prepended, and the existing
ones are deprecated.
  • Loading branch information
Viicos committed Feb 7, 2025
1 parent db63fec commit ec4e4a1
Show file tree
Hide file tree
Showing 19 changed files with 190 additions and 79 deletions.
40 changes: 20 additions & 20 deletions python/pydantic_core/core_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ def simple_ser_schema(type: ExpectedSerializationTypes) -> SimpleSerSchema:


class PlainSerializerFunctionSerSchema(TypedDict, total=False):
type: Required[Literal['function-plain']]
type: Required[Literal['serializer-function-plain']]
function: Required[SerializerFunction]
is_field_serializer: bool # default False
info_arg: bool # default False
Expand Down Expand Up @@ -292,7 +292,7 @@ def plain_serializer_function_ser_schema(
# just to avoid extra elements in schema, and to use the actual default defined in rust
when_used = None # type: ignore
return _dict_not_none(
type='function-plain',
type='serializer-function-plain',
function=function,
is_field_serializer=is_field_serializer,
info_arg=info_arg,
Expand Down Expand Up @@ -322,7 +322,7 @@ def __call__(self, input_value: Any, index_key: int | str | None = None, /) -> A


class WrapSerializerFunctionSerSchema(TypedDict, total=False):
type: Required[Literal['function-wrap']]
type: Required[Literal['serializer-function-wrap']]
function: Required[WrapSerializerFunction]
is_field_serializer: bool # default False
info_arg: bool # default False
Expand Down Expand Up @@ -356,7 +356,7 @@ def wrap_serializer_function_ser_schema(
# just to avoid extra elements in schema, and to use the actual default defined in rust
when_used = None # type: ignore
return _dict_not_none(
type='function-wrap',
type='serializer-function-wrap',
function=function,
is_field_serializer=is_field_serializer,
info_arg=info_arg,
Expand Down Expand Up @@ -1966,7 +1966,7 @@ class _ValidatorFunctionSchema(TypedDict, total=False):


class BeforeValidatorFunctionSchema(_ValidatorFunctionSchema, total=False):
type: Required[Literal['function-before']]
type: Required[Literal['validator-function-before']]
json_schema_input_schema: CoreSchema


Expand Down Expand Up @@ -2006,7 +2006,7 @@ def fn(v: bytes) -> str:
serialization: Custom serialization schema
"""
return _dict_not_none(
type='function-before',
type='validator-function-before',
function={'type': 'no-info', 'function': function},
schema=schema,
ref=ref,
Expand Down Expand Up @@ -2057,7 +2057,7 @@ def fn(v: bytes, info: core_schema.ValidationInfo) -> str:
serialization: Custom serialization schema
"""
return _dict_not_none(
type='function-before',
type='validator-function-before',
function=_dict_not_none(type='with-info', function=function, field_name=field_name),
schema=schema,
ref=ref,
Expand All @@ -2068,7 +2068,7 @@ def fn(v: bytes, info: core_schema.ValidationInfo) -> str:


class AfterValidatorFunctionSchema(_ValidatorFunctionSchema, total=False):
type: Required[Literal['function-after']]
type: Required[Literal['validator-function-after']]


def no_info_after_validator_function(
Expand Down Expand Up @@ -2105,7 +2105,7 @@ def fn(v: str) -> str:
serialization: Custom serialization schema
"""
return _dict_not_none(
type='function-after',
type='validator-function-after',
function={'type': 'no-info', 'function': function},
schema=schema,
ref=ref,
Expand Down Expand Up @@ -2154,7 +2154,7 @@ def fn(v: str, info: core_schema.ValidationInfo) -> str:
serialization: Custom serialization schema
"""
return _dict_not_none(
type='function-after',
type='validator-function-after',
function=_dict_not_none(type='with-info', function=function, field_name=field_name),
schema=schema,
ref=ref,
Expand Down Expand Up @@ -2191,7 +2191,7 @@ class WithInfoWrapValidatorFunctionSchema(TypedDict, total=False):


class WrapValidatorFunctionSchema(TypedDict, total=False):
type: Required[Literal['function-wrap']]
type: Required[Literal['validator-function-wrap']]
function: Required[WrapValidatorFunction]
schema: Required[CoreSchema]
ref: str
Expand Down Expand Up @@ -2239,7 +2239,7 @@ def fn(
serialization: Custom serialization schema
"""
return _dict_not_none(
type='function-wrap',
type='validator-function-wrap',
function={'type': 'no-info', 'function': function},
schema=schema,
json_schema_input_schema=json_schema_input_schema,
Expand Down Expand Up @@ -2291,7 +2291,7 @@ def fn(
serialization: Custom serialization schema
"""
return _dict_not_none(
type='function-wrap',
type='validator-function-wrap',
function=_dict_not_none(type='with-info', function=function, field_name=field_name),
schema=schema,
json_schema_input_schema=json_schema_input_schema,
Expand All @@ -2302,7 +2302,7 @@ def fn(


class PlainValidatorFunctionSchema(TypedDict, total=False):
type: Required[Literal['function-plain']]
type: Required[Literal['validator-function-plain']]
function: Required[ValidationFunction]
ref: str
json_schema_input_schema: CoreSchema
Expand Down Expand Up @@ -2341,7 +2341,7 @@ def fn(v: str) -> str:
serialization: Custom serialization schema
"""
return _dict_not_none(
type='function-plain',
type='validator-function-plain',
function={'type': 'no-info', 'function': function},
ref=ref,
json_schema_input_schema=json_schema_input_schema,
Expand Down Expand Up @@ -2383,7 +2383,7 @@ def fn(v: str, info: core_schema.ValidationInfo) -> str:
serialization: Custom serialization schema
"""
return _dict_not_none(
type='function-plain',
type='validator-function-plain',
function=_dict_not_none(type='with-info', function=function, field_name=field_name),
ref=ref,
json_schema_input_schema=json_schema_input_schema,
Expand Down Expand Up @@ -3965,10 +3965,10 @@ def definition_reference_schema(
'frozenset',
'generator',
'dict',
'function-after',
'function-before',
'function-wrap',
'function-plain',
'validator-function-after',
'validator-function-before',
'validator-function-wrap',
'validator-function-plain',
'default',
'nullable',
'union',
Expand Down
45 changes: 38 additions & 7 deletions src/serializers/shared.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::borrow::Cow;
use std::ffi::CString;
use std::fmt::Debug;

use pyo3::exceptions::PyTypeError;
Expand Down Expand Up @@ -148,6 +149,29 @@ combined_serializer! {
}
}

fn get_new_type(py: Python, type_: &str) -> PyResult<String> {
let maybe_new_type = match type_ {
"function-plain" => Some("serializer-function-plain"),
"function-wrap" => Some("serializer-function-wrap"),
_ => None,
};

match maybe_new_type {
Some(new_type) => {
let deprecation_message =
format!("Serialization core schema type '{type_}' is deprecated, use '{new_type}'");
let _ = PyErr::warn(
py,
&py.get_type::<pyo3::exceptions::PyDeprecationWarning>(),
&CString::new(deprecation_message)?,
1,
);
Ok(new_type.to_owned())
}
None => Ok(type_.to_owned()),
}
}

impl CombinedSerializer {
fn _build(
schema: &Bound<'_, PyDict>,
Expand All @@ -159,28 +183,35 @@ impl CombinedSerializer {

if let Some(ser_schema) = schema.get_as::<Bound<'_, PyDict>>(intern!(py, "serialization"))? {
let op_ser_type: Option<Bound<'_, PyString>> = ser_schema.get_as(type_key)?;
match op_ser_type.as_ref().map(|py_str| py_str.to_str()).transpose()? {
Some("function-plain") => {
// `function-plain` is a special case, not included in `find_serializer` since it means
let op_ser_type = op_ser_type.as_ref().map(|py_str| py_str.to_str()).transpose()?;
let new_type = op_ser_type.map(|typ| get_new_type(schema.py(), typ).unwrap());

match new_type.as_deref() {
Some("serializer-function-plain") => {
// `serializer-function-plain` is a special case, not included in `find_serializer` since it means
// something different in `schema.type`
// NOTE! we use the `schema` here, not `ser_schema`
return super::type_serializers::function::FunctionPlainSerializer::build(
schema,
config,
definitions,
)
.map_err(|err| py_schema_error_type!("Error building `function-plain` serializer:\n {}", err));
.map_err(|err| {
py_schema_error_type!("Error building `serializer-function-plain` serializer:\n {}", err)
});
}
Some("function-wrap") => {
// `function-wrap` is also a special case, not included in `find_serializer` since it mean
Some("serializer-function-wrap") => {
// `serializer-function-wrap` is also a special case, not included in `find_serializer` since it mean
// something different in `schema.type`
// NOTE! we use the `schema` here, not `ser_schema`
return super::type_serializers::function::FunctionWrapSerializer::build(
schema,
config,
definitions,
)
.map_err(|err| py_schema_error_type!("Error building `function-wrap` serializer:\n {}", err));
.map_err(|err| {
py_schema_error_type!("Error building `serializer-function-wrap` serializer:\n {}", err)
});
}
// applies to lists tuples and dicts, does not override the main schema `type`
Some("include-exclude-sequence" | "include-exclude-dict") => (),
Expand Down
12 changes: 6 additions & 6 deletions src/serializers/type_serializers/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl BuildSerializer for FunctionAfterSerializerBuilder {
pub struct FunctionPlainSerializerBuilder;

impl BuildSerializer for FunctionPlainSerializerBuilder {
const EXPECTED_TYPE: &'static str = "function-plain";
const EXPECTED_TYPE: &'static str = "serializer-function-plain";
fn build(
schema: &Bound<'_, PyDict>,
config: Option<&Bound<'_, PyDict>>,
Expand Down Expand Up @@ -95,7 +95,7 @@ fn destructure_function_schema<'py>(schema: &Bound<'py, PyDict>) -> PyResult<(bo
}

impl BuildSerializer for FunctionPlainSerializer {
const EXPECTED_TYPE: &'static str = "function-plain";
const EXPECTED_TYPE: &'static str = "serializer-function-plain";

/// NOTE! `schema` here is the actual `CoreSchema`, not `schema.serialization` as in the other builders
/// (done this way to match `FunctionWrapSerializer` which requires the full schema)
Expand Down Expand Up @@ -125,7 +125,7 @@ impl BuildSerializer for FunctionPlainSerializer {
}
};

let name = format!("plain_function[{function_name}]");
let name = format!("serializer-function-plain[{function_name}]");
Ok(Self {
func: function.unbind(),
function_name,
Expand Down Expand Up @@ -310,7 +310,7 @@ fn copy_outer_schema<'py>(schema: &Bound<'py, PyDict>) -> PyResult<Bound<'py, Py
pub struct FunctionWrapSerializerBuilder;

impl BuildSerializer for FunctionWrapSerializerBuilder {
const EXPECTED_TYPE: &'static str = "function-wrap";
const EXPECTED_TYPE: &'static str = "serializer-function-wrap";
fn build(
schema: &Bound<'_, PyDict>,
config: Option<&Bound<'_, PyDict>>,
Expand Down Expand Up @@ -339,7 +339,7 @@ pub struct FunctionWrapSerializer {
}

impl BuildSerializer for FunctionWrapSerializer {
const EXPECTED_TYPE: &'static str = "function-wrap";
const EXPECTED_TYPE: &'static str = "serializer-function-wrap";

/// NOTE! `schema` here is the actual `CoreSchema`, not `schema.serialization` as in the other builders
/// (done this way since we need the `CoreSchema`)
Expand Down Expand Up @@ -368,7 +368,7 @@ impl BuildSerializer for FunctionWrapSerializer {
None => AnySerializer::build(schema, config, definitions)?,
};

let name = format!("wrap_function[{function_name}, {}]", serializer.get_name());
let name = format!("serializer-function-wrap[{function_name}, {}]", serializer.get_name());
Ok(Self {
serializer: Arc::new(serializer),
func: function.into(),
Expand Down
18 changes: 12 additions & 6 deletions src/validators/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub struct FunctionBeforeValidator {
info_arg: bool,
}

impl_build!(FunctionBeforeValidator, "function-before");
impl_build!(FunctionBeforeValidator, "validator-function-before");

impl FunctionBeforeValidator {
fn _validate<'s, 'py>(
Expand Down Expand Up @@ -157,7 +157,7 @@ pub struct FunctionAfterValidator {
info_arg: bool,
}

impl_build!(FunctionAfterValidator, "function-after");
impl_build!(FunctionAfterValidator, "validator-function-after");

impl FunctionAfterValidator {
fn _validate<'py, I: Input<'py> + ?Sized>(
Expand Down Expand Up @@ -225,7 +225,7 @@ pub struct FunctionPlainValidator {
}

impl BuildValidator for FunctionPlainValidator {
const EXPECTED_TYPE: &'static str = "function-plain";
const EXPECTED_TYPE: &'static str = "validator-function-plain";

fn build(
schema: &Bound<'_, PyDict>,
Expand All @@ -240,7 +240,10 @@ impl BuildValidator for FunctionPlainValidator {
Some(c) => c.clone().into(),
None => py.None(),
},
name: format!("function-plain[{}()]", function_name(function_info.function.bind(py))?),
name: format!(
"validator-function-plain[{}()]",
function_name(function_info.function.bind(py))?
),
field_name: function_info.field_name.clone(),
info_arg: function_info.info_arg,
}
Expand Down Expand Up @@ -284,7 +287,7 @@ pub struct FunctionWrapValidator {
}

impl BuildValidator for FunctionWrapValidator {
const EXPECTED_TYPE: &'static str = "function-wrap";
const EXPECTED_TYPE: &'static str = "validator-function-wrap";

fn build(
schema: &Bound<'_, PyDict>,
Expand All @@ -303,7 +306,10 @@ impl BuildValidator for FunctionWrapValidator {
Some(c) => c.clone().into(),
None => py.None(),
},
name: format!("function-wrap[{}()]", function_name(function_info.function.bind(py))?),
name: format!(
"validator-function-wrap[{}()]",
function_name(function_info.function.bind(py))?
),
field_name: function_info.field_name.clone(),
info_arg: function_info.info_arg,
hide_input_in_errors,
Expand Down
Loading

0 comments on commit ec4e4a1

Please sign in to comment.