The 4 major type checkers are handling this snippet very differently:
(playground links: Mypy, Pyright, Pyre; Pytype was run with -k -n)
from enum import Enum, auto
from typing import Self, final
class C: ...
class CEnum(C, Enum): ...
class CI(CEnum):
A = auto()
B = auto()
@classmethod
def return_member(cls) -> Self:
# mypy => Incompatible return value type (got "CI", expected "Self")
# pyright => Expression of type "Literal[CI.A]" is incompatible with return type "Self@CI"
# pyre => Expected `Variable[_Self_playground_input_CI__ (bound to CI)]` but got `CI`.
# pytype => fine
# expected => fine
return cls.A
@final
class FinalCI(CEnum):
A = auto()
B = auto()
@classmethod
def return_member(cls) -> Self:
# mypy => fine
# pyright => Expression of type "Literal[FinalCI.A]" is incompatible with return type "Self@FinalCI"
# pyre => Expected `Variable[_Self_playground_input_FinalCI__ (bound to FinalCI)]` but got `FinalCI`.
# pytype => fine
# expected => fine
return cls.A
# mypy => Cannot extend enum with existing members: "CI"
# pyright => Enum class "CI" is final and cannot be subclassed
# pyre => fine
# pytype => fine
# expected => error
class CIChild(CI):
...
@final
class D:
@classmethod
def return_member(cls) -> Self:
# mypy => fine
# pyright => Expression of type "D" is incompatible with return type "Self@D"
# pyre => Expected `Variable[_Self_playground_input_D__ (bound to D)]` but got `D`.
# pytype => fine
# expected => fine
return D()
Results:
- Mypy: 3/4
- Pyright: 1/4
- Pyre: 0/4
- Pytype: 3/4
According to the specs:
An Enum class with one or more defined members cannot be subclassed. They are implicitly “final”.
Perhaps a clarification like this could be added along with corresponding tests?
When used as the return type of an enum class’s method,
Selfmeans the same as the class itself:class Shape(EnumWithNoMembers): SQUARE = 1 CIRCLE = 2 def m(self) -> Self: # OK (there can be no subclasses of Shape) return Shape.SQUARE @classmethod def cm(cls) -> Self: # OK (there can be no subclasses of Shape) return Shape.SQUARE