Pyright: Enum members should belong to the type of their enum

Created on 25 Sep 2019  路  6Comments  路  Source: microsoft/pyright

Describe the bug
When I use type hinting for MyEnum member as type of MyEnum, pyright raises Expression of type 'Type[MyEnum]' cannot be assigned to declared type 'MyEnum'.

To Reproduce

import enum

class MyEnum(enum.Enum):
    AAA = enum.auto()
    BBB = enum.auto()


my_enum: MyEnum = MyEnum["AAA"]

Expected behavior
According to PEP 435, Enum members should belong to the type of their enum.
So it should pass the test.

VS Code extension or command-line
VSCode extention 1.0.65

addressed in next version bug

All 6 comments

Huh, I didn't realize that enum classes supported subscript notation (MyEnum["AAA"]). Pyright does the right thing if you use member access notation (MyEnum.AAA). I'll add support for the subscript notation as well. Thanks for the bug report.

Thank you for your work!

I use this subscript notation (MyEnum["AAA"]) in the following cases.

def some_func(enum_name: str):
    my_enum = MyEnum[enum_name]

some_func("AAA")

In this case, I can't use member access notation (MyEnum.AAA).

I am looking forward to supporting this notation!

I'm curious why you would use this pattern. By doing so, you're giving up a major benefit of type safety because the type checker can't verify that you are accessing a defined member of the enum. If you happen to mistype the name of an enum member, you will find the error only at runtime. Why not always use the member access notation rather than indirecting through an accessor function like the one above?

I've addressed the problem, and the fix will be in the next release of pyright.

Thank you for your quick work!

I use this notaion with a module which has command-line interface.
This CLI needs arguments with the same variations as Enum.

Most parts of the code are type-safe,
but parts that pass command-line arguments to main code block need to be converted from str to Enum.

For example:

import enum
import argparse


class ExecutePriorityOption(enum.Enum):
    HIGH = enum.auto()
    MIDDLE = enum.auto()
    LOW = enum.auto()


parser = argparse.ArgumentParser()

# usage: cli.py [-h] {HIGH,MIDDLE,LOW}
parser.add_argument(
    "priority", choices=[e.name for e in ExecutePriorityOption]
)

args = parser.parse_args()

priority_enum = ExecutePriorityOption[args.priority]
# something which use priority_enum...

I prefer this approach because I don't have to write selectable arguments specifically for the CLI and can reference the Enum type.

This is now fixed in 1.0.66, which I just published.

Was this page helpful?
0 / 5 - 0 ratings