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

Typing error when defining an enum of an attrs class #1287

Open
MicaelJarniac opened this issue May 20, 2024 · 2 comments
Open

Typing error when defining an enum of an attrs class #1287

MicaelJarniac opened this issue May 20, 2024 · 2 comments
Labels
Bug Typing Typing/stub/Mypy/PyRight related bugs.

Comments

@MicaelJarniac
Copy link
Contributor

When trying to define an enum of an @attrs.define class, Mypy gives typing errors, but it works in runtime.

When trying to define an enum of an @attrs.frozen class, Mypy doesn't give an error, but it errors at runtime.

When trying to define an enum of a @dataclasses.dataclass class, Mypy doesn't give an error, and it works at runtime.

I started noticing this today after I removed support for Python 3.9 from my project, and ran poetry update.

from dataclasses import dataclass
from enum import Enum

import attrs
from pytest import raises


@attrs.define
class AttrsDefine:
    a: int
    b: float


# error: Definition of "__hash__" in base class "AttrsDefine" is incompatible with definition in base class "Enum"  [misc]
class AttrsDefineEnum(AttrsDefine, Enum):
    X = (1, 2.0)
    Y = (3, 4.0)


@attrs.frozen
class AttrsFrozen:
    a: int
    b: float


@dataclass
class Dataclass:
    a: int
    b: float


class DataclassEnum(Dataclass, Enum):
    X = (1, 2.0)
    Y = (3, 4.0)


def test_enums() -> None:
    with raises(attrs.exceptions.FrozenInstanceError) as exc_info:

        # attr.exceptions.FrozenInstanceError
        class AttrsFrozenEnum(AttrsFrozen, Enum):
            X = (1, 2.0)
            Y = (3, 4.0)

        print(repr(AttrsFrozenEnum.X))

    print(exc_info.exconly())
    print(repr(AttrsDefineEnum.X))
    print(repr(DataclassEnum.X))
❯ mypy attrenum.py
attrenum.py:15: error: Definition of "__hash__" in base class "AttrsDefine" is incompatible with definition in base class "Enum"  [misc]
Found 1 error in 1 file (checked 1 source file)
❯ pytest -s attrenum.py
=================================================================================== test session starts ===================================================================================
platform linux -- Python 3.11.6, pytest-7.4.0, pluggy-1.2.0
rootdir: /home/micael/projects/playground
collected 1 item                                                                                                                                                                          

attrenum.py attr.exceptions.FrozenInstanceError
AttrsDefineEnum(a=1, b=2.0)
<DataclassEnum.X: Dataclass(a=1, b=2.0)>
.

==================================================================================== 1 passed in 0.01s ====================================================================================
❯ python --version
Python 3.11.4
❯ mypy --version
mypy 1.10.0 (compiled: yes)
❯ pip freeze
attrs==23.2.0
iniconfig==2.0.0
mypy==1.10.0
mypy-extensions==1.0.0
packaging==24.0
pluggy==1.5.0
pytest==8.2.1
typing_extensions==4.11.0
@hynek hynek added the Typing Typing/stub/Mypy/PyRight related bugs. label Jul 24, 2024
@hynek
Copy link
Member

hynek commented Jul 24, 2024

What about dataclass(frozen=True)? So far, it sounds a Mypy thing to me.

@MicaelJarniac
Copy link
Contributor Author

from dataclasses import dataclass
from enum import Enum

import attrs
from pytest import raises


@attrs.define
class AttrsDefine:
    a: int
    b: float


# error: Definition of "__hash__" in base class "AttrsDefine" is incompatible with definition in base class "Enum"  [misc]
class AttrsDefineEnum(AttrsDefine, Enum):
    X = (1, 2.0)
    Y = (3, 4.0)


@attrs.frozen
class AttrsFrozen:
    a: int
    b: float


@dataclass
class Dataclass:
    a: int
    b: float


class DataclassEnum(Dataclass, Enum):
    X = (1, 2.0)
    Y = (3, 4.0)


@dataclass(frozen=True)
class DataclassFrozen:
    a: int
    b: float


class DataclassFrozenEnum(DataclassFrozen, Enum):
    X = (1, 2.0)
    Y = (3, 4.0)


def test_enums() -> None:
    with raises(attrs.exceptions.FrozenInstanceError) as exc_info:

        class AttrsFrozenEnum(AttrsFrozen, Enum):
            X = (1, 2.0)
            Y = (3, 4.0)

        print(repr(AttrsFrozenEnum.X))

    print(exc_info.exconly())  # attrenum.py attr.exceptions.FrozenInstanceError
    print(repr(AttrsDefineEnum.X))  # AttrsDefineEnum(a=1, b=2.0)
    print(repr(DataclassEnum.X))  # <DataclassEnum.X: a=1, b=2.0>
    print(repr(DataclassFrozenEnum.X))  # <DataclassFrozenEnum.X: a=1, b=2.0>
❯ mypy attrenum.py
attrenum.py:15: error: Definition of "__hash__" in base class "AttrsDefine" is incompatible with definition in base class "Enum"  [misc]
Found 1 error in 1 file (checked 1 source file)
❯ pytest -s attrenum.py
===================================================================================================================== test session starts =====================================================================================================================
platform linux -- Python 3.12.4, pytest-8.3.1, pluggy-1.5.0
rootdir: /home/micael/projects/playground
collected 1 item                                                                                                                                                                                                                                              

attrenum.py attr.exceptions.FrozenInstanceError
AttrsDefineEnum(a=1, b=2.0)
<DataclassEnum.X: a=1, b=2.0>
<DataclassFrozenEnum.X: a=1, b=2.0>
.

====================================================================================================================== 1 passed in 0.02s ======================================================================================================================

@hynek hynek added the Bug label Jul 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Typing Typing/stub/Mypy/PyRight related bugs.
Projects
None yet
Development

No branches or pull requests

2 participants