Sync from SUSE:SLFO:Main python-pydantic revision 9aba761bec11d43ce6a42a26c291888f
This commit is contained in:
424
bump-pydantic-core-2.35.1.patch
Normal file
424
bump-pydantic-core-2.35.1.patch
Normal file
@@ -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: ...
|
233
field-name-validator-core-schemas.patch
Normal file
233
field-name-validator-core-schemas.patch
Normal file
@@ -0,0 +1,233 @@
|
||||
From cd0d37c4c18f24b5624ae86cfe5288cd82edf2c1 Mon Sep 17 00:00:00 2001
|
||||
From: Douwe Maan <hi@douwe.me>
|
||||
Date: Wed, 16 Apr 2025 18:01:58 +0000
|
||||
Subject: [PATCH 1/4] Stop using deprecated field_name argument on validation
|
||||
function schemas
|
||||
|
||||
---
|
||||
docs/concepts/types.md | 2 +-
|
||||
pydantic/_internal/_generate_schema.py | 45 ++++++++++----------------
|
||||
pydantic/functional_validators.py | 5 +--
|
||||
tests/test_validators.py | 2 +-
|
||||
4 files changed, 20 insertions(+), 34 deletions(-)
|
||||
|
||||
Index: pydantic-2.11.7/docs/concepts/types.md
|
||||
===================================================================
|
||||
--- pydantic-2.11.7.orig/docs/concepts/types.md
|
||||
+++ pydantic-2.11.7/docs/concepts/types.md
|
||||
@@ -979,7 +979,7 @@ class CustomType:
|
||||
cls, source_type: Any, handler: GetCoreSchemaHandler
|
||||
) -> core_schema.CoreSchema:
|
||||
return core_schema.with_info_after_validator_function(
|
||||
- cls.validate, handler(int), field_name=handler.field_name
|
||||
+ cls.validate, handler(int)
|
||||
)
|
||||
|
||||
|
||||
Index: pydantic-2.11.7/pydantic/_internal/_generate_schema.py
|
||||
===================================================================
|
||||
--- pydantic-2.11.7.orig/pydantic/_internal/_generate_schema.py
|
||||
+++ pydantic-2.11.7/pydantic/_internal/_generate_schema.py
|
||||
@@ -222,7 +222,6 @@ def filter_field_decorator_info_by_field
|
||||
def apply_each_item_validators(
|
||||
schema: core_schema.CoreSchema,
|
||||
each_item_validators: list[Decorator[ValidatorDecoratorInfo]],
|
||||
- field_name: str | None,
|
||||
) -> core_schema.CoreSchema:
|
||||
# This V1 compatibility shim should eventually be removed
|
||||
|
||||
@@ -234,21 +233,20 @@ def apply_each_item_validators(
|
||||
# note that this won't work for any Annotated types that get wrapped by a function validator
|
||||
# but that's okay because that didn't exist in V1
|
||||
if schema['type'] == 'nullable':
|
||||
- schema['schema'] = apply_each_item_validators(schema['schema'], each_item_validators, field_name)
|
||||
+ schema['schema'] = apply_each_item_validators(schema['schema'], each_item_validators)
|
||||
return schema
|
||||
elif schema['type'] == 'tuple':
|
||||
if (variadic_item_index := schema.get('variadic_item_index')) is not None:
|
||||
schema['items_schema'][variadic_item_index] = apply_validators(
|
||||
schema['items_schema'][variadic_item_index],
|
||||
each_item_validators,
|
||||
- field_name,
|
||||
)
|
||||
elif is_list_like_schema_with_items_schema(schema):
|
||||
inner_schema = schema.get('items_schema', core_schema.any_schema())
|
||||
- schema['items_schema'] = apply_validators(inner_schema, each_item_validators, field_name)
|
||||
+ schema['items_schema'] = apply_validators(inner_schema, each_item_validators)
|
||||
elif schema['type'] == 'dict':
|
||||
inner_schema = schema.get('values_schema', core_schema.any_schema())
|
||||
- schema['values_schema'] = apply_validators(inner_schema, each_item_validators, field_name)
|
||||
+ schema['values_schema'] = apply_validators(inner_schema, each_item_validators)
|
||||
else:
|
||||
raise TypeError(
|
||||
f'`@validator(..., each_item=True)` cannot be applied to fields with a schema of {schema["type"]}'
|
||||
@@ -840,7 +838,7 @@ class GenerateSchema:
|
||||
extras_keys_schema=extras_keys_schema,
|
||||
model_name=cls.__name__,
|
||||
)
|
||||
- inner_schema = apply_validators(fields_schema, decorators.root_validators.values(), None)
|
||||
+ inner_schema = apply_validators(fields_schema, decorators.root_validators.values())
|
||||
inner_schema = apply_model_validators(inner_schema, model_validators, 'inner')
|
||||
|
||||
model_schema = core_schema.model_schema(
|
||||
@@ -1380,9 +1378,9 @@ class GenerateSchema:
|
||||
field_info.validate_default = True
|
||||
each_item_validators = [v for v in this_field_validators if v.info.each_item is True]
|
||||
this_field_validators = [v for v in this_field_validators if v not in each_item_validators]
|
||||
- schema = apply_each_item_validators(schema, each_item_validators, name)
|
||||
+ schema = apply_each_item_validators(schema, each_item_validators)
|
||||
|
||||
- schema = apply_validators(schema, this_field_validators, name)
|
||||
+ schema = apply_validators(schema, this_field_validators)
|
||||
|
||||
# the default validator needs to go outside of any other validators
|
||||
# so that it is the topmost validator for the field validator
|
||||
@@ -1972,7 +1970,7 @@ class GenerateSchema:
|
||||
collect_init_only=has_post_init,
|
||||
)
|
||||
|
||||
- inner_schema = apply_validators(args_schema, decorators.root_validators.values(), None)
|
||||
+ inner_schema = apply_validators(args_schema, decorators.root_validators.values())
|
||||
|
||||
model_validators = decorators.model_validators.values()
|
||||
inner_schema = apply_model_validators(inner_schema, model_validators, 'inner')
|
||||
@@ -2484,24 +2482,16 @@ class GenerateSchema:
|
||||
|
||||
_VALIDATOR_F_MATCH: Mapping[
|
||||
tuple[FieldValidatorModes, Literal['no-info', 'with-info']],
|
||||
- Callable[[Callable[..., Any], core_schema.CoreSchema, str | None], core_schema.CoreSchema],
|
||||
+ Callable[[Callable[..., Any], core_schema.CoreSchema], core_schema.CoreSchema],
|
||||
] = {
|
||||
- ('before', 'no-info'): lambda f, schema, _: core_schema.no_info_before_validator_function(f, schema),
|
||||
- ('after', 'no-info'): lambda f, schema, _: core_schema.no_info_after_validator_function(f, schema),
|
||||
- ('plain', 'no-info'): lambda f, _1, _2: core_schema.no_info_plain_validator_function(f),
|
||||
- ('wrap', 'no-info'): lambda f, schema, _: core_schema.no_info_wrap_validator_function(f, schema),
|
||||
- ('before', 'with-info'): lambda f, schema, field_name: core_schema.with_info_before_validator_function(
|
||||
- f, schema, field_name=field_name
|
||||
- ),
|
||||
- ('after', 'with-info'): lambda f, schema, field_name: core_schema.with_info_after_validator_function(
|
||||
- f, schema, field_name=field_name
|
||||
- ),
|
||||
- ('plain', 'with-info'): lambda f, _, field_name: core_schema.with_info_plain_validator_function(
|
||||
- f, field_name=field_name
|
||||
- ),
|
||||
- ('wrap', 'with-info'): lambda f, schema, field_name: core_schema.with_info_wrap_validator_function(
|
||||
- f, schema, field_name=field_name
|
||||
- ),
|
||||
+ ('before', 'no-info'): lambda f, schema: core_schema.no_info_before_validator_function(f, schema),
|
||||
+ ('after', 'no-info'): lambda f, schema: core_schema.no_info_after_validator_function(f, schema),
|
||||
+ ('plain', 'no-info'): lambda f, _: core_schema.no_info_plain_validator_function(f),
|
||||
+ ('wrap', 'no-info'): lambda f, schema: core_schema.no_info_wrap_validator_function(f, schema),
|
||||
+ ('before', 'with-info'): lambda f, schema: core_schema.with_info_before_validator_function(f, schema),
|
||||
+ ('after', 'with-info'): lambda f, schema: core_schema.with_info_after_validator_function(f, schema),
|
||||
+ ('plain', 'with-info'): lambda f, _: core_schema.with_info_plain_validator_function(f),
|
||||
+ ('wrap', 'with-info'): lambda f, schema: core_schema.with_info_wrap_validator_function(f, schema),
|
||||
}
|
||||
|
||||
|
||||
@@ -2512,7 +2502,6 @@ def apply_validators(
|
||||
validators: Iterable[Decorator[RootValidatorDecoratorInfo]]
|
||||
| Iterable[Decorator[ValidatorDecoratorInfo]]
|
||||
| Iterable[Decorator[FieldValidatorDecoratorInfo]],
|
||||
- field_name: str | None,
|
||||
) -> core_schema.CoreSchema:
|
||||
"""Apply validators to a schema.
|
||||
|
||||
@@ -2528,7 +2517,7 @@ def apply_validators(
|
||||
info_arg = inspect_validator(validator.func, validator.info.mode)
|
||||
val_type = 'with-info' if info_arg else 'no-info'
|
||||
|
||||
- schema = _VALIDATOR_F_MATCH[(validator.info.mode, val_type)](validator.func, schema, field_name)
|
||||
+ schema = _VALIDATOR_F_MATCH[(validator.info.mode, val_type)](validator.func, schema)
|
||||
return schema
|
||||
|
||||
|
||||
Index: pydantic-2.11.7/pydantic/functional_validators.py
|
||||
===================================================================
|
||||
--- pydantic-2.11.7.orig/pydantic/functional_validators.py
|
||||
+++ pydantic-2.11.7/pydantic/functional_validators.py
|
||||
@@ -75,7 +75,7 @@ class AfterValidator:
|
||||
info_arg = _inspect_validator(self.func, 'after')
|
||||
if info_arg:
|
||||
func = cast(core_schema.WithInfoValidatorFunction, self.func)
|
||||
- return core_schema.with_info_after_validator_function(func, schema=schema, field_name=handler.field_name)
|
||||
+ return core_schema.with_info_after_validator_function(func, schema=schema)
|
||||
else:
|
||||
func = cast(core_schema.NoInfoValidatorFunction, self.func)
|
||||
return core_schema.no_info_after_validator_function(func, schema=schema)
|
||||
@@ -136,7 +136,6 @@ class BeforeValidator:
|
||||
return core_schema.with_info_before_validator_function(
|
||||
func,
|
||||
schema=schema,
|
||||
- field_name=handler.field_name,
|
||||
json_schema_input_schema=input_schema,
|
||||
)
|
||||
else:
|
||||
@@ -230,7 +229,6 @@ class PlainValidator:
|
||||
func = cast(core_schema.WithInfoValidatorFunction, self.func)
|
||||
return core_schema.with_info_plain_validator_function(
|
||||
func,
|
||||
- field_name=handler.field_name,
|
||||
serialization=serialization, # pyright: ignore[reportArgumentType]
|
||||
json_schema_input_schema=input_schema,
|
||||
)
|
||||
@@ -307,7 +305,6 @@ class WrapValidator:
|
||||
return core_schema.with_info_wrap_validator_function(
|
||||
func,
|
||||
schema=schema,
|
||||
- field_name=handler.field_name,
|
||||
json_schema_input_schema=input_schema,
|
||||
)
|
||||
else:
|
||||
Index: pydantic-2.11.7/tests/test_validators.py
|
||||
===================================================================
|
||||
--- pydantic-2.11.7.orig/tests/test_validators.py
|
||||
+++ pydantic-2.11.7/tests/test_validators.py
|
||||
@@ -21,7 +21,7 @@ from unittest.mock import MagicMock
|
||||
import pytest
|
||||
from dirty_equals import HasRepr, IsInstance
|
||||
from pydantic_core import core_schema
|
||||
-from typing_extensions import TypedDict
|
||||
+from typing_extensions import TypeAliasType, TypedDict
|
||||
|
||||
from pydantic import (
|
||||
BaseModel,
|
||||
@@ -2684,7 +2684,7 @@ def foobar_validate(value: Any, info: co
|
||||
class Foobar:
|
||||
@classmethod
|
||||
def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
|
||||
- return core_schema.with_info_plain_validator_function(foobar_validate, field_name=handler.field_name)
|
||||
+ return core_schema.with_info_plain_validator_function(foobar_validate)
|
||||
|
||||
|
||||
def test_custom_type_field_name_model():
|
||||
@@ -2779,6 +2779,29 @@ def test_plain_validator_field_name():
|
||||
assert m.foobar == {'value': '1', 'field_name': 'foobar', 'data': {'x': 123}}
|
||||
|
||||
|
||||
+def test_validator_field_name_with_reused_type_alias():
|
||||
+ calls = []
|
||||
+
|
||||
+ def validate_my_field(value: str, info: ValidationInfo):
|
||||
+ calls.append((info.field_name, value))
|
||||
+ return value
|
||||
+
|
||||
+ MyField = TypeAliasType('MyField', Annotated[str, AfterValidator(validate_my_field)])
|
||||
+
|
||||
+ class MyModel(BaseModel):
|
||||
+ field1: MyField
|
||||
+ field2: MyField
|
||||
+
|
||||
+ MyModel.model_validate(
|
||||
+ {
|
||||
+ 'field1': 'value1',
|
||||
+ 'field2': 'value2',
|
||||
+ }
|
||||
+ )
|
||||
+
|
||||
+ assert calls == [('field1', 'value1'), ('field2', 'value2')]
|
||||
+
|
||||
+
|
||||
def validate_wrap(value: Any, handler: core_schema.ValidatorFunctionWrapHandler, info: core_schema.ValidationInfo):
|
||||
data = info.data
|
||||
if isinstance(data, dict):
|
BIN
pydantic-2.10.6.tar.gz
(Stored with Git LFS)
BIN
pydantic-2.10.6.tar.gz
(Stored with Git LFS)
Binary file not shown.
BIN
pydantic-2.11.7.tar.gz
(Stored with Git LFS)
Normal file
BIN
pydantic-2.11.7.tar.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -1,3 +1,137 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Jun 23 05:56:23 UTC 2025 - Daniel Garcia <daniel.garcia@suse.com>
|
||||
|
||||
- Add patch bump-pydantic-core-2.35.1.patch to support latest
|
||||
pydantic-core, gh#pydantic/pydantic#11963
|
||||
- Add patch field-name-validator-core-schemas.patch to remove
|
||||
deprecation warning, gh#pydantic/pydantic#11761
|
||||
- Update to 2.11.7
|
||||
* Copy FieldInfo instance if necessary during FieldInfo build by @Viicos in #11980
|
||||
2.11.6
|
||||
* Rebuild dataclass fields before schema generation by @Viicos in #11949
|
||||
* Always store the original field assignment on FieldInfo by @Viicos in #11946
|
||||
2.11.5
|
||||
* Check if FieldInfo is complete after applying type variable map by @Viicos in #11855
|
||||
* Do not delete mock validator/serializer in model_rebuild() by @Viicos in #11890
|
||||
* Do not duplicate metadata on model rebuild by @Viicos in #11902
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon May 5 08:19:26 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaubitz@suse.com>
|
||||
|
||||
- Update to 2.11.4
|
||||
* Bump mkdocs-llmstxt to v0.2.0
|
||||
* Allow config and bases to be specified together in create_model()
|
||||
* This change was backported as it was previously possible
|
||||
(although not meant to be supported)
|
||||
* To provide model_config as a field, which would make it
|
||||
possible to provide both configuration and bases.
|
||||
* Remove generics cache workaround
|
||||
* Remove coercion of decimal constraints
|
||||
* Fix crash when expanding root type in the mypy plugin
|
||||
* Fix issue with recursive generic models
|
||||
* Traverse function-before schemas during schema gathering
|
||||
- Drop field_name.patch, merged upstream
|
||||
- Update BuildRequires and Requires from pyproject.toml
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Apr 25 09:30:29 UTC 2025 - Markéta Machová <mmachova@suse.com>
|
||||
|
||||
- Add upstream field_name.patch for compatibility with recent pydantic-core
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Apr 24 04:47:19 UTC 2025 - Steve Kowalik <steven.kowalik@suse.com>
|
||||
|
||||
- Add missing Requires on typing-inspection.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sun Apr 20 10:54:45 UTC 2025 - Richard Rahl <rrahl0@opensuse.org>
|
||||
|
||||
- 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 <ecsos@opensuse.org>
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# spec file
|
||||
# spec file for package python-pydantic
|
||||
#
|
||||
# Copyright (c) 2025 SUSE LLC
|
||||
# Copyright (c) 2019, Martin Hauke <mardnh@gmx.de>
|
||||
@@ -27,17 +27,21 @@
|
||||
%endif
|
||||
%{?sle15_python_module_pythons}
|
||||
Name: python-pydantic%{psuffix}
|
||||
Version: 2.10.6
|
||||
Version: 2.11.7
|
||||
Release: 0
|
||||
Summary: Data validation and settings management using python type hinting
|
||||
License: MIT
|
||||
URL: https://github.com/pydantic/pydantic
|
||||
Source: https://github.com/pydantic/pydantic/archive/v%{version}.tar.gz#/pydantic-%{version}.tar.gz
|
||||
# PATCH-FIX-UPSTREAM bump-pydantic-core-2.35.1.patch gh#pydantic/pydantic#11963
|
||||
Patch0: bump-pydantic-core-2.35.1.patch
|
||||
# PATCH-FIX-UPSTREAM field-name-validator-core-schemas.patch gh#pydantic/pydantic#11761
|
||||
Patch1: field-name-validator-core-schemas.patch
|
||||
BuildRequires: %{python_module hatch-fancy-pypi-readme}
|
||||
BuildRequires: %{python_module hatchling}
|
||||
BuildRequires: %{python_module packaging}
|
||||
BuildRequires: %{python_module pip}
|
||||
BuildRequires: %{python_module pydantic-core >= 2.27.2}
|
||||
BuildRequires: %{python_module pydantic-core = 2.35.1}
|
||||
BuildRequires: %{python_module wheel}
|
||||
BuildRequires: fdupes
|
||||
BuildRequires: python-rpm-macros
|
||||
@@ -51,16 +55,19 @@ 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.4.0
|
||||
%if 0%{?python_version_nodots} < 310
|
||||
Requires: python-eval-type-backport
|
||||
%endif
|
||||
Requires: python-pydantic-core >= 2.27.2
|
||||
Requires: python-typing-extensions >= 4.6.1
|
||||
Requires: python-pydantic-core = 2.35.1
|
||||
Requires: python-typing-extensions >= 4.12.2
|
||||
Requires: python-typing-inspection
|
||||
BuildArch: noarch
|
||||
%python_subpackages
|
||||
|
||||
|
Reference in New Issue
Block a user