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

Pure-python implementation of dataclasses module has differences regarding slots #3791

Closed
3 tasks done
spookylukey opened this issue Feb 7, 2022 · 7 comments
Closed
3 tasks done
Assignees
Labels
bug V1 Bug related to Pydantic V1.X bug V2 Bug related to Pydantic V2

Comments

@spookylukey
Copy link

When using pydantic.dataclasses.dataclass, typing.get_type_hints() output on a Pydantic model includes __slots__ for the pure-Python version, but not for the Cython version.

Test case:

# test.py
import typing
from pydantic.dataclasses import dataclass

@dataclass
class Foo:
    pass

print(typing.get_type_hints(Foo.__pydantic_model__))
$ pip install pydantic
$ python test.py
{}
$ pip uninstall pydantic
$ SKIP_CYTHON=1 pip install --no-binary pydantic pydantic
$ python test.py
{'__slots__': typing.Tuple[str, ...]}

Found this with 1.8.2 , but the issue is still there with latest version - 1.9.0.

I don't know if this is deliberate, or unavoidable, but it tripped me up, so I thought it was worth reporting.

Impact

I discovered this because we were experimenting with AWS Graviton instances, which are 64-bit ARM CPUs, where, for whatever reason, we are falling back to the pure-Python version.

Checks

  • I added a descriptive title to this issue
  • I have searched (google, github) for similar issues and couldn't find anything
  • I have read and followed the docs and still think this is a bug
@spookylukey spookylukey added the bug V1 Bug related to Pydantic V1.X label Feb 7, 2022
@Goldziher
Copy link

Goldziher commented Aug 13, 2022

Yup this is clearly a bug. Pydantic will fail validation for dataclasses that use slots=True. See this for reference:

import pytest
from dataclasses import dataclass
from unittest import skipIf

from pydantic import BaseModel


@skipIf(sys.version_info < (3, 10), "python version incompatible with 'slots' arg")
def test_pydantic_handling_stdlib_dataclass_slots() -> None:
    """
    Test showing failure when using the slots kwarg available the stdlib dataclass decorator in python 3.10+
    """
    @dataclass(slots=True)
    class UserWithSlots:
        username: str
        group: str

    @dataclass(slots=False)
    class UserWithoutSlots:
        username: str
        group: str

    class ModelThatRaises(BaseModel):
        user: UserWithSlots

    class ModelThatDoesntRaise(BaseModel):
        user: UserWithoutSlots

    with pytest.raises(ValidationError):
        ModelThatRaises(user={"username": "MoisheZuchmir", "group": "admins"})

    ModelThatDoesntRaise(user={"username": "MoisheZuchmir", "group": "admins"})

Reported in Starlite here: litestar-org/litestar#359

@samuelcolvin
Copy link
Member

Have you tried on master? Might be fixed by #2557

@Goldziher
Copy link

@infohash can you try master?

@PrettyWood
Copy link
Member

PrettyWood commented Aug 13, 2022

The code of @spookylukey works on master since the refacto. But your code @Goldziher doesn't. We still don't support dataclasses with slots, which was added in 3.10. I'll check if this could be added easily

@PrettyWood
Copy link
Member

Doesn't feel like it's going to be easy to add since we keep a kind of state when wrapping up the dataclass and a slotted dataclass doesn't allow mutations on those fields. We would need to mess up even more with init, which is something I really don't want to do.
In v2, it should be easier to use pydantic directly with stdlib dataclasses, without the custom pydantic one 🙏

@samuelcolvin
Copy link
Member

Agreed, I think we can live without slots for v1.10.

@Kludex Kludex added the bug V2 Bug related to Pydantic V2 label Apr 26, 2023
@Kludex Kludex added this to the Version 2 Issues milestone Apr 26, 2023
@hramezani hramezani assigned dmontagu and unassigned hramezani May 2, 2023
@dmontagu
Copy link
Contributor

dmontagu commented May 8, 2023

I'm going to close this as I believe it is addressed in v2, but please comment here if I'm wrong.

@dmontagu dmontagu closed this as completed May 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug V1 Bug related to Pydantic V1.X bug V2 Bug related to Pydantic V2
Projects
None yet
Development

No branches or pull requests

7 participants