Skip to content

Make enum values final #11919

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

Closed
joey-laminar opened this issue Jan 6, 2022 · 1 comment · Fixed by #11962
Closed

Make enum values final #11919

joey-laminar opened this issue Jan 6, 2022 · 1 comment · Fixed by #11962
Labels
bug mypy got something wrong topic-enum

Comments

@joey-laminar
Copy link
Contributor

#10852 made it so that boolean values are correctly identified as Literals in an enum. Other values seem to not be:

from enum import Enum

class Truth(Enum):
    true = True
    false = False

class MyInt(Enum):
    a = 0
    b = 1

class MyStr(Enum):
    a = "a"
    b = "b"

reveal_type(Truth.false.value)
reveal_type(MyInt.a.value)
reveal_type(MyStr.a.value)

Results in:

a.py:15: note: Revealed type is "Literal[False]?"
a.py:16: note: Revealed type is "builtins.int"
a.py:17: note: Revealed type is "builtins.str"

Expected result:

a.py:15: note: Revealed type is "Literal[False]?"
a.py:16: note: Revealed type is "Literal[0]"
a.py:17: note: Revealed type is "Literal['a']"

The enum members themselves (MyInt.a) are correctly identified as final, but their values should be as well

@joey-laminar joey-laminar added the bug mypy got something wrong label Jan 6, 2022
@joey-laminar
Copy link
Contributor Author

Some experimentation shows that commenting out lvalue.is_inferred_def = False inside of store_declared_types in semanal.py fixes this issue, although I'm sure it breaks a bunch of other things. I don't yet understand enough to know why this is called for all types except bool

joey-laminar added a commit to joey-laminar/mypy that referenced this issue Jan 10, 2022
This fix allows using enum values in place of literals.

For example:

```
def is_a(a: Literal["a"]): return None
class MyStr(Enum):
    a = "a"
    b = "b"

is_a(MyStr.a.value)
```

Currently this fails with

```
error: Argument 1 to "is_a" has incompatible type "str"; expected "Literal['a']"
```

The fix itself is simple - the special casing of  final status for enums was being
called too late to have an effect. Moving the function call up solves
the problem.
JelleZijlstra pushed a commit that referenced this issue Jan 10, 2022
This fix allows using enum values in place of literals.

For example:

```
def is_a(a: Literal["a"]): return None
class MyStr(Enum):
    a = "a"
    b = "b"

is_a(MyStr.a.value)
```

Currently this fails with

```
error: Argument 1 to "is_a" has incompatible type "str"; expected "Literal['a']"
```

The fix itself is simple - the special casing of  final status for enums was being
called too late to have an effect. Moving the function call up solves
the problem.

Fixes #11919
tushar-deepsource pushed a commit to DeepSourceCorp/mypy that referenced this issue Jan 20, 2022
This fix allows using enum values in place of literals.

For example:

```
def is_a(a: Literal["a"]): return None
class MyStr(Enum):
    a = "a"
    b = "b"

is_a(MyStr.a.value)
```

Currently this fails with

```
error: Argument 1 to "is_a" has incompatible type "str"; expected "Literal['a']"
```

The fix itself is simple - the special casing of  final status for enums was being
called too late to have an effect. Moving the function call up solves
the problem.

Fixes python#11919
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-enum
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants