3

I wanted to implement a class constant in an Enum using a descriptor with a type hint that mypy would recognize. My first step was trying the docs Simple example: A descriptor that returns a constant.

class Ten:
    def __get__(self, obj, objtype=None) -> int:
        return 10


class A:
    x = 5      # Regular class attribute
    y = Ten()  # Descriptor instance


reveal_type(A.x)  # Revealed type is "builtins.int"
reveal_type(A.y)  # Revealed type is "builtins.int"

Afterwards, applying the above simple example to an Enum has mypy recognize the type as a Literal instead of an int:

Revealed type is "Literal[my_module.B.y]?"

from enum import Enum


class Ten:
    def __get__(self, obj, objtype=None) -> int:
        return 10


class B(Enum):
    One = 1
    Two = 2

    y = Ten()  # Descriptor instance


reveal_type(B.y)   # Revealed type is "Literal[my_module.B.y]?"

Am I doing something wrong or Is this a mypy bug? If it's a bug is there a workaround?

bad_coder
  • 11,289
  • 20
  • 44
  • 72
  • 1
    Possibly related [issue 12494](https://github.com/python/mypy/issues/12494) leads to [PR 12669](https://github.com/python/mypy/pull/12669). – bad_coder May 30 '22 at 15:27
  • In case someone thinks of using a cast below the descriptor it won't work because of *"Attempted to reuse member name in Enum"* – bad_coder May 30 '22 at 21:42
  • 1
    "Possibly related issue 12494 leads to PR 12669." Yup. I just need to spend some time making my approach in that PR a little less hacky and disgusting :) – Alex Waygood Jun 09 '22 at 20:08
  • 1
    @AlexWaygood I'd love to help out if I had the time and expertise, but if you need someone to test it let me know. – bad_coder Jun 09 '22 at 20:31

0 Answers0