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

Pydantic dataclasses cannot be used as Annotated Validators #9443

Open
1 task done
salemileandro opened this issue May 16, 2024 · 3 comments
Open
1 task done

Pydantic dataclasses cannot be used as Annotated Validators #9443

salemileandro opened this issue May 16, 2024 · 3 comments
Labels
bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation

Comments

@salemileandro
Copy link

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

Pydantic dataclasses cannot be used as Annotated Validators. The TypeError happens at class the definition.

I wanted to replicate the example of the section As a method on a custom type of the "Types" part of the Concepts but instead of using Python dataclasses, I wanted to use Pydantic dataclasses (to add validation).
I am not sure about all the internals but it looks like some conflicts about the __get_pydantic_core_schema__ that needs to be implemented for the class to be an Annotated Validator and the __get_pydantic_core_schema__ that is used for the definition.

I've read in the Pydantic website that [...] you should try to stick to the built-in constructs like those provided by annotated-types, pydantic.Field, or BeforeValidator and so on., so sorry if this is somehow already known and I should just avoid using Pydantic dataclasses in this specific context.

Example Code

import dataclasses
from typing import Annotated, Any

import pydantic
from pydantic import GetCoreSchemaHandler, PositiveFloat, TypeAdapter
from pydantic_core import CoreSchema, core_schema

@dataclasses.dataclass
class PythonDataclassValidator:
    exponent: PositiveFloat

    def __call__(self, value):
        return value**self.exponent

    def __get_pydantic_core_schema__(
        self, source_type: Any, handler: GetCoreSchemaHandler
    ) -> CoreSchema:
        """Return the Pydantic core schema for the custom after validator."""
        return core_schema.no_info_after_validator_function(self, handler(source_type))


### Error will happen at the next code line, during the class definition
### TypeError: PydanticDataclassValidator.__get_pydantic_core_schema__() missing 1 required positional argument: 'handler'

@pydantic.dataclasses.dataclass
class PydanticDataclassValidator:
    exponent: PositiveFloat

    def __call__(self, value):
        return value**self.exponent

    def __get_pydantic_core_schema__(
        self, source_type: Any, handler: GetCoreSchemaHandler
    ) -> CoreSchema:
        """Return the Pydantic core schema for the custom after validator."""
        return core_schema.no_info_after_validator_function(self, handler(source_type))


# This works as expected if I remove the whole code of the class PydanticDataclassValidator (this similar to the example given in Pydantic's website)
PythonType = Annotated[float, PythonDataclassValidator(2)]
print(TypeAdapter(PythonType).validate_python(2) == 4)

PydanticType = Annotated[float, PydanticDataclassValidator(2)]
print(TypeAdapter(PydanticType).validate_python(2) == 4)

Python, Pydantic & OS Version

pydantic version: 2.7.1
        pydantic-core version: 2.18.2
          pydantic-core build: profile=release pgo=true
                 install path: /home/leandro/miniforge3/envs/vbuild/lib/python3.10/site-packages/pydantic
               python version: 3.10.14 | packaged by conda-forge | (main, Mar 20 2024, 12:45:18) [GCC 12.3.0]
                     platform: Linux-6.8.0-76060800daily20240311-generic-x86_64-with-glibc2.35
             related packages: pydantic-settings-2.2.1 typing_extensions-4.11.0
                       commit: unknown
@salemileandro salemileandro added bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels May 16, 2024
@sydney-runkle
Copy link
Member

Hi @salemileandro,

Thanks for the question! Indeed, looks like a conflict on the __get_pydantic_core_schema__ front. I think this should be possible, but will definitely take some modification on the internal core schema building front.

I'll take a closer look at this for 2.8 and see if we can come up with a workaround for you!

@sydney-runkle sydney-runkle added this to the v2.8.0 milestone May 16, 2024
@sydney-runkle
Copy link
Member

Hi @salemileandro,

After chatting about this a bit more with the team, we've decided that we'd recommend just using plain dataclasses as annotated metadata for now.

We can revisit this for V3, but I'm going to remove this from the v2.8.0 milestone 👍

@sydney-runkle sydney-runkle removed this from the v2.8.0 milestone Jun 5, 2024
@salemileandro
Copy link
Author

Hi!
Thanks for letting me know! It's far from being a blocking bug, I can use other ways to achieve similar goals so no worries :)

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

No branches or pull requests

2 participants