From f7af1d7e06bb462fd996c238367ef11e3e8eae95 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Thu, 18 Apr 2024 11:08:52 -0500 Subject: [PATCH 1/3] linting --- python/pydantic_core/core_schema.py | 42 +++++++++++++++++++---------- src/validators/enum_.rs | 10 ++++++- tests/test_typing.py | 12 ++++++--- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/python/pydantic_core/core_schema.py b/python/pydantic_core/core_schema.py index 2cb875b23..8a3409ab6 100644 --- a/python/pydantic_core/core_schema.py +++ b/python/pydantic_core/core_schema.py @@ -120,45 +120,58 @@ class CoreConfig(TypedDict, total=False): class SerializationInfo(Protocol): @property - def include(self) -> IncExCall: ... + def include(self) -> IncExCall: + ... @property - def exclude(self) -> IncExCall: ... + def exclude(self) -> IncExCall: + ... @property def context(self) -> Any | None: """Current serialization context.""" @property - def mode(self) -> str: ... + def mode(self) -> str: + ... @property - def by_alias(self) -> bool: ... + def by_alias(self) -> bool: + ... @property - def exclude_unset(self) -> bool: ... + def exclude_unset(self) -> bool: + ... @property - def exclude_defaults(self) -> bool: ... + def exclude_defaults(self) -> bool: + ... @property - def exclude_none(self) -> bool: ... + def exclude_none(self) -> bool: + ... @property - def serialize_as_any(self) -> bool: ... + def serialize_as_any(self) -> bool: + ... - def round_trip(self) -> bool: ... + def round_trip(self) -> bool: + ... - def mode_is_json(self) -> bool: ... + def mode_is_json(self) -> bool: + ... - def __str__(self) -> str: ... + def __str__(self) -> str: + ... - def __repr__(self) -> str: ... + def __repr__(self) -> str: + ... class FieldSerializationInfo(SerializationInfo, Protocol): @property - def field_name(self) -> str: ... + def field_name(self) -> str: + ... class ValidationInfo(Protocol): @@ -302,7 +315,8 @@ def plain_serializer_function_ser_schema( class SerializerFunctionWrapHandler(Protocol): # pragma: no cover - def __call__(self, input_value: Any, index_key: int | str | None = None, /) -> Any: ... + def __call__(self, input_value: Any, index_key: int | str | None = None, /) -> Any: + ... # (input_value: Any, serializer: SerializerFunctionWrapHandler, /) -> Any diff --git a/src/validators/enum_.rs b/src/validators/enum_.rs index cf65c2f96..2c9ae4b28 100644 --- a/src/validators/enum_.rs +++ b/src/validators/enum_.rs @@ -121,7 +121,15 @@ impl Validator for EnumValidator { return Ok(v); } else if let Some(ref missing) = self.missing { state.floor_exactness(Exactness::Lax); - let enum_value = missing.bind(py).call1((input.to_object(py),))?; + let enum_value = missing.bind(py).call1((input.to_object(py),)).map_err(|_| { + ValError::new( + ErrorType::Enum { + expected: self.expected_repr.clone(), + context: None, + }, + input, + ) + })?; // check enum_value is an instance of the class like // https://github.com/python/cpython/blob/v3.12.2/Lib/enum.py#L1148 if enum_value.is_instance(class)? { diff --git a/tests/test_typing.py b/tests/test_typing.py index 2f460fb48..0f5e45d0c 100644 --- a/tests/test_typing.py +++ b/tests/test_typing.py @@ -19,16 +19,20 @@ class Foo: bar: str -def foo(bar: str) -> None: ... +def foo(bar: str) -> None: + ... -def validator_deprecated(value: Any, info: core_schema.FieldValidationInfo) -> None: ... +def validator_deprecated(value: Any, info: core_schema.FieldValidationInfo) -> None: + ... -def validator(value: Any, info: core_schema.ValidationInfo) -> None: ... +def validator(value: Any, info: core_schema.ValidationInfo) -> None: + ... -def wrap_validator(value: Any, call_next: Callable[[Any], Any], info: core_schema.ValidationInfo) -> None: ... +def wrap_validator(value: Any, call_next: Callable[[Any], Any], info: core_schema.ValidationInfo) -> None: + ... def test_schema_typing() -> None: From c1d65975ca36de42efc57f0e5dd95f2c51726860 Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Thu, 18 Apr 2024 11:16:12 -0500 Subject: [PATCH 2/3] revert unneeded linting changes --- python/pydantic_core/core_schema.py | 42 ++++++++++------------------- tests/test_typing.py | 12 +++------ 2 files changed, 18 insertions(+), 36 deletions(-) diff --git a/python/pydantic_core/core_schema.py b/python/pydantic_core/core_schema.py index 8a3409ab6..2cb875b23 100644 --- a/python/pydantic_core/core_schema.py +++ b/python/pydantic_core/core_schema.py @@ -120,58 +120,45 @@ class CoreConfig(TypedDict, total=False): class SerializationInfo(Protocol): @property - def include(self) -> IncExCall: - ... + def include(self) -> IncExCall: ... @property - def exclude(self) -> IncExCall: - ... + def exclude(self) -> IncExCall: ... @property def context(self) -> Any | None: """Current serialization context.""" @property - def mode(self) -> str: - ... + def mode(self) -> str: ... @property - def by_alias(self) -> bool: - ... + def by_alias(self) -> bool: ... @property - def exclude_unset(self) -> bool: - ... + def exclude_unset(self) -> bool: ... @property - def exclude_defaults(self) -> bool: - ... + def exclude_defaults(self) -> bool: ... @property - def exclude_none(self) -> bool: - ... + def exclude_none(self) -> bool: ... @property - def serialize_as_any(self) -> bool: - ... + def serialize_as_any(self) -> bool: ... - def round_trip(self) -> bool: - ... + def round_trip(self) -> bool: ... - def mode_is_json(self) -> bool: - ... + def mode_is_json(self) -> bool: ... - def __str__(self) -> str: - ... + def __str__(self) -> str: ... - def __repr__(self) -> str: - ... + def __repr__(self) -> str: ... class FieldSerializationInfo(SerializationInfo, Protocol): @property - def field_name(self) -> str: - ... + def field_name(self) -> str: ... class ValidationInfo(Protocol): @@ -315,8 +302,7 @@ def plain_serializer_function_ser_schema( class SerializerFunctionWrapHandler(Protocol): # pragma: no cover - def __call__(self, input_value: Any, index_key: int | str | None = None, /) -> Any: - ... + def __call__(self, input_value: Any, index_key: int | str | None = None, /) -> Any: ... # (input_value: Any, serializer: SerializerFunctionWrapHandler, /) -> Any diff --git a/tests/test_typing.py b/tests/test_typing.py index 0f5e45d0c..2f460fb48 100644 --- a/tests/test_typing.py +++ b/tests/test_typing.py @@ -19,20 +19,16 @@ class Foo: bar: str -def foo(bar: str) -> None: - ... +def foo(bar: str) -> None: ... -def validator_deprecated(value: Any, info: core_schema.FieldValidationInfo) -> None: - ... +def validator_deprecated(value: Any, info: core_schema.FieldValidationInfo) -> None: ... -def validator(value: Any, info: core_schema.ValidationInfo) -> None: - ... +def validator(value: Any, info: core_schema.ValidationInfo) -> None: ... -def wrap_validator(value: Any, call_next: Callable[[Any], Any], info: core_schema.ValidationInfo) -> None: - ... +def wrap_validator(value: Any, call_next: Callable[[Any], Any], info: core_schema.ValidationInfo) -> None: ... def test_schema_typing() -> None: From b2412fe49ed5ca7e977d3f25873f8b045858697c Mon Sep 17 00:00:00 2001 From: sydney-runkle Date: Mon, 22 Apr 2024 08:24:32 -0500 Subject: [PATCH 3/3] add test --- tests/validators/test_enums.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/validators/test_enums.py b/tests/validators/test_enums.py index 89db8aa21..49abc415b 100644 --- a/tests/validators/test_enums.py +++ b/tests/validators/test_enums.py @@ -1,6 +1,6 @@ import re import sys -from enum import Enum +from enum import Enum, IntFlag import pytest @@ -267,3 +267,21 @@ class MyEnum(Enum): with pytest.raises(SchemaError, match='`members` should have length > 0'): SchemaValidator(core_schema.enum_schema(MyEnum, [])) + + +def test_missing_error_converted_to_val_error() -> None: + class MyFlags(IntFlag): + OFF = 0 + ON = 1 + + v = SchemaValidator( + core_schema.with_default_schema( + schema=core_schema.enum_schema(MyFlags, list(MyFlags.__members__.values())), default=MyFlags.OFF + ) + ) + + assert v.validate_python(MyFlags.OFF) is MyFlags.OFF + assert v.validate_python(0) is MyFlags.OFF + + with pytest.raises(ValidationError): + v.validate_python(None)