[Python] Enum of dataclass works but frozen attrs doesn't

Discussão em 'Python' iniciado por Stack, Outubro 20, 2024.

  1. Stack

    Stack Membro Participativo

    The built-in enum provides a way to create enums of primitive types (IntEnum, StrEnum).

    I'd like to create an enum of structured objects.

    One way to do that is with dataclass, and it works:

    from dataclasses import dataclass
    from enum import Enum

    from typing_extensions import assert_never

    @dataclass(frozen=True)
    class _BaseInstTypeDataclass:
    instance_type: str
    display_name: str


    class InstTypeDataClass(_BaseInstTypeDataclass, Enum):
    t2_micro = ("t2.micro", "t2.micro: Cheap!")
    r7i_2xlarge = ("r7i.2xlarge", "r7i.2xlarge: Expensive!")


    assert list(InstTypeDataClass) == [
    InstTypeDataClass.t2_micro,
    InstTypeDataClass.r7i_2xlarge,
    ]
    assert isinstance(InstTypeDataClass.t2_micro, InstTypeDataClass)


    # This function type checks
    def f_dataclass(e: InstTypeDataClass):
    if e == InstTypeDataClass.t2_micro:
    ...
    elif e == InstTypeDataClass.r7i_2xlarge:
    ...
    else:
    assert_never(e)


    Both the static- (via pyright) and runtime-behavior is as expected.

    However, with attrs...:

    import attrs


    @attrs.define(frozen=True)
    class _BaseInstTypeAttrs:
    instance_type: str
    display_name: str


    class InstTypeAttrs(_BaseInstTypeAttrs, Enum):
    t2_micro = ("t2.micro", "t2.micro: Cheap!")
    r7i_2xlarge = ("r7i.2xlarge", "r7i.2xlarge: Expensive!")


    # This function type checks
    def f_attrs(e: InstTypeAttrs):
    if e == InstTypeAttrs.t2_micro:
    ...
    elif e == InstTypeAttrs.r7i_2xlarge:
    ...
    else:
    assert_never(e)


    ... the type checker is happy, but at run-time...:

    $ python foo.py
    _BaseInstTypeDataclass(instance_type='foo', display_name='bar')
    Traceback (most recent call last):
    File "foo.py", line 58, in <module>
    class InstTypeAttrs(_BaseInstTypeAttrs, Enum):
    File "/Users/.../python3.10/enum.py", line 287, in __new__
    enum_member._value_ = value
    File "/Users/.../python3.10/site-packages/attr/_make.py", line 551, in _frozen_setattrs
    raise FrozenInstanceError()
    attr.exceptions.FrozenInstanceError


    Is this because... Enum and attrs.define(frozen=True) don't play nice...?

    Continue reading...

Compartilhe esta Página