Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unsupported types bug with plain validator #8710

Merged
merged 3 commits into from Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
sydney-runkle marked this conversation as resolved.
Show resolved Hide resolved

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)