Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-pydantic for openSUSE:Factory checked in at 2025-06-24 20:46:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pydantic (Old) and /work/SRC/openSUSE:Factory/.python-pydantic.new.7067 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pydantic" Tue Jun 24 20:46:02 2025 rev:33 rq:1287850 version:2.11.7 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pydantic/python-pydantic.changes 2025-04-25 22:18:02.100323188 +0200 +++ /work/SRC/openSUSE:Factory/.python-pydantic.new.7067/python-pydantic.changes 2025-06-24 20:46:28.645659232 +0200 @@ -1,0 +2,35 @@ +Mon Jun 23 05:56:23 UTC 2025 - Daniel Garcia <daniel.gar...@suse.com> + +- Add patch bump-pydantic-core-2.35.1.patch to support latest + pydantic-core, gh#pydantic/pydantic#11963 +- Add patch field-name-validator-core-schemas.patch to remove + deprecation warning, gh#pydantic/pydantic#11761 +- Update to 2.11.7 + * Copy FieldInfo instance if necessary during FieldInfo build by @Viicos in #11980 +2.11.6 + * Rebuild dataclass fields before schema generation by @Viicos in #11949 + * Always store the original field assignment on FieldInfo by @Viicos in #11946 +2.11.5 + * Check if FieldInfo is complete after applying type variable map by @Viicos in #11855 + * Do not delete mock validator/serializer in model_rebuild() by @Viicos in #11890 + * Do not duplicate metadata on model rebuild by @Viicos in #11902 + +------------------------------------------------------------------- +Mon May 5 08:19:26 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- Update to 2.11.4 + * Bump mkdocs-llmstxt to v0.2.0 + * Allow config and bases to be specified together in create_model() + * This change was backported as it was previously possible + (although not meant to be supported) + * To provide model_config as a field, which would make it + possible to provide both configuration and bases. + * Remove generics cache workaround + * Remove coercion of decimal constraints + * Fix crash when expanding root type in the mypy plugin + * Fix issue with recursive generic models + * Traverse function-before schemas during schema gathering +- Drop field_name.patch, merged upstream +- Update BuildRequires and Requires from pyproject.toml + +------------------------------------------------------------------- Old: ---- field_name.patch pydantic-2.11.3.tar.gz New: ---- bump-pydantic-core-2.35.1.patch field-name-validator-core-schemas.patch pydantic-2.11.7.tar.gz ----------(Old B)---------- Old: * Traverse function-before schemas during schema gathering - Drop field_name.patch, merged upstream - Update BuildRequires and Requires from pyproject.toml ----------(Old E)---------- ----------(New B)---------- New: - Add patch bump-pydantic-core-2.35.1.patch to support latest pydantic-core, gh#pydantic/pydantic#11963 New: pydantic-core, gh#pydantic/pydantic#11963 - Add patch field-name-validator-core-schemas.patch to remove deprecation warning, gh#pydantic/pydantic#11761 ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pydantic.spec ++++++ --- /var/tmp/diff_new_pack.WsT13W/_old 2025-06-24 20:46:31.293769015 +0200 +++ /var/tmp/diff_new_pack.WsT13W/_new 2025-06-24 20:46:31.309769678 +0200 @@ -27,19 +27,21 @@ %endif %{?sle15_python_module_pythons} Name: python-pydantic%{psuffix} -Version: 2.11.3 +Version: 2.11.7 Release: 0 Summary: Data validation and settings management using python type hinting License: MIT URL: https://github.com/pydantic/pydantic Source: https://github.com/pydantic/pydantic/archive/v%{version}.tar.gz#/pydantic-%{version}.tar.gz -# PATCH-FIX-UPSTREAM https://github.com/pydantic/pydantic/commit/bce81efdeac1cbefd0196b478a32aa2586bd595a Do not provide field_name in validator core schemas -Patch: field_name.patch +# PATCH-FIX-UPSTREAM bump-pydantic-core-2.35.1.patch gh#pydantic/pydantic#11963 +Patch0: bump-pydantic-core-2.35.1.patch +# PATCH-FIX-UPSTREAM field-name-validator-core-schemas.patch gh#pydantic/pydantic#11761 +Patch1: field-name-validator-core-schemas.patch BuildRequires: %{python_module hatch-fancy-pypi-readme} BuildRequires: %{python_module hatchling} BuildRequires: %{python_module packaging} BuildRequires: %{python_module pip} -BuildRequires: %{python_module pydantic-core >= 2.33.1} +BuildRequires: %{python_module pydantic-core = 2.35.1} BuildRequires: %{python_module wheel} BuildRequires: fdupes BuildRequires: python-rpm-macros @@ -63,7 +65,7 @@ %if 0%{?python_version_nodots} < 310 Requires: python-eval-type-backport %endif -Requires: python-pydantic-core >= 2.27.2 +Requires: python-pydantic-core = 2.35.1 Requires: python-typing-extensions >= 4.12.2 Requires: python-typing-inspection BuildArch: noarch ++++++ bump-pydantic-core-2.35.1.patch ++++++ >From 4494c31a4834bdc2301cfa3d94f4bbc62c2774dc Mon Sep 17 00:00:00 2001 From: Viicos <65306057+vii...@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:52:26 +0200 Subject: [PATCH] Bump `pydantic-core` to v2.35.1 Make use of `ensure_ascii` option Update typechecking tests Remove core schema validation hook --- docs/api/standard_library_types.md | 2 +- docs/why.md | 2 +- pydantic/_internal/_core_utils.py | 8 - pydantic/_internal/_generate_schema.py | 5 +- pydantic/functional_serializers.py | 4 +- pydantic/functional_validators.py | 10 +- pydantic/main.py | 4 + pydantic/type_adapter.py | 3 + pydantic/version.py | 2 +- pyproject.toml | 4 +- tests/typechecking/decorators.py | 79 +++++++-- 12 files changed, 203 insertions(+), 140 deletions(-) Index: pydantic-2.11.7/docs/api/standard_library_types.md =================================================================== --- pydantic-2.11.7.orig/docs/api/standard_library_types.md +++ pydantic-2.11.7/docs/api/standard_library_types.md @@ -81,7 +81,7 @@ event = Event(dt='2032-04-23T10:20:30.40 print(event.model_dump()) """ -{'dt': datetime.datetime(2032, 4, 23, 10, 20, 30, 400000, tzinfo=TzInfo(+02:30))} +{'dt': datetime.datetime(2032, 4, 23, 10, 20, 30, 400000, tzinfo=TzInfo(9000))} """ ``` Index: pydantic-2.11.7/docs/why.md =================================================================== --- pydantic-2.11.7.orig/docs/why.md +++ pydantic-2.11.7/docs/why.md @@ -363,7 +363,7 @@ Functional validators and serializers, a print(Meeting(when='2020-01-01T12:00+01:00')) - #> when=datetime.datetime(2020, 1, 1, 12, 0, tzinfo=TzInfo(+01:00)) + #> when=datetime.datetime(2020, 1, 1, 12, 0, tzinfo=TzInfo(3600)) print(Meeting(when='now')) #> when=datetime.datetime(2032, 1, 2, 3, 4, 5, 6) print(Meeting(when='2020-01-01T12:00')) Index: pydantic-2.11.7/pydantic/_internal/_core_utils.py =================================================================== --- pydantic-2.11.7.orig/pydantic/_internal/_core_utils.py +++ pydantic-2.11.7/pydantic/_internal/_core_utils.py @@ -1,12 +1,10 @@ from __future__ import annotations import inspect -import os from collections.abc import Mapping, Sequence from typing import TYPE_CHECKING, Any, Union from pydantic_core import CoreSchema, core_schema -from pydantic_core import validate_core_schema as _validate_core_schema from typing_extensions import TypeGuard, get_args, get_origin from typing_inspection import typing_objects @@ -109,12 +107,6 @@ def get_ref(s: core_schema.CoreSchema) - return s.get('ref', None) -def validate_core_schema(schema: CoreSchema) -> CoreSchema: - if os.getenv('PYDANTIC_VALIDATE_CORE_SCHEMAS'): - return _validate_core_schema(schema) - return schema - - def _clean_schema_for_pretty_print(obj: Any, strip_metadata: bool = True) -> Any: # pragma: no cover """A utility function to remove irrelevant information from a core schema.""" if isinstance(obj, Mapping): Index: pydantic-2.11.7/pydantic/_internal/_generate_schema.py =================================================================== --- pydantic-2.11.7.orig/pydantic/_internal/_generate_schema.py +++ pydantic-2.11.7/pydantic/_internal/_generate_schema.py @@ -70,7 +70,6 @@ from ._core_utils import ( get_ref, get_type_ref, is_list_like_schema_with_items_schema, - validate_core_schema, ) from ._decorators import ( Decorator, @@ -666,9 +665,7 @@ class GenerateSchema: return schema def clean_schema(self, schema: CoreSchema) -> CoreSchema: - schema = self.defs.finalize_schema(schema) - schema = validate_core_schema(schema) - return schema + return self.defs.finalize_schema(schema) def _add_js_function(self, metadata_schema: CoreSchema, js_function: Callable[..., Any]) -> None: metadata = metadata_schema.get('metadata', {}) Index: pydantic-2.11.7/pydantic/functional_serializers.py =================================================================== --- pydantic-2.11.7.orig/pydantic/functional_serializers.py +++ pydantic-2.11.7/pydantic/functional_serializers.py @@ -300,7 +300,7 @@ def field_serializer( if TYPE_CHECKING: # The first argument in the following callables represent the `self` type: - ModelPlainSerializerWithInfo: TypeAlias = Callable[[Any, SerializationInfo], Any] + ModelPlainSerializerWithInfo: TypeAlias = Callable[[Any, SerializationInfo[Any]], Any] """A model serializer method with the `info` argument, in `plain` mode.""" ModelPlainSerializerWithoutInfo: TypeAlias = Callable[[Any], Any] @@ -309,7 +309,7 @@ if TYPE_CHECKING: ModelPlainSerializer: TypeAlias = 'ModelPlainSerializerWithInfo | ModelPlainSerializerWithoutInfo' """A model serializer method in `plain` mode.""" - ModelWrapSerializerWithInfo: TypeAlias = Callable[[Any, SerializerFunctionWrapHandler, SerializationInfo], Any] + ModelWrapSerializerWithInfo: TypeAlias = Callable[[Any, SerializerFunctionWrapHandler, SerializationInfo[Any]], Any] """A model serializer method with the `info` argument, in `wrap` mode.""" ModelWrapSerializerWithoutInfo: TypeAlias = Callable[[Any, SerializerFunctionWrapHandler], Any] Index: pydantic-2.11.7/pydantic/functional_validators.py =================================================================== --- pydantic-2.11.7.orig/pydantic/functional_validators.py +++ pydantic-2.11.7/pydantic/functional_validators.py @@ -332,7 +332,7 @@ if TYPE_CHECKING: def __call__(self, cls: Any, value: Any, /) -> Any: ... class _V2ValidatorClsMethod(Protocol): - def __call__(self, cls: Any, value: Any, info: _core_schema.ValidationInfo, /) -> Any: ... + def __call__(self, cls: Any, value: Any, info: core_schema.ValidationInfo[Any], /) -> Any: ... class _OnlyValueWrapValidatorClsMethod(Protocol): def __call__(self, cls: Any, value: Any, handler: _core_schema.ValidatorFunctionWrapHandler, /) -> Any: ... @@ -343,7 +343,7 @@ if TYPE_CHECKING: cls: Any, value: Any, handler: _core_schema.ValidatorFunctionWrapHandler, - info: _core_schema.ValidationInfo, + info: core_schema.ValidationInfo[Any], /, ) -> Any: ... @@ -559,7 +559,7 @@ class ModelWrapValidator(Protocol[_Model # thus validators _must_ handle all cases value: Any, handler: ModelWrapValidatorHandler[_ModelType], - info: _core_schema.ValidationInfo, + info: core_schema.ValidationInfo[Any], /, ) -> _ModelType: ... @@ -604,7 +604,7 @@ class FreeModelBeforeValidator(Protocol) # or anything else that gets passed to validate_python # thus validators _must_ handle all cases value: Any, - info: _core_schema.ValidationInfo, + info: core_schema.ValidationInfo[Any], /, ) -> Any: ... @@ -619,7 +619,7 @@ class ModelBeforeValidator(Protocol): # or anything else that gets passed to validate_python # thus validators _must_ handle all cases value: Any, - info: _core_schema.ValidationInfo, + info: core_schema.ValidationInfo[Any], /, ) -> Any: ... @@ -629,7 +629,7 @@ ModelAfterValidatorWithoutInfo = Callabl have info argument. """ -ModelAfterValidator = Callable[[_ModelType, _core_schema.ValidationInfo], _ModelType] +ModelAfterValidator = Callable[[_ModelType, core_schema.ValidationInfo[Any]], _ModelType] """A `@model_validator` decorated function signature. This is used when `mode='after'`.""" _AnyModelWrapValidator = Union[ModelWrapValidator[_ModelType], ModelWrapValidatorWithoutInfo[_ModelType]] Index: pydantic-2.11.7/pydantic/main.py =================================================================== --- pydantic-2.11.7.orig/pydantic/main.py +++ pydantic-2.11.7/pydantic/main.py @@ -480,6 +480,7 @@ class BaseModel(metaclass=_model_constru self, *, indent: int | None = None, + ensure_ascii: bool = False, include: IncEx | None = None, exclude: IncEx | None = None, context: Any | None = None, @@ -499,6 +500,8 @@ class BaseModel(metaclass=_model_constru Args: indent: Indentation to use in the JSON output. If None is passed, the output will be compact. + ensure_ascii: If `True`, the output is guaranteed to have all incoming non-ASCII characters escaped. + If `False` (the default), these characters will be output as-is. include: Field(s) to include in the JSON output. exclude: Field(s) to exclude from the JSON output. context: Additional context to pass to the serializer. @@ -519,6 +522,7 @@ class BaseModel(metaclass=_model_constru return self.__pydantic_serializer__.to_json( self, indent=indent, + ensure_ascii=ensure_ascii, include=include, exclude=exclude, context=context, Index: pydantic-2.11.7/pydantic/type_adapter.py =================================================================== --- pydantic-2.11.7.orig/pydantic/type_adapter.py +++ pydantic-2.11.7/pydantic/type_adapter.py @@ -591,6 +591,7 @@ class TypeAdapter(Generic[T]): /, *, indent: int | None = None, + ensure_ascii: bool = False, include: IncEx | None = None, exclude: IncEx | None = None, by_alias: bool | None = None, @@ -611,6 +612,8 @@ class TypeAdapter(Generic[T]): Args: instance: The instance to be serialized. indent: Number of spaces for JSON indentation. + ensure_ascii: If `True`, the output is guaranteed to have all incoming non-ASCII characters escaped. + If `False` (the default), these characters will be output as-is. include: Fields to include. exclude: Fields to exclude. by_alias: Whether to use alias names for field names. Index: pydantic-2.11.7/pydantic/version.py =================================================================== --- pydantic-2.11.7.orig/pydantic/version.py +++ pydantic-2.11.7/pydantic/version.py @@ -66,7 +66,7 @@ def version_info() -> str: def check_pydantic_core_version() -> bool: """Check that the installed `pydantic-core` dependency is compatible.""" # Keep this in sync with the version constraint in the `pyproject.toml` dependencies: - return __pydantic_core_version__ == '2.33.2' + return __pydantic_core_version__ == '2.35.1' def parse_mypy_version(version: str) -> tuple[int, int, int]: Index: pydantic-2.11.7/pyproject.toml =================================================================== --- pydantic-2.11.7.orig/pyproject.toml +++ pydantic-2.11.7/pyproject.toml @@ -43,10 +43,10 @@ classifiers = [ ] requires-python = '>=3.9' dependencies = [ - 'typing-extensions>=4.12.2', + 'typing-extensions>=4.13.0', 'annotated-types>=0.6.0', # Keep this in sync with the version in the `check_pydantic_core_version()` function: - 'pydantic-core==2.33.2', + 'pydantic-core==2.35.1', 'typing-inspection>=0.4.0', ] dynamic = ['version', 'readme'] Index: pydantic-2.11.7/tests/typechecking/decorators.py =================================================================== --- pydantic-2.11.7.orig/tests/typechecking/decorators.py +++ pydantic-2.11.7/tests/typechecking/decorators.py @@ -31,13 +31,25 @@ class BeforeModelValidator(BaseModel): """TODO This shouldn't be valid. At runtime, `self` is the actual value and `value` is the `ValidationInfo` instance.""" @model_validator(mode='before') - def valid_method_info(self, value: Any, info: ValidationInfo) -> Any: ... + def valid_method_info_default(self, value: Any, info: ValidationInfo) -> Any: ... + + @model_validator(mode='before') + def valid_method_info(self, value: Any, info: ValidationInfo[int]) -> Any: + assert_type(info.context, int) @model_validator(mode='before') @classmethod def valid_classmethod(cls, value: Any) -> Any: ... @model_validator(mode='before') + @classmethod + def valid_classmethod_info_default(cls, value: Any, info: ValidationInfo) -> Any: ... + + @model_validator(mode='before') + @classmethod + def valid_classmethod_info(cls, value: Any, info: ValidationInfo[int]) -> Any: ... + + @model_validator(mode='before') @staticmethod def valid_staticmethod(value: Any) -> Any: ... @@ -91,7 +103,10 @@ class AfterModelValidator(BaseModel): def valid_method_no_info(self) -> Self: ... @model_validator(mode='after') - def valid_method_info(self, info: ValidationInfo) -> Self: ... + def valid_method_info_default(self, info: ValidationInfo) -> Self: ... + + @model_validator(mode='after') + def valid_method_info(self, info: ValidationInfo[int]) -> Self: ... class BeforeFieldValidator(BaseModel): @@ -114,7 +129,11 @@ class BeforeFieldValidator(BaseModel): @field_validator('foo', mode='before', json_schema_input_type=int) # `json_schema_input_type` allowed here. @classmethod - def valid_with_info(cls, value: Any, info: ValidationInfo) -> Any: ... + def valid_with_info_default(cls, value: Any, info: ValidationInfo) -> Any: ... + + @field_validator('foo', mode='before', json_schema_input_type=int) # `json_schema_input_type` allowed here. + @classmethod + def valid_with_info(cls, value: Any, info: ValidationInfo[int]) -> Any: ... class AfterFieldValidator(BaseModel): @@ -122,6 +141,14 @@ class AfterFieldValidator(BaseModel): @classmethod def valid_classmethod(cls, value: Any) -> Any: ... + @field_validator('foo', mode='after') + @classmethod + def valid_classmethod_info_default(cls, value: Any, info: ValidationInfo) -> Any: ... + + @field_validator('foo', mode='after') + @classmethod + def valid_classmethod_info(cls, value: Any, info: ValidationInfo[int]) -> Any: ... + @field_validator('foo', mode='after', json_schema_input_type=int) # type: ignore[call-overload] # pyright: ignore[reportCallIssue, reportArgumentType] @classmethod def invalid_input_type_not_allowed(cls, value: Any) -> Any: ... @@ -148,7 +175,13 @@ class WrapFieldValidator(BaseModel): @field_validator('foo', mode='wrap', json_schema_input_type=int) # `json_schema_input_type` allowed here. @classmethod - def valid_with_info(cls, value: Any, handler: ValidatorFunctionWrapHandler, info: ValidationInfo) -> Any: ... + def valid_with_info_default( + cls, value: Any, handler: ValidatorFunctionWrapHandler, info: ValidationInfo + ) -> Any: ... + + @field_validator('foo', mode='wrap', json_schema_input_type=int) # `json_schema_input_type` allowed here. + @classmethod + def valid_with_info(cls, value: Any, handler: ValidatorFunctionWrapHandler, info: ValidationInfo[int]) -> Any: ... class PlainModelSerializer(BaseModel): @@ -162,7 +195,10 @@ class PlainModelSerializer(BaseModel): def valid_plain_serializer_2(self) -> Any: ... @model_serializer(mode='plain') - def valid_plain_serializer_info(self, info: SerializationInfo) -> Any: ... + def valid_plain_serializer_info_default(self, info: SerializationInfo) -> Any: ... + + @model_serializer(mode='plain') + def valid_plain_serializer_info(self, info: SerializationInfo[int]) -> Any: ... class WrapModelSerializer(BaseModel): @@ -175,7 +211,12 @@ class WrapModelSerializer(BaseModel): return value @model_serializer(mode='wrap') - def valid_info(self, handler: SerializerFunctionWrapHandler, info: SerializationInfo) -> Any: + def valid_info_default(self, handler: SerializerFunctionWrapHandler, info: SerializationInfo) -> Any: + value = handler(self) + return value + + @model_serializer(mode='wrap') + def valid_info(self, handler: SerializerFunctionWrapHandler, info: SerializationInfo[int]) -> Any: value = handler(self) return value @@ -205,7 +246,10 @@ class PlainFieldSerializer(BaseModel): """ @field_serializer('a', mode='plain') - def valid_method_info(self, value: Any, info: FieldSerializationInfo) -> Any: ... + def valid_method_info_default(self, value: Any, info: FieldSerializationInfo) -> Any: ... + + @field_serializer('a', mode='plain') + def valid_method_info(self, value: Any, info: FieldSerializationInfo[int]) -> Any: ... @field_serializer('a', mode='plain') @staticmethod @@ -213,7 +257,11 @@ class PlainFieldSerializer(BaseModel): @field_serializer('a', mode='plain') @staticmethod - def valid_staticmethod_info(value: Any, info: FieldSerializationInfo) -> Any: ... + def valid_staticmethod_info_default(value: Any, info: FieldSerializationInfo) -> Any: ... + + @field_serializer('a', mode='plain') + @staticmethod + def valid_staticmethod_info(value: Any, info: FieldSerializationInfo[int]) -> Any: ... @field_serializer('a', mode='plain') @classmethod @@ -221,7 +269,11 @@ class PlainFieldSerializer(BaseModel): @field_serializer('a', mode='plain') @classmethod - def valid_classmethod_info(cls, value: Any, info: FieldSerializationInfo) -> Any: ... + def valid_classmethod_info_default(cls, value: Any, info: FieldSerializationInfo) -> Any: ... + + @field_serializer('a', mode='plain') + @classmethod + def valid_classmethod_info(cls, value: Any, info: FieldSerializationInfo[int]) -> Any: ... partial_ = field_serializer('a', mode='plain')(partial(lambda v, x: v, x=1)) @@ -250,4 +302,11 @@ class WrapFieldSerializer(BaseModel): def valid_no_info(self, value: Any, handler: SerializerFunctionWrapHandler) -> Any: ... @field_serializer('a', mode='wrap') - def valid_info(self, value: Any, handler: SerializerFunctionWrapHandler, info: FieldSerializationInfo) -> Any: ... + def valid_info_default( + self, value: Any, handler: SerializerFunctionWrapHandler, info: FieldSerializationInfo + ) -> Any: ... + + @field_serializer('a', mode='wrap') + def valid_info( + self, value: Any, handler: SerializerFunctionWrapHandler, info: FieldSerializationInfo[int] + ) -> Any: ... ++++++ field-name-validator-core-schemas.patch ++++++ >From cd0d37c4c18f24b5624ae86cfe5288cd82edf2c1 Mon Sep 17 00:00:00 2001 From: Douwe Maan <h...@douwe.me> Date: Wed, 16 Apr 2025 18:01:58 +0000 Subject: [PATCH 1/4] Stop using deprecated field_name argument on validation function schemas --- docs/concepts/types.md | 2 +- pydantic/_internal/_generate_schema.py | 45 ++++++++++---------------- pydantic/functional_validators.py | 5 +-- tests/test_validators.py | 2 +- 4 files changed, 20 insertions(+), 34 deletions(-) Index: pydantic-2.11.7/docs/concepts/types.md =================================================================== --- pydantic-2.11.7.orig/docs/concepts/types.md +++ pydantic-2.11.7/docs/concepts/types.md @@ -979,7 +979,7 @@ class CustomType: cls, source_type: Any, handler: GetCoreSchemaHandler ) -> core_schema.CoreSchema: return core_schema.with_info_after_validator_function( - cls.validate, handler(int), field_name=handler.field_name + cls.validate, handler(int) ) Index: pydantic-2.11.7/pydantic/_internal/_generate_schema.py =================================================================== --- pydantic-2.11.7.orig/pydantic/_internal/_generate_schema.py +++ pydantic-2.11.7/pydantic/_internal/_generate_schema.py @@ -222,7 +222,6 @@ def filter_field_decorator_info_by_field def apply_each_item_validators( schema: core_schema.CoreSchema, each_item_validators: list[Decorator[ValidatorDecoratorInfo]], - field_name: str | None, ) -> core_schema.CoreSchema: # This V1 compatibility shim should eventually be removed @@ -234,21 +233,20 @@ def apply_each_item_validators( # note that this won't work for any Annotated types that get wrapped by a function validator # but that's okay because that didn't exist in V1 if schema['type'] == 'nullable': - schema['schema'] = apply_each_item_validators(schema['schema'], each_item_validators, field_name) + schema['schema'] = apply_each_item_validators(schema['schema'], each_item_validators) return schema elif schema['type'] == 'tuple': if (variadic_item_index := schema.get('variadic_item_index')) is not None: schema['items_schema'][variadic_item_index] = apply_validators( schema['items_schema'][variadic_item_index], each_item_validators, - field_name, ) elif is_list_like_schema_with_items_schema(schema): inner_schema = schema.get('items_schema', core_schema.any_schema()) - schema['items_schema'] = apply_validators(inner_schema, each_item_validators, field_name) + schema['items_schema'] = apply_validators(inner_schema, each_item_validators) elif schema['type'] == 'dict': inner_schema = schema.get('values_schema', core_schema.any_schema()) - schema['values_schema'] = apply_validators(inner_schema, each_item_validators, field_name) + schema['values_schema'] = apply_validators(inner_schema, each_item_validators) else: raise TypeError( f'`@validator(..., each_item=True)` cannot be applied to fields with a schema of {schema["type"]}' @@ -840,7 +838,7 @@ class GenerateSchema: extras_keys_schema=extras_keys_schema, model_name=cls.__name__, ) - inner_schema = apply_validators(fields_schema, decorators.root_validators.values(), None) + inner_schema = apply_validators(fields_schema, decorators.root_validators.values()) inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') model_schema = core_schema.model_schema( @@ -1380,9 +1378,9 @@ class GenerateSchema: field_info.validate_default = True each_item_validators = [v for v in this_field_validators if v.info.each_item is True] this_field_validators = [v for v in this_field_validators if v not in each_item_validators] - schema = apply_each_item_validators(schema, each_item_validators, name) + schema = apply_each_item_validators(schema, each_item_validators) - schema = apply_validators(schema, this_field_validators, name) + schema = apply_validators(schema, this_field_validators) # the default validator needs to go outside of any other validators # so that it is the topmost validator for the field validator @@ -1972,7 +1970,7 @@ class GenerateSchema: collect_init_only=has_post_init, ) - inner_schema = apply_validators(args_schema, decorators.root_validators.values(), None) + inner_schema = apply_validators(args_schema, decorators.root_validators.values()) model_validators = decorators.model_validators.values() inner_schema = apply_model_validators(inner_schema, model_validators, 'inner') @@ -2484,24 +2482,16 @@ class GenerateSchema: _VALIDATOR_F_MATCH: Mapping[ tuple[FieldValidatorModes, Literal['no-info', 'with-info']], - Callable[[Callable[..., Any], core_schema.CoreSchema, str | None], core_schema.CoreSchema], + Callable[[Callable[..., Any], core_schema.CoreSchema], core_schema.CoreSchema], ] = { - ('before', 'no-info'): lambda f, schema, _: core_schema.no_info_before_validator_function(f, schema), - ('after', 'no-info'): lambda f, schema, _: core_schema.no_info_after_validator_function(f, schema), - ('plain', 'no-info'): lambda f, _1, _2: core_schema.no_info_plain_validator_function(f), - ('wrap', 'no-info'): lambda f, schema, _: core_schema.no_info_wrap_validator_function(f, schema), - ('before', 'with-info'): lambda f, schema, field_name: core_schema.with_info_before_validator_function( - f, schema, field_name=field_name - ), - ('after', 'with-info'): lambda f, schema, field_name: core_schema.with_info_after_validator_function( - f, schema, field_name=field_name - ), - ('plain', 'with-info'): lambda f, _, field_name: core_schema.with_info_plain_validator_function( - f, field_name=field_name - ), - ('wrap', 'with-info'): lambda f, schema, field_name: core_schema.with_info_wrap_validator_function( - f, schema, field_name=field_name - ), + ('before', 'no-info'): lambda f, schema: core_schema.no_info_before_validator_function(f, schema), + ('after', 'no-info'): lambda f, schema: core_schema.no_info_after_validator_function(f, schema), + ('plain', 'no-info'): lambda f, _: core_schema.no_info_plain_validator_function(f), + ('wrap', 'no-info'): lambda f, schema: core_schema.no_info_wrap_validator_function(f, schema), + ('before', 'with-info'): lambda f, schema: core_schema.with_info_before_validator_function(f, schema), + ('after', 'with-info'): lambda f, schema: core_schema.with_info_after_validator_function(f, schema), + ('plain', 'with-info'): lambda f, _: core_schema.with_info_plain_validator_function(f), + ('wrap', 'with-info'): lambda f, schema: core_schema.with_info_wrap_validator_function(f, schema), } @@ -2512,7 +2502,6 @@ def apply_validators( validators: Iterable[Decorator[RootValidatorDecoratorInfo]] | Iterable[Decorator[ValidatorDecoratorInfo]] | Iterable[Decorator[FieldValidatorDecoratorInfo]], - field_name: str | None, ) -> core_schema.CoreSchema: """Apply validators to a schema. @@ -2528,7 +2517,7 @@ def apply_validators( info_arg = inspect_validator(validator.func, validator.info.mode) val_type = 'with-info' if info_arg else 'no-info' - schema = _VALIDATOR_F_MATCH[(validator.info.mode, val_type)](validator.func, schema, field_name) + schema = _VALIDATOR_F_MATCH[(validator.info.mode, val_type)](validator.func, schema) return schema Index: pydantic-2.11.7/pydantic/functional_validators.py =================================================================== --- pydantic-2.11.7.orig/pydantic/functional_validators.py +++ pydantic-2.11.7/pydantic/functional_validators.py @@ -75,7 +75,7 @@ class AfterValidator: info_arg = _inspect_validator(self.func, 'after') if info_arg: func = cast(core_schema.WithInfoValidatorFunction, self.func) - return core_schema.with_info_after_validator_function(func, schema=schema, field_name=handler.field_name) + return core_schema.with_info_after_validator_function(func, schema=schema) else: func = cast(core_schema.NoInfoValidatorFunction, self.func) return core_schema.no_info_after_validator_function(func, schema=schema) @@ -136,7 +136,6 @@ class BeforeValidator: return core_schema.with_info_before_validator_function( func, schema=schema, - field_name=handler.field_name, json_schema_input_schema=input_schema, ) else: @@ -230,7 +229,6 @@ class PlainValidator: func = cast(core_schema.WithInfoValidatorFunction, self.func) return core_schema.with_info_plain_validator_function( func, - field_name=handler.field_name, serialization=serialization, # pyright: ignore[reportArgumentType] json_schema_input_schema=input_schema, ) @@ -307,7 +305,6 @@ class WrapValidator: return core_schema.with_info_wrap_validator_function( func, schema=schema, - field_name=handler.field_name, json_schema_input_schema=input_schema, ) else: Index: pydantic-2.11.7/tests/test_validators.py =================================================================== --- pydantic-2.11.7.orig/tests/test_validators.py +++ pydantic-2.11.7/tests/test_validators.py @@ -21,7 +21,7 @@ from unittest.mock import MagicMock import pytest from dirty_equals import HasRepr, IsInstance from pydantic_core import core_schema -from typing_extensions import TypedDict +from typing_extensions import TypeAliasType, TypedDict from pydantic import ( BaseModel, @@ -2684,7 +2684,7 @@ def foobar_validate(value: Any, info: co class Foobar: @classmethod def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: - return core_schema.with_info_plain_validator_function(foobar_validate, field_name=handler.field_name) + return core_schema.with_info_plain_validator_function(foobar_validate) def test_custom_type_field_name_model(): @@ -2779,6 +2779,29 @@ def test_plain_validator_field_name(): assert m.foobar == {'value': '1', 'field_name': 'foobar', 'data': {'x': 123}} +def test_validator_field_name_with_reused_type_alias(): + calls = [] + + def validate_my_field(value: str, info: ValidationInfo): + calls.append((info.field_name, value)) + return value + + MyField = TypeAliasType('MyField', Annotated[str, AfterValidator(validate_my_field)]) + + class MyModel(BaseModel): + field1: MyField + field2: MyField + + MyModel.model_validate( + { + 'field1': 'value1', + 'field2': 'value2', + } + ) + + assert calls == [('field1', 'value1'), ('field2', 'value2')] + + def validate_wrap(value: Any, handler: core_schema.ValidatorFunctionWrapHandler, info: core_schema.ValidationInfo): data = info.data if isinstance(data, dict): ++++++ pydantic-2.11.3.tar.gz -> pydantic-2.11.7.tar.gz ++++++ ++++ 5172 lines of diff (skipped)