Skip to content

Commit

Permalink
Fix unsupported types bug with plain validator (#8710)
Browse files Browse the repository at this point in the history
Co-authored-by: David Montague <35119617+dmontagu@users.noreply.github.com>
  • Loading branch information
sydney-runkle and dmontagu committed Feb 5, 2024
1 parent aac1069 commit 8e790d5
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
15 changes: 13 additions & 2 deletions pydantic/functional_validators.py
Expand Up @@ -153,8 +153,19 @@ class Model(BaseModel):
func: core_schema.NoInfoValidatorFunction | core_schema.WithInfoValidatorFunction

def __get_pydantic_core_schema__(self, source_type: Any, handler: _GetCoreSchemaHandler) -> core_schema.CoreSchema:
schema = handler(source_type)
serialization = core_schema.wrap_serializer_function_ser_schema(function=lambda v, h: h(v), schema=schema)
# Note that for some valid uses of PlainValidator, it is not possible to generate a core schema for the
# source_type, so calling `handler(source_type)` will error, which prevents us from generating a proper
# serialization schema. To work around this for use cases that will not involve serialization, we simply
# catch any PydanticSchemaGenerationError that may be raised while attempting to build the serialization schema
# and abort any attempts to handle special serialization.
from pydantic import PydanticSchemaGenerationError

try:
schema = handler(source_type)
serialization = core_schema.wrap_serializer_function_ser_schema(function=lambda v, h: h(v), schema=schema)
except PydanticSchemaGenerationError:
serialization = None

info_arg = _inspect_validator(self.func, 'plain')
if info_arg:
func = cast(core_schema.WithInfoValidatorFunction, self.func)
Expand Down
16 changes: 16 additions & 0 deletions tests/test_validators.py
Expand Up @@ -2823,3 +2823,19 @@ class Blah(BaseModel):
data = blah.model_dump()
assert isinstance(data['foo'], ser_type)
assert isinstance(data['bar'], ser_type)


def test_plain_validator_with_unsupported_type() -> None:
class UnsupportedClass:
pass

PreviouslySupportedType = Annotated[
UnsupportedClass,
PlainValidator(lambda _: UnsupportedClass()),
]

type_adapter = TypeAdapter(PreviouslySupportedType)

model = type_adapter.validate_python('abcdefg')
assert isinstance(model, UnsupportedClass)
assert isinstance(type_adapter.dump_python(model), UnsupportedClass)

0 comments on commit 8e790d5

Please sign in to comment.