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

2.6.0 breaks PlainValidator on unsupported types #8697

Closed
1 task done
Tracked by #8671
MHajoha opened this issue Feb 1, 2024 · 1 comment · Fixed by #8710
Closed
1 task done
Tracked by #8671

2.6.0 breaks PlainValidator on unsupported types #8697

MHajoha opened this issue Feb 1, 2024 · 1 comment · Fixed by #8710
Labels
bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation

Comments

@MHajoha
Copy link

MHajoha commented Feb 1, 2024

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

Previously, it was possible to annotate an unsupported type (which by itself would cause Pydantic to throw a PydanticSchemaGenerationError) with PlainValidator and the annotated type could be used by Pydantic. With 2.6.0, this is no longer possible, the PydanticSchemaGenerationError is thrown.

Confirmed on 2.6.0 and on current main (commit 29906d7).

It seems likely this is caused by #8567, since handler is now called earlier and throws.

Example Code

from typing import TypeAlias, Annotated

import pydantic
from pydantic import PlainValidator

print(pydantic.version.version_info())


class UnsupportedClass:
    pass


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

# The next line fails on 2.6.0 and main (29906d744d8bae7a7e5fcba653d3867454a9e1d5)
type_adapter = pydantic.TypeAdapter(PreviouslySupportedType)

print(type_adapter.validate_python("abcdefg"))

Output on 2.5.3

             pydantic version: 2.5.3
        pydantic-core version: 2.14.6
          pydantic-core build: profile=release pgo=true
                 install path: /home/maxh/Work/project/.venv311-oldpydantic/lib/python3.11/site-packages/pydantic
               python version: 3.11.1 (main, Jan 12 2023, 14:43:37) [GCC 12.2.0]
                     platform: Linux-6.7.2-zen1-1-zen-x86_64-with-glibc2.38
             related packages: typing_extensions-4.9.0
<__main__.UnsupportedClass object at 0xdeadbeef>

Output on 2.6.0

             pydantic version: 2.6.0
        pydantic-core version: 2.16.1
          pydantic-core build: profile=release pgo=true
                 install path: /home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic
               python version: 3.11.1 (main, Jan 12 2023, 14:43:37) [GCC 12.2.0]
                     platform: Linux-6.7.2-zen1-1-zen-x86_64-with-glibc2.38
             related packages: typing_extensions-4.9.0
                       commit: unknown
Traceback (most recent call last):
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/type_adapter.py", line 207, in __init__
    core_schema = _getattr_no_parents(type, '__pydantic_core_schema__')
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/type_adapter.py", line 98, in _getattr_no_parents
    raise AttributeError(attribute)
AttributeError: __pydantic_core_schema__

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/maxh/Work/project/pydantic_261_example.py", line 19, in <module>
    type_adapter = pydantic.TypeAdapter(PreviouslySupportedType)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/type_adapter.py", line 209, in __init__
    core_schema = _get_schema(type, config_wrapper, parent_depth=_parent_depth + 1)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/type_adapter.py", line 81, in _get_schema
    schema = gen.generate_schema(type_)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 501, in generate_schema
    schema = self._generate_schema(obj)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 739, in _generate_schema
    schema = self._post_process_generated_schema(self._generate_schema_inner(obj))
                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 746, in _generate_schema_inner
    return self._annotated_schema(obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 1681, in _annotated_schema
    schema = self._apply_annotations(source_type, annotations)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 1749, in _apply_annotations
    schema = get_inner_schema(source_type)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_schema_generation_shared.py", line 82, in __call__
    schema = self._handler(__source_type)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 1831, in new_handler
    schema = metadata_get_schema(source, get_inner_schema)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/functional_validators.py", line 156, in __get_pydantic_core_schema__
    schema = handler(source_type)
             ^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_schema_generation_shared.py", line 82, in __call__
    schema = self._handler(__source_type)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 1730, in inner_handler
    schema = self._generate_schema(obj)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 739, in _generate_schema
    schema = self._post_process_generated_schema(self._generate_schema_inner(obj))
                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 766, in _generate_schema_inner
    return self.match_type(obj)
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 853, in match_type
    return self._unknown_type_schema(obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 397, in _unknown_type_schema
    raise PydanticSchemaGenerationError(
pydantic.errors.PydanticSchemaGenerationError: Unable to generate pydantic-core schema for <class '__main__.UnsupportedClass'>. Set `arbitrary_types_allowed=True` in the model_config to ignore this error or implement `__get_pydantic_core_schema__` on your type to fully support it.

If you got this error by calling handler(<some type>) within `__get_pydantic_core_schema__` then you likely need to call `handler.generate_schema(<some type>)` since we do not call `__get_pydantic_core_schema__` on `<some type>` otherwise to avoid infinite recursion.

For further information visit https://errors.pydantic.dev/2.6/u/schema-for-unknown-type

Output on main (29906d7)

(It's basically the same)
(.venv311-devpydantic) [maxh@laptop ~/Work/project]$ python pydantic_261_example.py 
             pydantic version: 2.6.0
        pydantic-core version: 2.16.1
          pydantic-core build: profile=release pgo=true
                 install path: /home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic
               python version: 3.11.1 (main, Jan 12 2023, 14:43:37) [GCC 12.2.0]
                     platform: Linux-6.7.2-zen1-1-zen-x86_64-with-glibc2.38
             related packages: typing_extensions-4.9.0
                       commit: unknown
Traceback (most recent call last):
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/type_adapter.py", line 207, in __init__
    core_schema = _getattr_no_parents(type, '__pydantic_core_schema__')
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/type_adapter.py", line 98, in _getattr_no_parents
    raise AttributeError(attribute)
AttributeError: __pydantic_core_schema__

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/maxh/Work/project/pydantic_261_example.py", line 19, in <module>
    type_adapter = pydantic.TypeAdapter(PreviouslySupportedType)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/type_adapter.py", line 209, in __init__
    core_schema = _get_schema(type, config_wrapper, parent_depth=_parent_depth + 1)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/type_adapter.py", line 81, in _get_schema
    schema = gen.generate_schema(type_)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 502, in generate_schema
    schema = self._generate_schema(obj)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 747, in _generate_schema
    schema = self._post_process_generated_schema(self._generate_schema_inner(obj))
                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 754, in _generate_schema_inner
    return self._annotated_schema(obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 1701, in _annotated_schema
    schema = self._apply_annotations(source_type, annotations)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 1769, in _apply_annotations
    schema = get_inner_schema(source_type)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_schema_generation_shared.py", line 82, in __call__
    schema = self._handler(__source_type)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 1851, in new_handler
    schema = metadata_get_schema(source, get_inner_schema)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/functional_validators.py", line 156, in __get_pydantic_core_schema__
    schema = handler(source_type)
             ^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_schema_generation_shared.py", line 82, in __call__
    schema = self._handler(__source_type)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 1750, in inner_handler
    schema = self._generate_schema(obj)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 747, in _generate_schema
    schema = self._post_process_generated_schema(self._generate_schema_inner(obj))
                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 774, in _generate_schema_inner
    return self.match_type(obj)
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 861, in match_type
    return self._unknown_type_schema(obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/maxh/Work/project/.venv311-devpydantic/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py", line 398, in _unknown_type_schema
    raise PydanticSchemaGenerationError(
pydantic.errors.PydanticSchemaGenerationError: Unable to generate pydantic-core schema for <class '__main__.UnsupportedClass'>. Set `arbitrary_types_allowed=True` in the model_config to ignore this error or implement `__get_pydantic_core_schema__` on your type to fully support it.

If you got this error by calling handler(<some type>) within `__get_pydantic_core_schema__` then you likely need to call `handler.generate_schema(<some type>)` since we do not call `__get_pydantic_core_schema__` on `<some type>` otherwise to avoid infinite recursion.

For further information visit https://errors.pydantic.dev/2.6/u/schema-for-unknown-type
@MHajoha MHajoha added bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels Feb 1, 2024
@MHajoha MHajoha changed the title 2.6.0 breaks PlainValidator on unsopported types 2.6.0 breaks PlainValidator on unsupported types Feb 1, 2024
@sydney-runkle
Copy link
Member

@MHajoha,

Thanks for bringing this to our attention. This change wasn't intentional - that pattern is indeed something that we want to support!

We'll look into a fix to include with our upcoming patch release. Stay tuned 🚀

tumidi added a commit to questionpy-org/questionpy-server that referenced this issue Apr 2, 2024
Also upgrading pydantic to latest version as blocking issue is resolved.

Ref: pydantic/pydantic#8697
tumidi added a commit to questionpy-org/questionpy-sdk that referenced this issue Apr 2, 2024
Also upgrading pydantic to latest version as blocking issue is resolved.

Ref: pydantic/pydantic#8697
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants