From 64fbc5e7eddd5ce1dd2a2e78521732767fc99bee7b58e7d09f89625c5517b167 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Fri, 12 Dec 2025 09:14:29 +0000 Subject: [PATCH 1/2] - Update to 2.12.5 * Fix pickle error when using model_construct() on a model with MISSING as a default value in #12522. * Several updates to the documentation - Remove patches bump-pydantic-core-2.35.1.patch, field-name-validator-core-schemas.patch, py314.patch, and support-pydantic-core-2.39.0.patch as they've merged upstream. OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-pydantic?expand=0&rev=81 --- .gitattributes | 23 + .gitignore | 1 + _multibuild | 3 + bump-pydantic-core-2.35.1.patch | 424 ++++++++ field-name-validator-core-schemas.patch | 233 +++++ py314.patch | 566 +++++++++++ pydantic-2.11.9.tar.gz | 3 + pydantic-2.12.5.tar.gz | 3 + python-pydantic.changes | 1192 +++++++++++++++++++++++ python-pydantic.spec | 99 ++ support-pydantic-core-2.39.0.patch | 293 ++++++ 11 files changed, 2840 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 _multibuild create mode 100644 bump-pydantic-core-2.35.1.patch create mode 100644 field-name-validator-core-schemas.patch create mode 100644 py314.patch create mode 100644 pydantic-2.11.9.tar.gz create mode 100644 pydantic-2.12.5.tar.gz create mode 100644 python-pydantic.changes create mode 100644 python-pydantic.spec create mode 100644 support-pydantic-core-2.39.0.patch diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/_multibuild b/_multibuild new file mode 100644 index 0000000..fcc7b97 --- /dev/null +++ b/_multibuild @@ -0,0 +1,3 @@ + + test + diff --git a/bump-pydantic-core-2.35.1.patch b/bump-pydantic-core-2.35.1.patch new file mode 100644 index 0000000..18f11dd --- /dev/null +++ b/bump-pydantic-core-2.35.1.patch @@ -0,0 +1,424 @@ +From 4494c31a4834bdc2301cfa3d94f4bbc62c2774dc Mon Sep 17 00:00:00 2001 +From: Viicos <65306057+Viicos@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: ... diff --git a/field-name-validator-core-schemas.patch b/field-name-validator-core-schemas.patch new file mode 100644 index 0000000..760e5b4 --- /dev/null +++ b/field-name-validator-core-schemas.patch @@ -0,0 +1,233 @@ +From cd0d37c4c18f24b5624ae86cfe5288cd82edf2c1 Mon Sep 17 00:00:00 2001 +From: Douwe Maan +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): diff --git a/py314.patch b/py314.patch new file mode 100644 index 0000000..7512d03 --- /dev/null +++ b/py314.patch @@ -0,0 +1,566 @@ +From 9452e13c571db7d31051768c3b4d47a6e2ceea7d Mon Sep 17 00:00:00 2001 +From: Victorien <65306057+Viicos@users.noreply.github.com> +Date: Thu, 10 Jul 2025 11:31:03 +0200 +Subject: [PATCH] Add initial support for Python 3.14 (#11991) + +Adds basic support for Python 3.14. Deferred annotations work for simple cases, but will need to be improved in the future. +--- + .github/workflows/ci.yml | 11 +- + .github/workflows/integration.yml | 4 +- + docs/migration.md | 4 +- + pydantic/_internal/_config.py | 10 +- + pydantic/_internal/_fields.py | 7 +- + pydantic/_internal/_generics.py | 7 +- + pydantic/_internal/_model_construction.py | 24 +- + pydantic/_internal/_typing_extra.py | 36 +- + pydantic/dataclasses.py | 13 +- + pyproject.toml | 3 + + tests/test_dataclasses.py | 11 +- + tests/test_deferred_annotations.py | 81 ++++ + tests/test_forward_ref.py | 15 - + tests/test_model_signature.py | 2 +- + tests/test_pickle.py | 12 +- + tests/test_v1.py | 2 + + uv.lock | 512 ++++++++++++---------- + 17 files changed, 469 insertions(+), 285 deletions(-) + create mode 100644 tests/test_deferred_annotations.py + + +Index: pydantic-2.11.9/docs/migration.md +=================================================================== +--- pydantic-2.11.9.orig/docs/migration.md ++++ pydantic-2.11.9/docs/migration.md +@@ -188,7 +188,7 @@ to help ease migration, but calling them + If you'd still like to use said arguments, you can use [this workaround](https://github.com/pydantic/pydantic/issues/8825#issuecomment-1946206415). + * JSON serialization of non-string key values is generally done with `str(key)`, leading to some changes in behavior such as the following: + +-```python ++```python {test="skip"} + from typing import Optional + + from pydantic import BaseModel as V2BaseModel +@@ -218,7 +218,7 @@ print(v2_model.model_dump_json()) + * `model_dump_json()` results are compacted in order to save space, and don't always exactly match that of `json.dumps()` output. + That being said, you can easily modify the separators used in `json.dumps()` results in order to align the two outputs: + +-```python ++```python {test="skip"} + import json + + from pydantic import BaseModel as V2BaseModel +Index: pydantic-2.11.9/pydantic/_internal/_config.py +=================================================================== +--- pydantic-2.11.9.orig/pydantic/_internal/_config.py ++++ pydantic-2.11.9/pydantic/_internal/_config.py +@@ -98,7 +98,13 @@ class ConfigWrapper: + self.config_dict = cast(ConfigDict, config) + + @classmethod +- def for_model(cls, bases: tuple[type[Any], ...], namespace: dict[str, Any], kwargs: dict[str, Any]) -> Self: ++ def for_model( ++ cls, ++ bases: tuple[type[Any], ...], ++ namespace: dict[str, Any], ++ raw_annotations: dict[str, Any], ++ kwargs: dict[str, Any], ++ ) -> Self: + """Build a new `ConfigWrapper` instance for a `BaseModel`. + + The config wrapper built based on (in descending order of priority): +@@ -109,6 +115,7 @@ class ConfigWrapper: + Args: + bases: A tuple of base classes. + namespace: The namespace of the class being created. ++ raw_annotations: The (non-evaluated) annotations of the model. + kwargs: The kwargs passed to the class being created. + + Returns: +@@ -123,7 +130,6 @@ class ConfigWrapper: + config_class_from_namespace = namespace.get('Config') + config_dict_from_namespace = namespace.get('model_config') + +- raw_annotations = namespace.get('__annotations__', {}) + if raw_annotations.get('model_config') and config_dict_from_namespace is None: + raise PydanticUserError( + '`model_config` cannot be used as a model field name. Use `model_config` for model configuration.', +Index: pydantic-2.11.9/pydantic/_internal/_fields.py +=================================================================== +--- pydantic-2.11.9.orig/pydantic/_internal/_fields.py ++++ pydantic-2.11.9/pydantic/_internal/_fields.py +@@ -119,7 +119,8 @@ def collect_model_fields( # noqa: C901 + + # https://docs.python.org/3/howto/annotations.html#accessing-the-annotations-dict-of-an-object-in-python-3-9-and-older + # annotations is only used for finding fields in parent classes +- annotations = cls.__dict__.get('__annotations__', {}) ++ annotations = _typing_extra.safe_get_annotations(cls) ++ + fields: dict[str, FieldInfo] = {} + + class_vars: set[str] = set() +@@ -375,7 +376,9 @@ def collect_dataclass_fields( + + with ns_resolver.push(base): + for ann_name, dataclass_field in dataclass_fields.items(): +- if ann_name not in base.__dict__.get('__annotations__', {}): ++ base_anns = _typing_extra.safe_get_annotations(base) ++ ++ if ann_name not in base_anns: + # `__dataclass_fields__`contains every field, even the ones from base classes. + # Only collect the ones defined on `base`. + continue +Index: pydantic-2.11.9/pydantic/_internal/_generics.py +=================================================================== +--- pydantic-2.11.9.orig/pydantic/_internal/_generics.py ++++ pydantic-2.11.9/pydantic/_internal/_generics.py +@@ -1,5 +1,6 @@ + from __future__ import annotations + ++import operator + import sys + import types + import typing +@@ -7,6 +8,7 @@ from collections import ChainMap + from collections.abc import Iterator, Mapping + from contextlib import contextmanager + from contextvars import ContextVar ++from functools import reduce + from itertools import zip_longest + from types import prepare_class + from typing import TYPE_CHECKING, Annotated, Any, TypeVar +@@ -21,9 +23,6 @@ from ._core_utils import get_type_ref + from ._forward_ref import PydanticRecursiveRef + from ._utils import all_identical, is_model_class + +-if sys.version_info >= (3, 10): +- from typing import _UnionGenericAlias # type: ignore[attr-defined] +- + if TYPE_CHECKING: + from ..main import BaseModel + +@@ -311,7 +310,7 @@ def replace_types(type_: Any, type_map: + # PEP-604 syntax (Ex.: list | str) is represented with a types.UnionType object that does not have __getitem__. + # We also cannot use isinstance() since we have to compare types. + if sys.version_info >= (3, 10) and origin_type is types.UnionType: +- return _UnionGenericAlias(origin_type, resolved_type_args) ++ return reduce(operator.or_, resolved_type_args) + # NotRequired[T] and Required[T] don't support tuple type resolved_type_args, hence the condition below + return origin_type[resolved_type_args[0] if len(resolved_type_args) == 1 else resolved_type_args] + +Index: pydantic-2.11.9/pydantic/_internal/_model_construction.py +=================================================================== +--- pydantic-2.11.9.orig/pydantic/_internal/_model_construction.py ++++ pydantic-2.11.9/pydantic/_internal/_model_construction.py +@@ -105,12 +105,29 @@ class ModelMetaclass(ABCMeta): + # that `BaseModel` itself won't have any bases, but any subclass of it will, to determine whether the `__new__` + # call we're in the middle of is for the `BaseModel` class. + if bases: ++ raw_annotations: dict[str, Any] ++ if sys.version_info >= (3, 14): ++ if ( ++ '__annotations__' in namespace ++ ): # `from __future__ import annotations` was used in the model's module ++ raw_annotations = namespace['__annotations__'] ++ else: ++ # See https://docs.python.org/3.14/library/annotationlib.html#using-annotations-in-a-metaclass: ++ from annotationlib import Format, call_annotate_function, get_annotate_from_class_namespace ++ ++ if annotate := get_annotate_from_class_namespace(namespace): ++ raw_annotations = call_annotate_function(annotate, format=Format.FORWARDREF) ++ else: ++ raw_annotations = {} ++ else: ++ raw_annotations = namespace.get('__annotations__', {}) ++ + base_field_names, class_vars, base_private_attributes = mcs._collect_bases_data(bases) + +- config_wrapper = ConfigWrapper.for_model(bases, namespace, kwargs) ++ config_wrapper = ConfigWrapper.for_model(bases, namespace, raw_annotations, kwargs) + namespace['model_config'] = config_wrapper.config_dict + private_attributes = inspect_namespace( +- namespace, config_wrapper.ignored_types, class_vars, base_field_names ++ namespace, raw_annotations, config_wrapper.ignored_types, class_vars, base_field_names + ) + if private_attributes or base_private_attributes: + original_model_post_init = get_model_post_init(namespace, bases) +@@ -365,6 +382,7 @@ def get_model_post_init(namespace: dict[ + + def inspect_namespace( # noqa C901 + namespace: dict[str, Any], ++ raw_annotations: dict[str, Any], + ignored_types: tuple[type[Any], ...], + base_class_vars: set[str], + base_class_fields: set[str], +@@ -375,6 +393,7 @@ def inspect_namespace( # noqa C901 + + Args: + namespace: The attribute dictionary of the class to be created. ++ raw_annotations: The (non-evaluated) annotations of the model. + ignored_types: A tuple of ignore types. + base_class_vars: A set of base class class variables. + base_class_fields: A set of base class fields. +@@ -396,7 +415,6 @@ def inspect_namespace( # noqa C901 + all_ignored_types = ignored_types + default_ignored_types() + + private_attributes: dict[str, ModelPrivateAttr] = {} +- raw_annotations = namespace.get('__annotations__', {}) + + if '__root__' in raw_annotations or '__root__' in namespace: + raise TypeError("To define root models, use `pydantic.RootModel` rather than a field called '__root__'") +Index: pydantic-2.11.9/pydantic/_internal/_typing_extra.py +=================================================================== +--- pydantic-2.11.9.orig/pydantic/_internal/_typing_extra.py ++++ pydantic-2.11.9/pydantic/_internal/_typing_extra.py +@@ -26,6 +26,9 @@ else: + from types import EllipsisType as EllipsisType + from types import NoneType as NoneType + ++if sys.version_info >= (3, 14): ++ import annotationlib ++ + if TYPE_CHECKING: + from pydantic import BaseModel + +@@ -289,6 +292,19 @@ def _type_convert(arg: Any) -> Any: + return arg + + ++def safe_get_annotations(cls: type[Any]) -> dict[str, Any]: ++ """Get the annotations for the provided class, accounting for potential deferred forward references. ++ ++ Starting with Python 3.14, accessing the `__annotations__` attribute might raise a `NameError` if ++ a referenced symbol isn't defined yet. In this case, we return the annotation in the *forward ref* ++ format. ++ """ ++ if sys.version_info >= (3, 14): ++ return annotationlib.get_annotations(cls, format=annotationlib.Format.FORWARDREF) ++ else: ++ return cls.__dict__.get('__annotations__', {}) ++ ++ + def get_model_type_hints( + obj: type[BaseModel], + *, +@@ -309,9 +325,14 @@ def get_model_type_hints( + ns_resolver = ns_resolver or NsResolver() + + for base in reversed(obj.__mro__): +- ann: dict[str, Any] | None = base.__dict__.get('__annotations__') +- if not ann or isinstance(ann, types.GetSetDescriptorType): ++ # For Python 3.14, we could also use `Format.VALUE` and pass the globals/locals ++ # from the ns_resolver, but we want to be able to know which specific field failed ++ # to evaluate: ++ ann = safe_get_annotations(base) ++ ++ if not ann: + continue ++ + with ns_resolver.push(base): + globalns, localns = ns_resolver.types_namespace + for name, value in ann.items(): +@@ -341,13 +362,18 @@ def get_cls_type_hints( + obj: The class to inspect. + ns_resolver: A namespace resolver instance to use. Defaults to an empty instance. + """ +- hints: dict[str, Any] | dict[str, tuple[Any, bool]] = {} ++ hints: dict[str, Any] = {} + ns_resolver = ns_resolver or NsResolver() + + for base in reversed(obj.__mro__): +- ann: dict[str, Any] | None = base.__dict__.get('__annotations__') +- if not ann or isinstance(ann, types.GetSetDescriptorType): ++ # For Python 3.14, we could also use `Format.VALUE` and pass the globals/locals ++ # from the ns_resolver, but we want to be able to know which specific field failed ++ # to evaluate: ++ ann = safe_get_annotations(base) ++ ++ if not ann: + continue ++ + with ns_resolver.push(base): + globalns, localns = ns_resolver.types_namespace + for name, value in ann.items(): +Index: pydantic-2.11.9/pydantic/dataclasses.py +=================================================================== +--- pydantic-2.11.9.orig/pydantic/dataclasses.py ++++ pydantic-2.11.9/pydantic/dataclasses.py +@@ -157,7 +157,12 @@ def dataclass( + `x: int = dataclasses.field(default=pydantic.Field(..., kw_only=True), kw_only=True)` + """ + for annotation_cls in cls.__mro__: +- annotations: dict[str, Any] = getattr(annotation_cls, '__annotations__', {}) ++ if sys.version_info >= (3, 14): ++ from annotationlib import Format, get_annotations ++ ++ annotations = get_annotations(annotation_cls, format=Format.FORWARDREF) ++ else: ++ annotations: dict[str, Any] = getattr(annotation_cls, '__annotations__', {}) + for field_name in annotations: + field_value = getattr(cls, field_name, None) + # Process only if this is an instance of `FieldInfo`. +@@ -176,9 +181,9 @@ def dataclass( + field_args['repr'] = field_value.repr + + setattr(cls, field_name, dataclasses.field(**field_args)) +- # In Python 3.9, when subclassing, information is pulled from cls.__dict__['__annotations__'] +- # for annotations, so we must make sure it's initialized before we add to it. +- if cls.__dict__.get('__annotations__') is None: ++ if sys.version_info < (3, 10) and cls.__dict__.get('__annotations__') is None: ++ # In Python 3.9, when a class doesn't have any annotations, accessing `__annotations__` ++ # raises an `AttributeError`. + cls.__annotations__ = {} + cls.__annotations__[field_name] = annotations[field_name] + +Index: pydantic-2.11.9/pyproject.toml +=================================================================== +--- pydantic-2.11.9.orig/pyproject.toml ++++ pydantic-2.11.9/pyproject.toml +@@ -32,6 +32,7 @@ classifiers = [ + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', ++ 'Programming Language :: Python :: 3.14', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'License :: OSI Approved :: MIT License', +@@ -220,6 +221,8 @@ pydocstyle = { convention = 'google' } + 'docs/*' = ['D'] + 'pydantic/__init__.py' = ['F405', 'F403', 'D'] + 'tests/test_forward_ref.py' = ['F821'] ++# We can't configure a specific Python version per file (this one only supports 3.14+): ++'tests/test_deferred_annotations.py' = ['F821', 'F841'] + 'tests/*' = ['D', 'B', 'C4'] + 'pydantic/deprecated/*' = ['D', 'PYI'] + 'pydantic/color.py' = ['PYI'] +Index: pydantic-2.11.9/tests/test_dataclasses.py +=================================================================== +--- pydantic-2.11.9.orig/tests/test_dataclasses.py ++++ pydantic-2.11.9/tests/test_dataclasses.py +@@ -30,6 +30,7 @@ from pydantic import ( + BaseModel, + BeforeValidator, + ConfigDict, ++ Field, + PydanticDeprecatedSince20, + PydanticUndefinedAnnotation, + PydanticUserError, +@@ -45,7 +46,6 @@ from pydantic import ( + ) + from pydantic._internal._mock_val_ser import MockValSer + from pydantic.dataclasses import is_pydantic_dataclass, rebuild_dataclass +-from pydantic.fields import Field, FieldInfo + from pydantic.json_schema import model_json_schema + + +@@ -2072,15 +2072,14 @@ def test_inheritance_replace(decorator1: + def test_dataclasses_inheritance_default_value_is_not_deleted( + decorator1: Callable[[Any], Any], default: Literal[1] + ) -> None: +- if decorator1 is dataclasses.dataclass and isinstance(default, FieldInfo): +- pytest.skip(reason="stdlib dataclasses don't support Pydantic fields") +- + @decorator1 + class Parent: + a: int = default + +- assert Parent.a == 1 +- assert Parent().a == 1 ++ # stdlib dataclasses don't support Pydantic's `Field()`: ++ if decorator1 is pydantic.dataclasses.dataclass: ++ assert Parent.a == 1 ++ assert Parent().a == 1 + + @pydantic.dataclasses.dataclass + class Child(Parent): +Index: pydantic-2.11.9/tests/test_deferred_annotations.py +=================================================================== +--- /dev/null ++++ pydantic-2.11.9/tests/test_deferred_annotations.py +@@ -0,0 +1,81 @@ ++"""Tests related to deferred evaluation of annotations introduced in Python 3.14 by PEP 649 and 749.""" ++ ++import sys ++from dataclasses import field ++from typing import Annotated ++ ++import pytest ++from annotated_types import MaxLen ++ ++from pydantic import BaseModel, Field, ValidationError ++from pydantic.dataclasses import dataclass ++ ++pytestmark = pytest.mark.skipif( ++ sys.version_info < (3, 14), reason='Requires deferred evaluation of annotations introduced in Python 3.14' ++) ++ ++ ++def test_deferred_annotations_model() -> None: ++ class Model(BaseModel): ++ a: Int ++ b: Str = 'a' ++ ++ Int = int ++ Str = str ++ ++ inst = Model(a='1', b=b'test') ++ assert inst.a == 1 ++ assert inst.b == 'test' ++ ++ ++@pytest.mark.xfail( ++ reason=( ++ 'When rebuilding model fields, we individually re-evaluate all fields (using `_eval_type()`) ' ++ "and as such we don't benefit from PEP 649's capabilities." ++ ), ++) ++def test_deferred_annotations_nested_model() -> None: ++ def outer(): ++ def inner(): ++ class Model(BaseModel): ++ ann: Annotated[List[Dict[str, str]], MaxLen(1)] ++ ++ Dict = dict ++ ++ return Model ++ ++ List = list ++ ++ Model = inner() ++ ++ return Model ++ ++ Model = outer() ++ ++ with pytest.raises(ValidationError) as exc_info: ++ Model(ann=[{'a': 'b'}, {'c': 'd'}]) ++ ++ assert exc_info.value.errors()[0]['type'] == 'too_long' ++ ++ ++def test_deferred_annotations_pydantic_dataclass() -> None: ++ @dataclass ++ class A: ++ a: Int = field(default=1) ++ ++ Int = int ++ ++ assert A(a='1').a == 1 ++ ++ ++@pytest.mark.xfail( ++ reason="To support Pydantic's `Field()` function in dataclasses, we directly write to `__annotations__`" ++) ++def test_deferred_annotations_pydantic_dataclass_pydantic_field() -> None: ++ @dataclass ++ class A: ++ a: Int = Field(default=1) ++ ++ Int = int ++ ++ assert A(a='1').a == 1 +Index: pydantic-2.11.9/tests/test_forward_ref.py +=================================================================== +--- pydantic-2.11.9.orig/tests/test_forward_ref.py ++++ pydantic-2.11.9/tests/test_forward_ref.py +@@ -74,21 +74,6 @@ def test_forward_ref_auto_update_no_mode + assert f.model_dump() == {'a': {'b': {'a': {'b': {'a': None}}}}} + + +-def test_forward_ref_one_of_fields_not_defined(create_module): +- @create_module +- def module(): +- from pydantic import BaseModel +- +- class Foo(BaseModel): +- foo: 'Foo' +- bar: 'Bar' +- +- assert {k: repr(v) for k, v in module.Foo.model_fields.items()} == { +- 'foo': 'FieldInfo(annotation=Foo, required=True)', +- 'bar': "FieldInfo(annotation=ForwardRef('Bar'), required=True)", +- } +- +- + def test_basic_forward_ref(create_module): + @create_module + def module(): +Index: pydantic-2.11.9/tests/test_model_signature.py +=================================================================== +--- pydantic-2.11.9.orig/tests/test_model_signature.py ++++ pydantic-2.11.9/tests/test_model_signature.py +@@ -184,7 +184,7 @@ def test_annotated_field(): + assert typing_objects.is_annotated(get_origin(sig.parameters['foo'].annotation)) + + +-@pytest.mark.skipif(sys.version_info < (3, 10), reason='repr different on older versions') ++@pytest.mark.skipif(sys.version_info < (3, 10), sys.version_info >= (3, 14), reason='repr different on older versions') + def test_annotated_optional_field(): + from annotated_types import Gt + +Index: pydantic-2.11.9/tests/test_pickle.py +=================================================================== +--- pydantic-2.11.9.orig/tests/test_pickle.py ++++ pydantic-2.11.9/tests/test_pickle.py +@@ -1,6 +1,7 @@ + import dataclasses + import gc + import pickle ++import sys + from typing import Optional + + import pytest +@@ -17,6 +18,11 @@ except ImportError: + + pytestmark = pytest.mark.skipif(cloudpickle is None, reason='cloudpickle is not installed') + ++cloudpickle_xfail = pytest.mark.xfail( ++ condition=sys.version_info >= (3, 14), ++ reason='Cloudpickle issue: https://github.com/cloudpipe/cloudpickle/issues/572', ++) ++ + + class IntWrapper: + def __init__(self, v: int): +@@ -88,7 +94,7 @@ def model_factory() -> type: + (ImportableModel, False), + (ImportableModel, True), + # Locally-defined model can only be pickled with cloudpickle. +- (model_factory(), True), ++ pytest.param(model_factory(), True, marks=cloudpickle_xfail), + ], + ) + def test_pickle_model(model_type: type, use_cloudpickle: bool): +@@ -133,7 +139,7 @@ def nested_model_factory() -> type: + (ImportableNestedModel, False), + (ImportableNestedModel, True), + # Locally-defined model can only be pickled with cloudpickle. +- (nested_model_factory(), True), ++ pytest.param(nested_model_factory(), True, marks=cloudpickle_xfail), + ], + ) + def test_pickle_nested_model(model_type: type, use_cloudpickle: bool): +@@ -264,7 +270,7 @@ def nested_dataclass_model_factory() -> + (ImportableNestedDataclassModel, False), + (ImportableNestedDataclassModel, True), + # Locally-defined model can only be pickled with cloudpickle. +- (nested_dataclass_model_factory(), True), ++ pytest.param(nested_dataclass_model_factory(), True, marks=cloudpickle_xfail), + ], + ) + def test_pickle_dataclass_nested_in_model(model_type: type, use_cloudpickle: bool): +Index: pydantic-2.11.9/tests/test_v1.py +=================================================================== +--- pydantic-2.11.9.orig/tests/test_v1.py ++++ pydantic-2.11.9/tests/test_v1.py +@@ -1,3 +1,4 @@ ++import sys + import warnings + + import pytest +@@ -14,6 +15,7 @@ def test_version(): + assert V1_VERSION != VERSION + + ++@pytest.mark.skipif(sys.version_info >= (3, 14), reason='Python 3.14+ not supported') + @pytest.mark.thread_unsafe(reason='Mutates the value') + def test_root_validator(): + class Model(V1BaseModel): diff --git a/pydantic-2.11.9.tar.gz b/pydantic-2.11.9.tar.gz new file mode 100644 index 0000000..0c315eb --- /dev/null +++ b/pydantic-2.11.9.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e14caadd65cf15f778c90cd9f4878942b44aeaeaf3a6b595fbc88b0555df0dc1 +size 3090332 diff --git a/pydantic-2.12.5.tar.gz b/pydantic-2.12.5.tar.gz new file mode 100644 index 0000000..309fb69 --- /dev/null +++ b/pydantic-2.12.5.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 +size 821591 diff --git a/python-pydantic.changes b/python-pydantic.changes new file mode 100644 index 0000000..ffce658 --- /dev/null +++ b/python-pydantic.changes @@ -0,0 +1,1192 @@ +------------------------------------------------------------------- +Wed Dec 3 20:31:21 UTC 2025 - Guang Yee + +- Update to 2.12.5 + * Fix pickle error when using model_construct() on a model with MISSING as a default value in #12522. + * Several updates to the documentation +- Remove patches bump-pydantic-core-2.35.1.patch, field-name-validator-core-schemas.patch, + py314.patch, and support-pydantic-core-2.39.0.patch as they've merged upstream. + +------------------------------------------------------------------- +Mon Sep 29 12:28:15 UTC 2025 - Markéta Machová + +- Add upstream py314.patch to fix compatibility with Python 3.14 + +------------------------------------------------------------------- +Sat Sep 13 16:02:48 UTC 2025 - Dirk Müller + +- update to 2.11.9: + * Backport v1.10.23 changes + * Fix mypy plugin for mypy 1.18 + +------------------------------------------------------------------- +Fri Aug 15 04:23:15 UTC 2025 - Steve Kowalik + +- Add patch support-pydantic-core-2.39.0.patch: + * Support pydantic-core 2.39.0. + +------------------------------------------------------------------- +Mon Jun 23 05:56:23 UTC 2025 - Daniel Garcia + +- 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 + +- 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 + +------------------------------------------------------------------- +Fri Apr 25 09:30:29 UTC 2025 - Markéta Machová + +- Add upstream field_name.patch for compatibility with recent pydantic-core + +------------------------------------------------------------------- +Thu Apr 24 04:47:19 UTC 2025 - Steve Kowalik + +- Add missing Requires on typing-inspection. + +------------------------------------------------------------------- +Sun Apr 20 10:54:45 UTC 2025 - Richard Rahl + +- update to 2.11.3: + * Preserve field description when rebuilding model fields +- update to 2.11.2: + * Make sure __pydantic_private__ exists before setting private attributes + * Do not override FieldInfo._complete when using field from parent class + * Provide the available definitions when applying discriminated unions + * Do not expand root type in the mypy plugin for variables + * Mention the attribute name in model fields deprecation message + * Properly validate parameterized mappings +- update to 2.11.1: + * Do not override 'definitions-ref' schemas containing serialization schemas or metadata +- update to 2.11.0: + * Re-enable memray related tests on Python 3.12+ + * Add a check_pydantic_core_version() function + * Remove greenlet development dependency + * Support unsubstituted type variables with both a default and a bound or constraints + * Add a default_factory_takes_validated_data property to FieldInfo + * Raise a better error when a generic alias is used inside type[] + * Properly support PEP 695 generics syntax + * Properly support type variable defaults + * Add support for validating v6, v7, v8 UUIDs + * Improve alias configuration APIs + * Add experimental support for free threading + * Add encoded_string() method to the URL types + * Add support for defer_build with @validate_call decorator + * Allow @with_config decorator to be used with keyword arguments + * Simplify customization of default value inclusion in JSON Schema generation + * Add generate_arguments_schema() function + * Rework create_model field definitions format + * Raise a deprecation warning when a field is annotated as final with a default value + * Deprecate accessing model_fields and model_computed_fields on instances + * Move core schema generation logic for path types inside the GenerateSchema class + * Move Mapping schema gen to GenerateSchema to complete removal of prepare_annotations_for_known_type workaround + * Remove Python 3.8 Support + * Optimize calls to get_type_ref + * Disable pydantic-core core schema validation + * Only evaluate FieldInfo annotations if required during schema building + * Improve __setattr__ performance of Pydantic models by caching setter functions + * Improve annotation application performance + * Improve performance of _typing_extra module + * Refactor and optimize schema cleaning logic + * Create a single dictionary when creating a CoreConfig instance + * Reuse cached core schemas for parametrized generic Pydantic models + * Add validation tests for _internal/_validators.py + * Subclass all single host url classes from AnyUrl to preserve behavior from v2.9 + * Improve TypeAdapter instance repr + * Use the correct frame when instantiating a parametrized TypeAdapter + * Relax check for validated data in default factory utils + * Fix type checking issue with model_fields and model_computed_fields + * Use the parent configuration during schema generation for stdlib dataclasses + * Use the globals of the function when evaluating the return type of serializers and computed_fields + * Fix url constraint application + * Fix URL equality with different validation methods + * Fix JSON schema title when specified as '' + * Do not evaluate annotations for private fields + * Support serialization as any for Secret types and Url types + * Fix type hint of Field.default to be compatible with Python 3.8 and 3.9 + * hashing support for urls + * Hide BaseModel.__replace__ definition from type checkers + * Set fields when defer_build is set on Pydantic dataclasses + * Do not resolve the JSON Schema reference for dict core schema keys + * Use the globals of the function when evaluating the return type for PlainSerializer and WrapSerializer functions + * Fix host required enforcement for urls to be compatible with v2.9 behavior + * Fix url json schema in serialization mode + * Fix for comparison of AnyUrl objects + * Properly fetch PEP 695 type params for functions, do not fetch annotations from signature + * Infer final fields with a default value as class variables in the mypy plugin + * Recursively unpack Literal values if using PEP 695 type aliases + * Override __subclasscheck__ on ModelMetaclass to avoid memory leak and performance issues + * Include JSON Schema input core schema in function schemas + * Add len to _BaseUrl to avoid TypeError + * Make sure the type reference is removed from the seen references + * Add FastAPI and SQLModel to third-party tests + * Improve discriminated union error message for invalid union variants + * Unpack PEP 695 type aliases if using the Annotated form + * Remove custom MRO implementation of Pydantic models + * Add pandera third-party tests + * Add ODMantic third-party tests + * Copy WithJsonSchema schema to avoid sharing mutated data + * Do not cache parametrized models when in the process of parametrizing another model + * Add discriminated union related metadata entries to the CoreMetadata definition + * Consolidate schema definitions logic in the _Definitions class + * Fix url serialization for unions + * Support initializing root model fields with values of the root type in the mypy plugin + * Move deque schema gen to GenerateSchema class + +------------------------------------------------------------------- +Fri Jan 24 15:21:26 UTC 2025 - ecsos + +- Update to 2.10.6 + * Fixes + - Fix JSON Schema reference collection with 'examples' keys by @Viicos in #11325 + - Fix url python serialization by @sydney-runkle in #11331 +- Changes from 2.10.5 + * Fixes + - Remove custom MRO implementation of Pydantic models by @Viicos in #11184 + - Fix URL serialization for unions by @sydney-runkle in #11233 +- Changes from 2.10.4 + * Packaging + - Bump pydantic-core to v2.27.2 by @davidhewitt in #11138 + * Fixes + - Fix for comparison of AnyUrl objects by @alexprabhat99 in #11082 + - Properly fetch PEP 695 type params for functions, do not fetch annotations from signature by @Viicos in #11093 + - Include JSON Schema input core schema in function schemas by @Viicos in #11085 + - Add len to _BaseUrl to avoid TypeError by @Kharianne in #11111 + - Make sure the type reference is removed from the seen references by @Viicos in #11143 +- Changes from 2.10.3 + * Fixes + - Set fields when defer_build is set on Pydantic dataclasses by @Viicos in #10984 + - Do not resolve the JSON Schema reference for dict core schema keys by @Viicos in #10989 + - Use the globals of the function when evaluating the return type for PlainSerializer and WrapSerializer functions by @Viicos in #11008 + - Fix host required enforcement for urls to be compatible with v2.9 behavior by @sydney-runkle in #11027 + - Add a default_factory_takes_validated_data property to FieldInfo by @Viicos in #11034 + - Fix url json schema in serialization mode by @sydney-runkle in #11035 +- Changes from 2.10.2 + * Fixes + - Only evaluate FieldInfo annotations if required during schema building by @Viicos in #10769 + - Do not evaluate annotations for private fields by @Viicos in #10962 + - Support serialization as any for Secret types and Url types by @sydney-runkle in #10947 + - Fix type hint of Field.default to be compatible with Python 3.8 and 3.9 by @Viicos in #10972 + - Add hashing support for URL types by @sydney-runkle in #10975 + - Hide BaseModel.__replace__ definition from type checkers by @Viicos in 10979 +- Changes from 2.10.1 + * Packaging + - Bump pydantic-core version to v2.27.1 by @sydney-runkle in #10938 + * Fixes + - Use the correct frame when instantiating a parametrized TypeAdapter by @Viicos in #10893 + - Relax check for validated data in default_factory utils by @sydney-runkle in #10909 + - Fix type checking issue with model_fields and model_computed_fields by @sydney-runkle in #10911 + - Use the parent configuration during schema generation for stdlib dataclasses by @sydney-runkle in #10928 + - Use the globals of the function when evaluating the return type of serializers and computed_fields by @Viicos in #10929 + - Fix URL constraint application by @sydney-runkle in #10922 + - Fix URL equality with different validation methods by @sydney-runkle in #10934 + - Fix JSON schema title when specified as '' by @sydney-runkle in #10936 + - Fix python mode serialization for complex inference by @sydney-runkle in pydantic-core#1549 +- Changes from 2.10.0 + * Packaging + - Bump pydantic-core to v2.27.0 by @sydney-runkle in #10825 + - Replaced pdm with uv by @frfahim in #10727 + * New Features + - Support fractions.Fraction by @sydney-runkle in #10318 + - Support Hashable for json validation by @sydney-runkle in #10324 + - Add a SocketPath type for linux systems by @theunkn0wn1 in #10378 + - Allow arbitrary refs in JSON schema examples by @sydney-runkle in #10417 + - Support defer_build for Pydantic dataclasses by @Viicos in #10313 + - Adding v1 / v2 incompatibility warning for nested v1 model by @sydney-runkle in #10431 + - Add support for unpacked TypedDict to type hint variadic keyword arguments with @validate_call by @Viicos in #10416 + - Support compiled patterns in protected_namespaces by @sydney-runkle in #10522 + - Add support for propertyNames in JSON schema by @FlorianSW in #10478 + - Adding __replace__ protocol for Python 3.13+ support by @sydney-runkle in #10596 + - Expose public sort method for JSON schema generation by @sydney-runkle in #10595 + - Add runtime validation of @validate_call callable argument by @kc0506 in #10627 + - Add experimental_allow_partial support by @samuelcolvin in #10748 + - Support default factories taking validated data as an argument by @Viicos in #10678 + - Allow subclassing ValidationError and PydanticCustomError by @Youssefares in pydantic/pydantic-core#1413 + - Add trailing-strings support to experimental_allow_partial by @sydney-runkle in #10825 + - Add rebuild() method for TypeAdapter and simplify defer_build patterns by @sydney-runkle in #10537 + - Improve TypeAdapter instance repr by @sydney-runkle in #10872 + * Changes + - Don't allow customization of SchemaGenerator until interface is more stable by @sydney-runkle in #10303 + - Cleanly defer_build on TypeAdapters, removing experimental flag by @sydney-runkle in #10329 + - Fix mro of generic subclass by @kc0506 in #10100 + - Strip whitespaces on JSON Schema title generation by @sydney-runkle in #10404 + - Use b64decode and b64encode for Base64Bytes type by @sydney-runkle in #10486 + - Relax protected namespace config default by @sydney-runkle in #10441 + - Revalidate parametrized generics if instance's origin is subclass of OG class by @sydney-runkle in #10666 + - Warn if configuration is specified on the @dataclass decorator and with the __pydantic_config__ attribute by @sydney-runkle in #10406 + - Recommend against using Ellipsis (...) with Field by @Viicos in #10661 + - Migrate to subclassing instead of annotated approach for pydantic url types by @sydney-runkle in #10662 + - Change JSON schema generation of Literals and Enums by @Viicos in #10692 + - Simplify unions involving Any or Never when replacing type variables by @Viicos in #10338 + - Do not require padding when decoding base64 bytes by @bschoenmaeckers in pydantic/pydantic-core#1448 + - Support dates all the way to 1BC by @changhc in pydantic/speedate#77 + * Performance + - Schema cleaning: skip unnecessary copies during schema walking by @Viicos in #10286 + - Refactor namespace logic for annotations evaluation by @Viicos in #10530 + - Improve email regexp on edge cases by @AlekseyLobanov in #10601 + - CoreMetadata refactor with an emphasis on documentation, schema build time performance, and reducing complexity by @sydney-runkle in #10675 + * Fixes + - Remove guarding check on computed_field with field_serializer by @nix010 in #10390 + - Fix Predicate issue in v2.9.0 by @sydney-runkle in #10321 + - Fixing annotated-types bound by @sydney-runkle in #10327 + - Turn tzdata install requirement into optional timezone dependency by @jakob-keller in #10331 + - Use correct types namespace when building namedtuple core schemas by @Viicos in #10337 + - Fix evaluation of stringified annotations during namespace inspection by @Viicos in #10347 + - Fix IncEx type alias definition by @Viicos in #10339 + - Do not error when trying to evaluate annotations of private attributes by @Viicos in #10358 + - Fix nested type statement by @kc0506 in #10369 + - Improve typing of ModelMetaclass.mro by @Viicos in #10372 + - Fix class access of deprecated computed_fields by @Viicos in #10391 + - Make sure inspect.iscoroutinefunction works on coroutines decorated with @validate_call by @MovisLi in #10374 + - Fix NameError when using validate_call with PEP 695 on a class by @kc0506 in #10380 + - Fix ZoneInfo with various invalid types by @sydney-runkle in #10408 + - Fix PydanticUserError on empty model_config with annotations by @cdwilson in #10412 + - Fix variance issue in _IncEx type alias, only allow True by @Viicos in #10414 + - Fix serialization schema generation when using PlainValidator by @Viicos in #10427 + - Fix schema generation error when serialization schema holds references by @Viicos in #10444 + - Inline references if possible when generating schema for json_schema_input_type by @Viicos in #10439 + - Fix recursive arguments in Representation by @Viicos in #10480 + - Fix representation for builtin function types by @kschwab in #10479 + - Add python validators for decimal constraints (max_digits and decimal_places) by @sydney-runkle in #10506 + - Only fetch __pydantic_core_schema__ from the current class during schema generation by @Viicos in #10518 + - Fix stacklevel on deprecation warnings for BaseModel by @sydney-runkle in #10520 + - Fix warning stacklevel in BaseModel.__init__ by @Viicos in #10526 + - Improve error handling for in-evaluable refs for discriminator application by @sydney-runkle in #10440 + - Change the signature of ConfigWrapper.core_config to take the title directly by @Viicos in #10562 + - Do not use the previous config from the stack for dataclasses without config by @Viicos in #10576 + - Fix serialization for IP types with mode='python' by @sydney-runkle in #10594 + - Support constraint application for Base64Etc types by @sydney-runkle in #10584 + - Fix validate_call ignoring Field in Annotated by @kc0506 in #10610 + - Raise an error when Self is invalid by @kc0506 in #10609 + - Using core_schema.InvalidSchema instead of metadata injection + checks by @sydney-runkle in [#1... + +------------------------------------------------------------------- +Wed Oct 2 22:06:18 UTC 2024 - Meera Belur + +- update to 2.9.2. + * history updates + * v bump + * Fix `ZoneInfo` with various invalid types + * Fix variance issue in `_IncEx` type alias, only allow `True` + * Fix serialization schema generation when using `PlainValidator` + * Adding notes on designing callable discriminators + * Do not error when trying to evaluate annotations of private attributes + * bump + * Fix evaluation of stringified annotations during namespace inspection + * Use correct types namespace when building namedtuple core schemas + * Fix `IncEx` type alias definition + * Turn `tzdata` install requirement into optional `timezone` dependency + * Fixing `annotated-types` bound + * Fix `Predicate` issue in `v2.9.0` + * Prep for v2.9 release + * Fix lifecycle docs formatting + * Add schema generation benchmarks for models with custom serializers + * Add link for complex docs + * Respect `schema_generator` config value in `TypeAdapter` + * Ensure `__pydantic_complete__` is set when rebuilding dataclasses + * Try fix for `coverage` with hidden files + * Ensure coverage data artifact is correctly uploaded + * Support signature for wrap validators without `info` + * Reformat + add some benchmarks for annotated validators + * 👥 Update Pydantic People + * Fix typo in `orgs.toml` + * Add benchmarks for schema generation with custom validators + * Bump to `v2.9.0b2` + * Reorganize types ns functions + * Add in Hyperlint Base Style Guide + Spellcheck Configurations + * Bump `pydantic-core` to `v2.23.1` and other minor v bumps + * Use identity instead of equality after validating model in `__init__` + * Update ns stack with already copied ns + * Remove defaults filter for namespace + * Improve concepts documentation related to models + * Add benchmarks for direct model instantiation + * Fix parent namespace issue with model rebuilds + * Raise helpful warning when `self` isn't returned from model validator + * Fix history.md typos + * Minor reorganization of benchmarks + * Add comment reflecting unexpected union cache behavior that affects validation order + * Update release tweet to encourage usage for beta versions + * Add benchmarks for categories: serialization, validation and schema generation + * Fix a crash when cleaning the namespace in `ModelMetaclass` + * Fix warnings assertions to use `pytest.warns + * Prep for v2.9.0b1 release + * Add support for annotated_types.Not + * Add 'wss' for allowed schemes in NatsDsn + * Add missing imports in documentation example + * Bump `v1` version stub to `v1.10.18` + * Use `pppr` for insiders install + * Apply misc. improvements to "Get started" documentation + * Allow validators to customize validation JSON schema + * Update `mkdocs-material` to `9.5.31` + * Update and clean up several aspects of documentation tooling + * Fix key error with custom serializer + * Remove `initial_metadata` from internal metadata construct + * Remove unused environment variables in CI + * Make sure generated JSON Schemas are valid in tests + * Fix invalid JSON Schemas being generated for functions in certain scenarios + * Breaking Change: Fix JSON Schema generation for constrained dates + * Deprecate passing a dict to the `Examples` class + * Remove `typed_dict_cls` data from `CoreMetadata` + * Fix JSON Schema generation of fields with plain validators in serialization mode + * Fix JSON Schema `number` type for literal and enum schemas + * Remove docs about pydantic plugins + * Allow `WithJsonSchema` to inject `$ref`s w/ `http` or `https` links + * Improve runtime errors for string constraints like `pattern` for incompatible types + * Add support for stringified annotations when using `PrivateAttr` with `Annotated` + * Fix core schema simplification when serialization schemas are involved in specific scenarios + * Reorganize `BaseModel` annotations + * Support PDM `v2.18.1` + * Support complex number + * Add initial architeture documentation + * Handle `nullable` schemas with `serialization` schema available during JSON Schema generation + * Blacklist default globals to support exotic user code with `__` prefixed annotations + * Fix `ImportString` special cases + * Add dsn for Snowflake + * Temporary: cap `pdm` version for `mypy` tests + * Temporary: use `pdm` v2.17.3 to unblock CI failures + * Performance boost: skip caching parent namespaces in most cases + * Do not compute JSON Schema default when plain serializers are used with `when_used` set to `'json-unless-none'` and the default value is `None` + * Add warning for double `frozen` config setting on dataclass + * Revert "Experimental feature: opt-in fast build + * Remove default module globals from types namespace + * Docs update and warning frozen defined both + * Fix ip schema serialization logic + * Improve documentation of the `@computed_field` decorator + * Improve `pyright` tests, refactor model decorators signatures + * Update tests for changes to core + * Fix `PydanticDeprecatedSince26.since` argument + * Use `is_annotated` consistently + * Adding tests for TODO union serialization fixes + * Update `griffe_doclinks` plugin and misc. docs improvements + * Remove allOf JSON schema workarounds + * Remove logic to handle unused `__get_pydantic_core_schema__` signature + * Fix `frozen` enforcement for dataclasses + * Experimental feature: opt-in fast build + * Docs update for `types.py` + * Fix evaluation of `__pydantic_extra__` annotation in specific circumstances + * Removing old typing function + * Simplify internal generics logic - remove generator overhead + * Minor speedup / cleanup for internal `FieldInfo` functions + * Bump `pydantic-core` to v2.21.0 + * Raise a better user error when failing to evaluate a forward reference + * Add `Config.val_json_bytes` + * Enable more lint rules + * Clarify `model_serializer + * Fix `Mapping` and `MutableMapping` annotations to use mapping schema instead of dict schema + * Bump CodSpeedHQ/action from 2 to 3 + * Bump dawidd6/action-download-artifact from 3 to 6 + * Move `import_module` import in `__getattr__` + * Refactor application of deque annotations + * Using cached internal import for `BaseModel` + * 👥 Update Pydantic People + * Initial start at improving import times for modules, using caching primarily + * Add import / isinstance benchmarks + * Move annotation compatibility errors to validation phase + * Support compatibility with `pdm v2.17.0` + * Apply `strict=True` to `__init__` in mypy plugin + * Fix false positives on v1 models in mypy plugin for from_orm check requiring from_attributes=True config + * Fix typing for `IPvAnyAddress` and `IPvAnyInterface` + * ⚡️ Speed up method `ConfigWrapper.core_config` by 28% in `pydantic/_internal/_config.py` + * ⚡️ Speed up function `apply_each_item_validators` by 100% in `pydantic/_internal/_generate_schema.py` + * Refactor annotation injection for known + * Fix Sequence ignoring discriminator + * chore: fix entry in `.gitignore` to let `make format` work correctly + * Move `decimal.Decimal` validation to `_generate_schema.py` + * Move date schemas to `_generate_schema.py` + * Simplify schema generation for uuid, url, and ip types + * Fix dataclass ignoring default_factory passed in Annotated + * Changed `BaseModel.model_validate_json` raises docstring to mention `ValidationError` instead of `ValueError` + * ⚡️ Speed up method `GenerateSchema._unpack_refs_defs` by 26% in `pydantic/_internal/_generate_schema.py` + * Move enum schema gen to `_generate_schema.py` for consistency + * Add class name to "has conflict" warnings + * `Counter` is handled as a mapping, not a sequence, fix `SequenceValidator` accordingly + * Fix type annotations for some potentially generic `GenerateSchema.match_type` options + * Simplify IP address schema in `_std_types_schema.py` + * Fix typo in `invalid-annotated-type` error code + * Fix _field_name_for_signature docstring + * ⚡️ Speed up function `_field_name_for_signature` by 37% in `pydantic/_internal/_signature.py` + * Add support for `ZoneInfo` + * Fix a typo on Validators doc page + * Adding new schema building benchmark + * Handle frozen fields on a per-field basis + * Allow usage of `type[Annotated[...]]` + * typing: fix recursive typing of `main.IncEnx` + * Fix `ComputedFieldInfo.wrapped_property` pointer when a property setter is assigned + * ⚡️ Speed up `dataclass + * Replace str type annotation with Any in validator factories in documentation on validators + * Fix typing issue with field_validator-decorated methods + * Prevent type error for exotic BaseModel/RootModel inheritance + * ⚡️ Speed up `ModelPrivateAttr.__set_name__ + * chore + * ⚡️ Speed up `multiple_of_validator + * Update functional_serializers.py Typo in Docs Example Simple Fix + * Update changelog to reflect breaking changes regarding PEP 570 + * Update history, bump version to alpha on `main` + * Fix issue with assertion caused by pluggable schema validator + * Fix #9706 PathLike with subtype + * Adding coverage comment + * docs: Add documentation for Semantic Version and Timezone Name + * Bump `pydantic-core` to `v2.20.1`, `pydantic-extra-types` to `v2.9.0` + * Remove spooky meetings file + * Pedantic typo correction within explanation of Pydantic's root in 'pedantic' in index.md + * Breaking Change: Merge `dict` type `json_schema_extra` + * Fix list constraint json schema application + * Respect use_enum_values on Literal types + * Bump `ruff` to `v0.5.0` and `pyright` to `v1.1.369` + * Fix breaking change in `to_snake` from v2.7 -> v2.8 + * Fix labeler, again + * Hooky - switch to reviewers, labeler, fix ci bug + +------------------------------------------------------------------- +Fri Sep 27 02:01:34 UTC 2024 - Yogalakshmi Arunachalam + +- update to 2.8.2. + * Fix issue with assertion caused by pluggable schema validator by @dmontagu in #9838 + +------------------------------------------------------------------- +Mon Jul 1 16:29:01 UTC 2024 - Dirk Müller + +- update to 2.8.0: + * Update citation version automatically with new releases + * Bump pyright to `v1.1.367` and add type checking tests for + pipeline API + * Update `pydantic.v1` stub to `v1.10.17` + * General package updates to prep for `v2.8.0b1` + * Bump `pydantic-core` to `v2.20.0` + * Add support for Python 3.13 + * Update `pdm` version used for `pdm.lock` to v2.16.1 + * Update to `ruff` `v0.4.8` + * Experimental: support `defer_build` for `TypeAdapter` + * Implement `deprecated` field in json schema + * Experimental: Add pipeline API + * Add support for programmatic title generation + * Implement `fail_fast` feature + * Add `ser_json_inf_nan='strings'` mode to produce valid JSON + * Replace `__spec__.parent` with `__package__` + * Fix Outputted Model JSON Schema for `Sequence` type + * Fix typing of `_frame_depth` + * Make `ImportString` json schema compatible + * Hide private attributes (`PrivateAttr`) from `__init__` + signature in type checkers + * Make detection of `TypeVar` defaults robust to the CPython + `PEP-696` implementation + * Fix usage of `PlainSerializer` with builtin types + * Add more robust custom validation examples + * Fix ignored `strict` specification for + `StringConstraint(strict=False)` + * Use `Self` where possible + * Do not alter `RootModel.model_construct` signature in the + `mypy` plugin + * Fixed type hint of `validation_context` + * Support context being passed to TypeAdapter's + `dump_json`/`dump_python` + * Updates type signature for `Field()` constructor + * Improve builtin alias generators + * Fix typing of `TypeAdapter` + * Add fallback default value for private fields in + `__setstate__` of BaseModel + * Support `PEP 746` + * Allow validator and serializer functions to have default + values + * Fix bug with mypy plugin's handling of covariant `TypeVar` + fields + * Fix multiple annotation / constraint application logic + * Respect `regex` flags in validation and json schema + * Fix type hint on `IpvAnyAddress` + * Allow a field specifier on `__pydantic_extra__` + * Use normalized case for file path comparison + * Modify constraint application logic to allow field + constraints on `Optional[Decimal]` + * `validate_call` type params fix + * Check all warnings returned by pytest.warns() + * Reuse `re.Pattern` object in regex patterns to allow for + regex flags +- drop support-pytest-8.patch (upstream) + +------------------------------------------------------------------- +Sun Jun 30 20:44:51 UTC 2024 - Dirk Müller + +- drop optional email-validator dependency + +------------------------------------------------------------------- +Mon Jun 24 15:45:05 UTC 2024 - Dirk Müller + +- update to 2.7.4: + * Bump `pydantic.v1` to `v1.10.16` reference + * Specify `recursive_guard` as kwarg in `FutureRef._evaluate` + +------------------------------------------------------------------- +Thu Jun 6 14:14:46 UTC 2024 - Dirk Müller + +- update to 2.7.3: + * Bump `pydantic-core` to `v2.18.4` + * Fix u style unicode strings in python @samuelcolvin in + pydantic/jiter#110 + * Replace `__spec__.parent` with `__package__` + * Fix validation of `int`s with leading unary minus + * Fix `str` subclass validation for enums + * Support `BigInt`s in `Literal`s and `Enum`s + * Fix: uuid - allow `str` subclass as input + +------------------------------------------------------------------- +Thu May 30 04:56:19 UTC 2024 - Steve Kowalik + +- Add patch support-pytest-8.patch: + * Support changes in pytest 8.x. + +------------------------------------------------------------------- +Sat Apr 27 07:45:31 UTC 2024 - Dirk Müller + +- update to 2.7.1: + * Bump `pydantic-core` to `v2.18.2` + * Ftp and Websocket connection strings support + * Use field description for RootModel schema description when + there is `…` + * Fix `validation_alias` behavior with `model_construct` for + `AliasChoices` and `AliasPath` + * Revert `typing.Literal` and import it outside the + TYPE_CHECKING block + * Fix `Secret` serialization schema, applicable for unions + * Fix `strict` application to `function-after` with + `use_enum_values` + * Address case where `model_construct` on a class which defines + `model_post_init` fails with `AttributeError` + * Fix `model_json_schema` with config types + * Support multiple zeros as an `int` + * Fix validation of `int`s with leading unary plus + * Fix interaction between `extra != 'ignore'` and + `from_attributes=True` + * Handle error from `Enum`'s `missing` function as + `ValidationError` + * Fix memory leak with `Iterable` validation + * Adopt `jiter` `v0.2.0` + * Extract attribute docstrings from `FieldInfo.description` + * Add a `with_config` decorator to comply with typing spec + * Allow an optional separator splitting the value and unit of + the result of `ByteSize.human_readable` + * Add generic `Secret` base type + * Make use of `Sphinx` inventories for cross references in docs + * Add environment variable to disable plugins + * Add support for `deprecated` fields + * Allow `field_serializer('*')` + * Handle a case when `model_config` is defined as a model + property + * Update `create_model()` to support `typing.Annotated` as + input + * Add `ClickhouseDsn` support + * Add support for `re.Pattern[str]` to `pattern` field + * Support for `serialize_as_any` runtime setting + * Add support for `typing.Self` + * Ability to pass `context` to serialization + * Add feedback widget to docs with flarelytics integration + * Support for parsing partial JSON strings in Python + * Add support for field level number to str coercion option + * Update `warnings` parameter for serialization utilities to + allow raising a warning + +------------------------------------------------------------------- +Sat Mar 16 11:56:01 UTC 2024 - Dirk Müller + +- update to 2.6.4: + * Fix usage of `AliasGenerator` with `computed_field` decorator + * Fix nested discriminated union schema gen, pt 2 + * Fix bug with no_strict_optional=True caused by API deferral + +------------------------------------------------------------------- +Thu Mar 7 03:28:00 UTC 2024 - Steve Kowalik + +- Update to 2.6.3 (bsc#1222806, CVE-2024-3772): + * Fix inheriting `Field` annotations in dataclasses + * Fix warning for tuple of wrong size in `Union` + * Fix `computed_field` JSON serializer `exclude_none` behavior + * Check for `email-validator` version >= 2.0 + * Add `NatsDsn` + * Add `ConfigDict.ser_json_inf_nan` + * Support `AliasGenerator` usage + * Support `yyyy-MM-DD` datetime parsing + * Added bits conversions to the `ByteSize` class + * Add `eval_type_backport` to handle union operator + * Add support for `dataclass` fields `init` + * Implement pickling for `ValidationError` + * Add unified tuple validator that can handle "variadic" tuples via PEP-646 + * Drop Python3.7 support + * Make `@validate_call` return a function instead of a custom descriptor + * Introducing `classproperty` decorator for `model_computed_fields` + * Move `getattr` warning in deprecated `BaseConfig` + * Only hash `model_fields`, not whole `__dict__` + * Fix overload position of `computed_field` + * Fix issue `unittest.mock` deprecation warnings + * Fix `to_snake` conversion + * Add support for field `alias` in `dataclass` signature + * Fix ordering of keys in `__dict__` with `model_construct` call + * Fix usage of `@deprecated` + * Add more support for private attributes in `model_construct` call + * Support `pydantic.Field(repr=False)` in dataclasses + * Override `dataclass_transform` behavior for `RootModel` + * Refactor signature generation for simplicity + * Fix ordering bug of PlainValidator annotation + * Fix `exclude_none` for json serialization of `computed_field`s + * Support yyyy-MM-DD string for datetimes + * Fix memory leak with recursive definitions creating reference cycles + * Add `ConfigDict.ser_json_inf_nan` + * Fix validation of `Literal` from JSON keys when used as `dict` key + * Fix bug re `custom_init` on members of `Union` + * Fix `JsonValue` `bool` serialization + * Fix handling of unhashable inputs with `Literal` in `Union`s + Fix package description limit + * Allow plugins to catch non `ValidationError` errors + * Added `validation_error_cause` to config + * Allow `str` as argument to `Discriminator` + * Add `SchemaSerializer.__reduce__` method to enable pickle serialization + * Properly rebuild the `FieldInfo` when a forward ref gets evaluated + * Fix failure to load `SecretStr` from JSON (regression in v2.4) + * Fix `defer_build` behavior with `TypeAdapter` + * Fix: update `TypeVar` handling when default is not set + * Raise an error when deleting frozen (model) fields + * Use generated alias for aliases that are not specified otherwise + * Fix: support `pydantic.Field(kw_only=True)` with inherited dataclasses + * Support `validate_call` decorator for methods in classes with `__slots__` + * Fix pydantic dataclass problem with `dataclasses.field` default + * Support `|` operator (Union) in PydanticRecursiveRef + * Add support for `NotRequired` generics in `TypedDict` + * Added fix for signature of inherited dataclass + * `PrivateAttr` is passed from `Annotated` default position + * Don't decode bytes (which may not be UTF8) when displaying SecretBytes + * Use `classmethod` instead of `classmethod[Any, Any, Any]` + * Clearer error on invalid Plugin + * Correct pydantic dataclasses import + * Fix `definition-ref` bug with `Dict` keys + * Don't accept `NaN` in float and decimal constraints + * Add `lax_str` and `lax_int` support for enum values not inherited + from str/int + * Fix: proper pluralization in `ValidationError` messages + * Disallow the string `'-'` as `datetime` input + * Fix: NaN and Inf float serialization + * Implement optional `number` to `str` coercion + * Add `BaseModel.model_validate_strings` and `TypeAdapter.validate_strings` + * Add Pydantic `plugins` experimental implementation + * Do not override `model_post_init` in subclass with private attrs + * Fix config detection for `TypedDict` from grandparent classes + * Fix hash function generation for frozen models with unusual MRO + * Make `strict` config overridable in field for Path + * Use `ser_json_` on default in `GenerateJsonSchema` + * Adding a check that alias is validated as an identifier for Python + * Raise an error when computed field overrides field + * Enforce behavior of private attributes having double leading underscore + * Fix generic dataclass fields mutation bug (when using `TypeAdapter`) + * Fix `TypeError` on `model_validator` in `wrap` mode + * Fixed a regular expression denial of service issue by limiting whitespaces + * Fix handling of `UUID` values having `UUID.version=None` + * Fix `__iter__` returning private `cached_property` info + * Make ModelWrapValidator protocols generic + * Make shadowing attributes a warning instead of an error + * Document `Base64Str` and `Base64Bytes` + * Fix `config.defer_build` for serialization first cases + * Support `__get_validators__` + * Replace MiMalloc w/ default allocator + * Cleaner error for invalid input to `Path` fields + * Add section about Constrained classes to the Migration Guide + * Fix issue where generic models couldn't be parametrized with BaseModel + * add field_serializer to computed_field + * fix dataclass annotated before validator called twice + * Add benchmark representing FastAPI startup time + * Fix json_encoders for Enum subclasses + * Revert "Fix default port for mongosrv DSNs (#6827)" + * Do not require `validate_assignment` to use `Field.frozen` + * Fix generic computed fields + * Handle non-json native enum values + * Include Field extra keys name in warning + * Skip FieldInfo merging when unnecessary + * Add `StringConstraints` for use as Annotated metadata + * Fix incorrect subclass check for secretstr + * Mypy plugin for settings + * fast-path checking finite decimals + * Fix pydantic dataclasses that use slots with default values + * Fix inheritance of hash function for frozen models + * Error if an invalid field name is used with Field + * Add `GenericModel` to `MOVED_IN_V2` + * remove email validation from the north star benchmark + * Fix default port for mongosrv DSNs + * Fix serialization issue with `InstanceOf` + * Add back support for `json_encoders` + * Use `WeakValueDictionary` to fix generic memory leak + * Add `config.defer_build` to optionally make model building lazy + * Revise the section on required / optional / nullable fields. + * Replace TransformSchema with GetPydanticSchema + * Fix serialization for IPvAny + * Touch up Decimal validator + * Handle function validators in a discriminated union + * Fix pydantic dataclass problem with dataclasses.field default_factory + * Produce more accurate signatures for pydantic dataclasses + * Ignore unrecognized fields from dataclasses metadata +- Drop patches Fix-Python-3.12-test-failures.patch and + ignore-urllib3-pyopenssl-warning.patch +- Switch to pyproject macros. +- Inject mulitbuild. + +------------------------------------------------------------------- +Mon Jan 22 09:12:28 UTC 2024 - Dirk Müller + +- update to 1.10.14: + * Update install.md + * Fixes ci to only deploy docs on release + * Fix cached_property handling in dataclasses when copied + +------------------------------------------------------------------- +Thu Nov 16 09:58:50 UTC 2023 - Dirk Müller + +- update to 1.10.13: + * Fix: Add max length check to `pydantic.validate_email` + * Docs: Fix pip commands to install v1 + * Fixes the `maxlen` property being dropped on `deque` + validation. Happened only if the deque item has been typed. + Changes the `_validate_sequence_like` func, #6581 by + * Importing create_model in tools.py through relative path + instead of absolute path - so that it doesn't import V2 code + when copied over to V2 branch, #6361 by @SharathHuddar + * Add Pydantic `Json` field support to settings management, + * Fixed literal validator errors for unhashable values + * Fixed bug with generics receiving forward refs + * Update install method of FastAPI for internal tests in CI, + #6117 by @Kludex +- add Fix-Python-3.12-test-failures.patch: fix test fails with + Python 3.12 + +------------------------------------------------------------------- +Wed Jul 5 13:07:17 UTC 2023 - Dirk Müller + +- update to 1.10.9: + * Fix trailing zeros not ignored in Decimal validation + * Fix mypy plugin for v1.4.0 + * Add future and past date hypothesis strategies + * Discourage usage of Cython 3 with Pydantic 1.x + +------------------------------------------------------------------- +Thu May 25 07:32:32 UTC 2023 - Daniel Garcia + +- Update to v1.10.8 + * Fix a bug in `Literal` usage with `typing-extension==4.6.0`, #5826 + by @hramezani + * This solves the (closed) issue #3849 where aliased fields that use + discriminated union fail to validate when the data contains the + non-aliased field name, #5736 by @benwah + * Update email-validator dependency to >=2.0.0post2, #5627 by + @adriangb + * update `AnyClassMethod` for changes in + [python/typeshed#9771](https://github.com/python/typeshed/issues/9771), + #5505 by @ITProKyle + +------------------------------------------------------------------- +Mon Mar 27 10:00:20 UTC 2023 - Dirk Müller + +- update to 1.10.7: + * Fix creating schema from model using `ConstrainedStr` with + `regex` as dict key + * Address bug in mypy plugin caused by + explicit_package_bases=True + * Add implicit defaults in the mypy plugin for Field with no + default argument + * Fix schema generated for Enum values used as Literals in + discriminated unions + * Fix mypy failures caused by the pydantic mypy plugin when + users define `from_orm` in their own classes + * Fix `InitVar` usage with pydantic dataclasses, mypy version + `1.1.1` and the custom mypy plugin + * Implement logic to support creating validators from non + standard callables by using defaults to identify them and + unwrapping `functools.partial` and `functools.partialmethod` + when checking the signature + * Fix mypy plugin for v1.1.1, and fix `dataclass_transform` + decorator for pydantic dataclasses + * Raise `ValidationError`, not `ConfigError`, when a + discriminator value is unhashable + * Fix broken parametrized bases handling with `GenericModel`s + with complex sets of models + * Invalidate mypy cache if plugin config changes + * Fix `RecursionError` when deep-copying dataclass types + wrapped by pydantic + * Fix `X | Y` union syntax breaking `GenericModel` + +------------------------------------------------------------------- +Thu Mar 16 07:18:03 UTC 2023 - Daniel Garcia + +- Disable DeprecationWarning in tests to avoid error with the latest + setuptools and pkg_resources deprecation + +------------------------------------------------------------------- +Mon Jan 2 20:22:05 UTC 2023 - Dirk Müller + +- update to v1.10.4: + * Change dependency to typing-extensions>=4.2.0, #4885 by @samuelcolvin + * fix parsing of custom root models, #4883 by @gou177 + * fix: use dataclass proxy for frozen or empty dataclasses, #4878 by + @PrettyWood + * Fix schema and schema_json on models where a model instance is a one of + default values, #4781 by @Bobronium + * Add Jina AI to sponsors on docs index page, #4767 by @samuelcolvin + * fix: support assignment on DataclassProxy, #4695 by @PrettyWood + * Add postgresql+psycopg as allowed scheme for PostgreDsn to make it + usable with SQLAlchemy 2, #4689 by @morian + * Allow dict schemas to have both patternProperties and + additionalProperties, #4641 by @jparise + * Fixes error passing None for optional lists with unique_items, #4568 by + @mfulgo + * Fix GenericModel with Callable param raising a TypeError, #4551 by + @mfulgo + * Fix field regex with StrictStr type annotation, #4538 by @sisp + * Correct dataclass_transform keyword argument name from field_descriptors + to field_specifiers, #4500 by @samuelcolvin + * fix: avoid multiple calls of __post_init__ when dataclasses are + inherited, #4487 by @PrettyWood + * Reduce the size of binary wheels, #2276 by @samuelcolvin + +------------------------------------------------------------------- +Fri Sep 9 00:47:25 UTC 2022 - Steve Kowalik + +- Update to 1.10.2: + * Prevent long (length > 4_300) strings/bytes as input to int fields, see + python/cpython#95778 and CVE-2020-10735 + * fix: dataclass wrapper was not always called + * Use tomllib on Python 3.11 when parsing mypy configuration + * Basic fix of GenericModel cache to detect order of arguments in Union models + * Fix mypy plugin when using bare types like list and dict as default_factory + * Add __hash__ method to pydancic.color.Color class + * Refactor the whole pydantic dataclass decorator to really act like its + standard lib equivalent. It hence keeps __eq__, __hash__, ... and makes + comparison with its non-validated version possible. + * Now that Config.extra is supported, dataclass ignores by default extra + arguments (like BaseModel) + * Fix PEP487 __set_name__ protocol in BaseModel for PrivateAttrs + * Allow for custom parsing of environment variables via parse_env_var in + Config + * Fix StrictStr does not raise ValidationError when max_length is present + in Field + * Make SecretStr and SecretBytes hashable + * Fix StrictBytes does not raise ValidationError when max_length is present + in Field + * Add support for bare type + * Support Python 3.11, including binaries for 3.11 in PyPI + * Add support for re.Pattern + * Fix __post_init_post_parse__ is incorrectly passed keyword arguments when + no __post_init__ is defined + * Fix implicitly importing ForwardRef and Callable from pydantic.typing + instead of typing and also expose MappingIntStrAny + * remove Any types from the dataclass decorator so it can be used with the + disallow_any_expr mypy option + * fix "extra fields not permitted" error when dataclass with Extra.forbid + is validated multiple times + * Discriminated union models now use oneOf instead of anyOf when generating + OpenAPI schema definitions + * Allow type checkers to infer inner type of Json type. Json[list[str]] will + be now inferred as list[str] + * Allow empty string aliases by using a alias is not None check, rather + than bool(alias) + * Use parent model's Config when validating nested NamedTuple fields + * Update BaseModel.construct to work with aliased Fields + * Catch certain raised errors in smart_deepcopy and revert to deepcopy if so + * Add Config.anystr_upper and to_upper kwarg to constr and conbytes + * Fix JSON schema for set and frozenset when they include default values + * Teach the mypy plugin that methods decorated by @validator are classmethods + * Improve mypy plugin's ability to detect required fields + * Support fields of type Type[] in schema + * Adds reserved word check to signature generation logic + * Fix Json strategy failure for the complex nested field + * Add JSON-compatible float constraint allow_inf_nan + * Remove undefined behaviour when env_prefix had characters in common with + env_nested_delimiter + * Support generics model with create_model + * allow submodels to overwrite extra field info + * support overwriting dunder attributes of BaseModel instances + * Support kw_only in dataclasses + * Add comparison method for Color class + * created new function to_lower_camel() for "non pascal case" camel case + * Add checks to default and default_factory arguments in Mypy plugin + * Fix parsing of very small numeric timedelta values + * Update SecretsSettingsSource to respect config.case_sensitive + * Add support for multiple dotenv files + * Raise an explicit ConfigError when multiple fields are incorrectly set + for a single validator + * Allow ellipsis on Fields inside Annotated for TypedDicts required + * Catch overflow errors in int_validator + * validate_arguments decorator now supports alias + * Add ability to use Final in a field type annotation + * Update requirement to typing_extensions>=4.1.0 to guarantee + dataclass_transform is available +- Remove patch remove-pkg_resources.patch: + * Included upstream. +- Add patch ignore-urllib3-pyopenssl-warning.patch: + * Ignore DeprecationWarning until requests-toolbelt is fixed. +- Update {Build,}Requires to email-validator package. + +------------------------------------------------------------------- +Tue Jul 19 09:20:43 UTC 2022 - Steve Kowalik + +- Add patch remove-pkg_resources.patch: + * Use packaging, not pkg_resources for versions. + +------------------------------------------------------------------- +Sat Jun 18 13:37:28 UTC 2022 - Michael Ströder + +- Update to 1.9.1 + * Limit the size of generics._generic_types_cache and generics._assigned_parameters + to avoid unlimited increase in memory usage, #4083 by @samuelcolvin + * Add Jupyverse and FPS as Jupyter projects using pydantic, #4082 by @davidbrochart + * Speedup __isinstancecheck__ on pydantic models when the type is not a model, + may also avoid memory "leaks", #4081 by @samuelcolvin + * Fix in-place modification of FieldInfo that caused problems with + PEP 593 type aliases, #4067 by @adriangb + * Add support for autocomplete in VS Code via __dataclass_transform__ + when using pydantic.dataclasses.dataclass, #4006 by @giuliano-oliveira + * Remove benchmarks from codebase and docs, #3973 by @samuelcolvin + * Typing checking with pyright in CI, improve docs on vscode/pylance/pyright, #3972 by @samuelcolvin + * Fix nested Python dataclass schema regression, #3819 by @himbeles + * Update documentation about lazy evaluation of sources for Settings, #3806 by @garyd203 + * Prevent subclasses of bytes being converted to bytes, #3706 by @samuelcolvin + * Fixed "error checking inheritance of" when using PEP585 and PEP604 type hints, #3681 by @aleksul + * Allow self referencing ClassVars in models, #3679 by @samuelcolvin + * Fix issue with self-referencing dataclass, #3675 by @uriyyo + * Include non-standard port numbers in rendered URLs, #3652 by @dolfinus + * Config.copy_on_model_validation does a deep copy and not a shallow one, #3641 by @PrettyWood + * fix: clarify that discriminated unions do not support singletons, #3636 by @tommilligan + * Add read_text(encoding='utf-8') for setup.py, #3625 by @hswong3i + * Fix JSON Schema generation for Discriminated Unions within lists, #3608 by @samuelcolvin + +------------------------------------------------------------------- +Wed Feb 2 04:12:37 UTC 2022 - Steve Kowalik + +- Skip some truculent tests. +- Clean up non-required Python 3.6 {Build,}Requires. + +------------------------------------------------------------------- +Wed Jan 5 16:08:23 UTC 2022 - Ben Greiner + +- Update to 1.9.0 + * add python 3.10 support, #2885 by @PrettyWood + * Discriminated unions, #619 by @PrettyWood + * Config.smart_union for better union logic, #2092 by @PrettyWood + * Binaries for Macos M1 CPUs, #3498 by @samuelcolvin + * Complex types can be set via nested environment variables, e.g. + foo___bar, #3159 by @Air-Mark + * add a dark mode to pydantic documentation, #2913 by @gbdlin + * Add support for autocomplete in VS Code via + __dataclass_transform__, #2721 by @tiangolo + * Add "exclude" as a field parameter so that it can be configured + using model config, #660 by @daviskirk +- Full changelog in HISTORY.md + +------------------------------------------------------------------- +Thu May 13 11:07:30 UTC 2021 - Markéta Machová + +- Update to 1.8.2 (bsc#1186019, CVE-2021-29510) + * Security fix: Fix date and datetime parsing so passing either 'infinity' + or float('inf') (or their negative values) does not cause an infinite loop + * Allow passing json_encoders in class kwargs + * support arbitrary types with custom __eq__ + * Hypothesis plugin for testing + * support for NamedTuple and TypedDict + * Support Annotated hints on model fields + * frozen parameter on Config to allow models to be hashed + * Breaking Change, remove old deprecation aliases from v1 + * Breaking Change: always validate only first sublevel items with each_item + * many more changes, see upstream changelog + +------------------------------------------------------------------- +Fri Jan 8 13:10:40 UTC 2021 - Markéta Machová + +- Update to 1.7.3 + * python 3.9 support + * Private model attributes + * "secrets files" support in BaseSettings + * convert stdlib dataclasses to pydantic dataclasses and use stdlib dataclasses in models + * few bugfixes +- Drop validate-config.patch + +------------------------------------------------------------------- +Mon Dec 7 01:00:22 UTC 2020 - Benjamin Greiner + +- Add dataclasses requirement for Python 3.6: Fixes Leap 15.2 build + and future TW python36 flavor gh#openSUSE/python-rpm-macros#66 + +------------------------------------------------------------------- +Mon Oct 12 08:58:44 UTC 2020 - Marketa Calabkova + +- Add upstream patch validate-config.patch which fixes build with new pytest + +------------------------------------------------------------------- +Sun Aug 2 15:14:47 UTC 2020 - John Vandenberg + +- Add optional test dependencies +- Recommend optional runtime dependency python-typing_extensions +- Remove unused runtime dependency ujson +- Update to v1.6.1 + * fix validation and parsing of nested models with default_factory +- from v1.6 + * Modify validators for conlist and conset to not have always=True + * Add port check to AnyUrl (can't exceed 65536) ports are 16 insigned + bits: 0 <= port <= 2**16-1 src: rfc793 header format + * Document default regex anchoring semantics + * Use chain.from_iterable in class_validators.py. This is a faster + and more idiomatic way of using itertools.chain. Instead of computing + all the items in the iterable and storing them in memory, they are + computed one-by-one and never stored as a huge list. + This can save on both runtime and memory space + * Add conset(), analogous to conlist() + * make pydantic errors (un)pickable + * Allow custom encoding for dotenv files + * Ensure SchemaExtraCallable is always defined to get type hints on BaseConfig + * Update datetime parser to support negative timestamps + * Update mypy, remove AnyType alias for Type[Any] + * Adjust handling of root validators so that errors are aggregated + from all failing root validators, instead of reporting on only + the first root validator to fail + * Make __modify_schema__ on Enums apply to the enum schema rather + than fields that use the enum + * Fix behavior of __all__ key when used in conjunction with index + keys in advanced include/exclude of fields that are sequences + * Subclass validators do not run when referencing a List field + defined in a parent class when each_item=True + * change schema.field_class_to_schema to support frozenset in schema + * Call __modify_schema__ only for the field schema + * Move the assignment of field.validate_always in fields.py so the + always parameter of validators work on inheritance + * Added support for UUID instantiation through 16 byte strings such + as b'\x12\x34\x56\x78' * 4. + This was done to support BINARY(16) columns in sqlalchemy + * Add a test assertion that default_factory can return a singleton + * Add NameEmail.__eq__ so duplicate NameEmail instances are + evaluated as equal + * Add datamodel-code-generator link in pydantic document site + * Added a "Discussion of Pydantic" section to the documentation, + with a link to "Pydantic Introduction" video + * Avoid some side effects of default_factory by calling it only + once if possible and by not setting a default value in the schema + * Added docs about dumping dataclasses to JSON + * Make BaseModel.__signature__ class-only, so getting __signature__ + from model instance will raise AttributeError + * include 'format': 'password' in the schema for secret types + * Modify schema constraints on ConstrainedFloat so that + exclusiveMinimum and minimum are not included in the schema if + they are equal to -math.inf and exclusiveMaximum and maximum are + not included if they are equal to math.inf + * Squash internal __root__ dicts in .dict() (and, by extension, in .json()) + * Move const validator to post-validators so it validates the parsed value + * Fix model validation to handle nested literals + * Remove user_required = True from RedisDsn, neither user nor + password are required + * Remove extra allOf from schema for fields with Union and custom Field + * Updates OpenAPI schema generation to output all enums as separate + models. Instead of inlining the enum values in the model schema, + models now use a $ref property to point to the enum definition + +------------------------------------------------------------------- +Tue Jun 9 19:24:27 UTC 2020 - Dirk Mueller + +- update to 1.5.1 + * Signature generation with `extra: allow` never uses a field name, #1418 by @prettywood + * Avoid mutating `Field` default value, #1412 by @prettywood + +------------------------------------------------------------------- +Sat Apr 18 19:11:39 UTC 2020 - Martin Hauke + +- Update to version 1.5 + * Make includes/excludes arguments for .dict(), ._iter(), ..., + immutable + * Always use a field's real name with includes/excludes in + model._iter(), regardless of by_alias, #1397 by @AlexECX + * Update constr regex example to include start and end lines, + * Confirm that shallow model.copy() does make a shallow copy of + attributes + * Renaming model_name argument of main.create_model() + to __model_name to allow using model_name as a field name + * Replace raising of exception to silent passing for non-Var + attributes in mypy plugin + * Remove typing_extensions dependency for python 3.8 + * Make SecretStr and SecretBytes initialization idempotent + * document making secret types dumpable using the json method + * fix card number length check in PaymentCardNumber, + PaymentCardBrand now inherits from str + * Have BaseModel inherit from Representation to make mypy happy + when overriding __str__ + * Allow None as input to all optional list fields + * Add datetime field to default_factory example + * Allow subclasses of known types to be encoded with superclass + encoder + * Exclude exported fields from all elements of a list/tuple of + submodels/dicts with '__all__', #1286 by @masalim2 + * Add pydantic.color.Color objects as available input for Color + fields + * In examples, type nullable fields as Optional, so that these + are valid mypy annotations + * Make pattern_validator() accept pre-compiled Pattern objects. + Fix str_validator() return type to str + * Support instance methods and class methods with + @validate_arguments + * Add default_factory argument to Field to create a dynamic + default value by passing a zero-argument callable + * add support for NewType of List, Optional, etc + * fix mypy signature for root_validator + * Fixed parsing of nested 'custom root type' models + * Add validate_arguments function decorator which checks the + arguments to a function matches type annotations + * Add __signature__ to models + * Refactor ._iter() method, 10x speed boost for dict(model) + +------------------------------------------------------------------- +Thu Mar 19 13:25:26 UTC 2020 - Marketa Calabkova + +- Update to version 1.4 + * rename Schema to Field, make it a function to placate mypy + * Implement root_validator and rename root errors from __obj__ to __root__ + * Added initvars support to post_init_post_parse + * complete rewrite of URL parsing logic + * BaseSettings now uses the special env settings to define which + environment variables to read, not aliases + * add support for assert statements inside validators + * Change the precedence of aliases so child model aliases override + parent aliases, including using alias_generator + * Add a mypy plugin for type checking BaseModel.__init__ and more + * Add support for typing.Literal for Python 3.8 + * Add a ByteSize type for converting byte string (1GB) to plain bytes + * Add support for required Optional with name: Optional[AnyType] = Field(...) + and refactor ModelField creation to preserve required parameter value + * Add __eq__ to SecretStr and SecretBytes to allow "value equals" + * Add support for nested generic models + * alias precedence logic changed so aliases on a field always take + priority over an alias from alias_generator + * many more fixes and improvements + +------------------------------------------------------------------- +Fri Sep 20 09:56:55 UTC 2019 - Tomáš Chvátal + +- Format with spec-cleaner + +------------------------------------------------------------------- +Thu Sep 19 20:25:27 UTC 2019 - Martin Hauke + +- Initial package, version 0.32.2 diff --git a/python-pydantic.spec b/python-pydantic.spec new file mode 100644 index 0000000..b5adff3 --- /dev/null +++ b/python-pydantic.spec @@ -0,0 +1,99 @@ +# +# spec file for package python-pydantic +# +# Copyright (c) 2025 SUSE LLC and contributors +# Copyright (c) 2019, Martin Hauke +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +%global flavor @BUILD_FLAVOR@%{nil} +%if "%{flavor}" == "test" +%define psuffix -test +%bcond_without test +%else +%define psuffix %{nil} +%bcond_with test +%endif +%{?sle15_python_module_pythons} +Name: python-pydantic%{psuffix} +Version: 2.12.5 +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 +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.41.5} +BuildRequires: %{python_module wheel} +BuildRequires: fdupes +BuildRequires: python-rpm-macros +%if %{with test} +BuildRequires: %{python_module Faker} +BuildRequires: %{python_module cloudpickle} +BuildRequires: %{python_module dirty-equals} +BuildRequires: %{python_module email-validator >= 2.0} +BuildRequires: %{python_module jsonschema >= 4.23.0 } +BuildRequires: %{python_module pydantic = %{version}} +BuildRequires: %{python_module pytest-benchmark} +BuildRequires: %{python_module pytest-examples} +BuildRequires: %{python_module pytest-mock} +BuildRequires: %{python_module pytest-run-parallel} +BuildRequires: %{python_module pytest} +BuildRequires: %{python_module python-dotenv >= 0.10.4} +BuildRequires: %{python_module rich} +BuildRequires: %{python_module typing-inspection} +%endif +Requires: python-annotated-types >= 0.6.0 +Requires: python-pydantic-core = 2.41.5 +Requires: python-typing-extensions >= 4.14.1 +Requires: python-typing-inspection +BuildArch: noarch +%python_subpackages + +%description +Data validation and settings management using Python type hinting. + +%prep +%autosetup -p1 -n pydantic-%{version} + +# FIXME: make it compatible with the older version of setuptools. +# make sure to remove this hack once we have a newer version of setuptools. +sed -i '/.*Programming Language :: Python :: 3\.14.*/d' pyproject.toml + +%build +%pyproject_wheel + +%install +%if %{without test} +%pyproject_install +%python_expand %fdupes %{buildroot}%{$python_sitelib} +%endif + +%check +%if %{with test} +%pytest +%endif + +%if %{without test} +%files %{python_files} +%license LICENSE +%doc README.md HISTORY.md +%{python_sitelib}/pydantic +%{python_sitelib}/pydantic-%{version}.dist-info +%endif + +%changelog diff --git a/support-pydantic-core-2.39.0.patch b/support-pydantic-core-2.39.0.patch new file mode 100644 index 0000000..c2e2d12 --- /dev/null +++ b/support-pydantic-core-2.39.0.patch @@ -0,0 +1,293 @@ +From d6c65493a8436b22733d0f04d0bb3df1bc952ac9 Mon Sep 17 00:00:00 2001 +From: Viicos <65306057+Viicos@users.noreply.github.com> +Date: Fri, 16 May 2025 15:46:24 +0200 +Subject: [PATCH 1/8] Add `UNSET` sentinel + +--- + pydantic/_internal/_generate_schema.py | 3 + + pydantic/fields.py | 4 +- + pydantic/json_schema.py | 7 +- + pyproject.toml | 2 +- + 5 files changed, 15 insertions(+), 122 deletions(-) + +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 +@@ -42,6 +42,7 @@ from zoneinfo import ZoneInfo + + import typing_extensions + from pydantic_core import ( ++ MISSING, + CoreSchema, + MultiHostUrl, + PydanticCustomError, +@@ -1050,6 +1051,8 @@ class GenerateSchema: + return core_schema.multi_host_url_schema() + elif obj is None or obj is _typing_extra.NoneType: + return core_schema.none_schema() ++ if obj is MISSING: ++ return core_schema.missing_sentinel_schema() + elif obj in IP_TYPES: + return self._ip_schema(obj) + elif obj in TUPLE_TYPES: +Index: pydantic-2.11.7/pydantic/fields.py +=================================================================== +--- pydantic-2.11.7.orig/pydantic/fields.py ++++ pydantic-2.11.7/pydantic/fields.py +@@ -15,7 +15,7 @@ from warnings import warn + + import annotated_types + import typing_extensions +-from pydantic_core import PydanticUndefined ++from pydantic_core import MISSING, PydanticUndefined + from typing_extensions import Self, TypeAlias, Unpack, deprecated + from typing_inspection import typing_objects + from typing_inspection.introspection import UNKNOWN, AnnotationSource, ForbiddenQualifier, Qualifier, inspect_annotation +@@ -392,7 +392,7 @@ class FieldInfo(_repr.Representation): + Returns: + A field object with the passed values. + """ +- if annotation is default: ++ if annotation is not MISSING and annotation is default: + raise PydanticUserError( + 'Error when building FieldInfo from annotated attribute. ' + "Make sure you don't have any field name clashing with a type annotation.", +Index: pydantic-2.11.7/pydantic/json_schema.py +=================================================================== +--- pydantic-2.11.7.orig/pydantic/json_schema.py ++++ pydantic-2.11.7/pydantic/json_schema.py +@@ -36,7 +36,7 @@ from typing import ( + ) + + import pydantic_core +-from pydantic_core import CoreSchema, PydanticOmit, core_schema, to_jsonable_python ++from pydantic_core import MISSING, CoreSchema, PydanticOmit, core_schema, to_jsonable_python + from pydantic_core.core_schema import ComputedField + from typing_extensions import TypeAlias, assert_never, deprecated, final + from typing_inspection.introspection import get_literal_values +@@ -805,6 +805,17 @@ class GenerateJsonSchema: + result['type'] = 'null' + return result + ++ def missing_sentinel_schema(self, schema: core_schema.MissingSentinelSchema) -> JsonSchemaValue: ++ """Generates a JSON schema that matches the `MISSING` sentinel value. ++ ++ Args: ++ schema: The core schema. ++ ++ Returns: ++ The generated JSON schema. ++ """ ++ raise PydanticOmit ++ + def enum_schema(self, schema: core_schema.EnumSchema) -> JsonSchemaValue: + """Generates a JSON schema that matches an Enum value. + +@@ -1109,7 +1120,7 @@ class GenerateJsonSchema: + json_schema = self.generate_inner(schema['schema']) + + default = self.get_default_value(schema) +- if default is NoDefault: ++ if default is NoDefault or default is MISSING: + return json_schema + + # we reflect the application of custom plain, no-info serializers to defaults for +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.35.1' ++ return __pydantic_core_version__ == '2.39.0' + + + def parse_mypy_version(version: str) -> tuple[int, int, int]: +Index: pydantic-2.11.7/docs/concepts/experimental.md +=================================================================== +--- pydantic-2.11.7.orig/docs/concepts/experimental.md ++++ pydantic-2.11.7/docs/concepts/experimental.md +@@ -502,3 +502,49 @@ args, kwargs = val.validate_json('{"args + print(args, kwargs) + #> ('arg1',) {'extra': 1} + ``` ++ ++## `MISSING` sentinel ++ ++The `MISSING` sentinel is a singleton indicating a field value was not provided during validation. ++ ++This singleton can be used as a default value, as an alternative to `None` when it has an explicit ++meaning. During serialization, any field with `MISSING` as a value is excluded from the output. ++ ++```python ++from typing import Union ++ ++from pydantic import BaseModel ++from pydantic.experimental.missing_sentinel import MISSING ++ ++ ++class Configuration(BaseModel): ++ timeout: Union[int, None, MISSING] = MISSING ++ ++ ++# configuration defaults, stored somewhere else: ++defaults = {'timeout': 200} ++ ++conf = Configuration() ++ ++# `timeout` is excluded from the serialization output: ++conf.model_dump() ++# {} ++ ++# The `MISSING` value doesn't appear in the JSON Schema: ++Configuration.model_json_schema()['properties']['timeout'] ++#> {'anyOf': [{'type': 'integer'}, {'type': 'null'}], 'title': 'Timeout'}} ++ ++ ++# `is` can be used to discrimate between the sentinel and other values: ++timeout = conf.timeout if conf.timeout is not MISSING else defaults['timeout'] ++``` ++ ++This feature is marked as experimental because it relies on the draft [PEP 661](https://peps.python.org/pep-0661/), introducing sentinels in the standard library. ++ ++As such, the following limitations currently apply: ++ ++* Static type checking of sentinels is only supported with Pyright ++ [1.1.402](https://github.com/microsoft/pyright/releases/tag/1.1.402) ++ or greater, and the `enableExperimentalFeatures` type evaluation setting ++ should be enabled. ++* Pickling of models containing `MISSING` as a value is not supported. +Index: pydantic-2.11.7/docs/errors/validation_errors.md +=================================================================== +--- pydantic-2.11.7.orig/docs/errors/validation_errors.md ++++ pydantic-2.11.7/docs/errors/validation_errors.md +@@ -1384,6 +1384,27 @@ except ValidationError as exc: + #> 'missing_positional_only_argument' + ``` + ++## `missing_sentinel_error` ++ ++This error is raised when the experimental `MISSING` sentinel is the only value allowed, and wasn't ++provided during validation: ++ ++```python ++from pydantic import BaseModel, ValidationError ++from pydantic.experimental.missing_sentinel import MISSING ++ ++ ++class Model(BaseModel): ++ f: MISSING ++ ++ ++try: ++ Model(f=1) ++except ValidationError as exc: ++ print(repr(exc.errors()[0]['type'])) ++ #> 'missing_sentinel_error' ++``` ++ + ## `model_attributes_type` + + This error is raised when the input value is not a valid dictionary, model instance, or instance that fields can be extracted from: +Index: pydantic-2.11.7/pydantic/experimental/missing_sentinel.py +=================================================================== +--- /dev/null ++++ pydantic-2.11.7/pydantic/experimental/missing_sentinel.py +@@ -0,0 +1,5 @@ ++"""Experimental module exposing a function a `MISSING` sentinel.""" ++ ++from pydantic_core import MISSING ++ ++__all__ = ('MISSING',) +Index: pydantic-2.11.7/pyproject.toml +=================================================================== +--- pydantic-2.11.7.orig/pyproject.toml ++++ pydantic-2.11.7/pyproject.toml +@@ -46,7 +46,7 @@ dependencies = [ + '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.35.1', ++ 'pydantic-core==2.39.0', + 'typing-inspection>=0.4.0', + ] + dynamic = ['version', 'readme'] +Index: pydantic-2.11.7/tests/test_missing_sentinel.py +=================================================================== +--- /dev/null ++++ pydantic-2.11.7/tests/test_missing_sentinel.py +@@ -0,0 +1,71 @@ ++import pickle ++from typing import Union ++ ++import pytest ++from pydantic_core import MISSING, PydanticSerializationUnexpectedValue ++ ++from pydantic import BaseModel, TypeAdapter, ValidationError ++ ++ ++def test_missing_sentinel_model() -> None: ++ class Model(BaseModel): ++ f: Union[int, MISSING] = MISSING ++ g: MISSING = MISSING ++ ++ m1 = Model() ++ ++ assert m1.model_dump() == {} ++ assert m1.model_dump_json() == '{}' ++ ++ m2 = Model.model_validate({'f': MISSING, 'g': MISSING}) ++ ++ assert m2.f is MISSING ++ assert m2.g is MISSING ++ ++ m3 = Model(f=1) ++ ++ assert m3.model_dump() == {'f': 1} ++ assert m3.model_dump_json() == '{"f":1}' ++ ++ ++def test_missing_sentinel_type_adapter() -> None: ++ """Note that this usage isn't explicitly supported (and useless in practice).""" ++ ++ # TODO Remove annotation with PEP 747: ++ ta: TypeAdapter[object] = TypeAdapter(MISSING) ++ ++ assert ta.validate_python(MISSING) is MISSING ++ ++ with pytest.raises(ValidationError) as exc_info: ++ ta.validate_python(1) ++ ++ assert exc_info.value.errors()[0]['type'] == 'missing_sentinel_error' ++ ++ assert ta.dump_python(MISSING) is MISSING ++ ++ with pytest.raises(PydanticSerializationUnexpectedValue): ++ ta.dump_python(1) ++ ++ ++# Defined in module to be picklable: ++class ModelPickle(BaseModel): ++ f: Union[int, MISSING] = MISSING ++ ++ ++@pytest.mark.xfail(reason="PEP 661 sentinels aren't picklable yet in the experimental typing-extensions implementation") ++def test_missing_sentinel_pickle() -> None: ++ m = ModelPickle() ++ m_reconstructed = pickle.loads(pickle.dumps(m)) ++ ++ assert m_reconstructed.f is MISSING ++ ++ ++def test_missing_sentinel_json_schema() -> None: ++ class Model(BaseModel): ++ f: Union[int, MISSING] = MISSING ++ g: MISSING = MISSING ++ h: MISSING ++ ++ assert Model.model_json_schema()['properties'] == { ++ 'f': {'title': 'F', 'type': 'integer'}, ++ } From 34e6e0e6347b9e071b1f2fe76e986716775442d9fa55f5689022484d0eb0c410 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Date: Fri, 12 Dec 2025 09:26:39 +0000 Subject: [PATCH 2/2] Refresh source with osc service mr OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-pydantic?expand=0&rev=82 --- pydantic-2.12.5.tar.gz | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydantic-2.12.5.tar.gz b/pydantic-2.12.5.tar.gz index 309fb69..08bd452 100644 --- a/pydantic-2.12.5.tar.gz +++ b/pydantic-2.12.5.tar.gz @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 -size 821591 +oid sha256:c79f06e47b8a49593a02ad0b3a0102089c4d22c55666183614dbbad33c12ae73 +size 1976436