Open perey opened 7 months ago
I couldn't find any such way, short of # type: ignore.
The solution has been to use a generic __init__(self, *args)
, and the same goes for __new__
.
from enum import Enum
class Planet(Enum):
MERCURY = (3.303e+23, 2.4397e6)
def __init__(self, *args) -> None:
self.mass = args[0]
self.radius = args[1]
mercury = Planet(Planet.MERCURY)
assert mercury is Planet.MERCURY
mercury = Planet((3.303e+23, 2.4397e6))
assert mercury is Planet.MERCURY
There are some issues related to (...)
There are a lot of mypy issues related to Enum. I gave up on checking for Enum fixes in new mypy releases.
Bug Report
The standard library's
enum.Enum
has a class method†__call__
that can take a member of the enumeration, or a member's value, and returns that member in either case.It is also possible to override the enumeration's
__init__
. The Python docs show an example that uses this to attach additional data to the members.If this is done, mypy reports an error when calling the class, expecting the call to follow the signature of
__init__
.To Reproduce
Playground
This is a stripped-down example of the one from the Python docs. It runs successfully (the asserts pass).
Expected Behavior
One possibility, of course, would be for mypy to produce no errors. But this is a somewhat odd situation, so failing that, there should be a way‡ to signal to mypy that this is what's happening.
I couldn't find any such way, short of
# type: ignore
. Overriding and annotating__call__
didn't work:This definition type-checks fine, but it doesn't affect the previous errors. (It's worth noting that this doesn't seem to actually override anything; the calls bypass it and go for the metaclass.)
It is possibly to go the other way and adapt the code to suit mypy, by making the use of
__call__
explicit. This type-checks fine:But that seems backwards to me.
Searching for existing issues or Q&As didn't turn up anything that looked like it matched. There are some issues related to the functional API (e.g. #10469, a dupe of #6037), which also uses
__call__
, but mypy specifically supports that. There's also #15024, but that appears to be about__call__
on an instance.Actual Behavior
Your Environment
† Technically it's implemented on the metaclass rather than by
@classmethod
.‡ Preferably something obvious, to be PEP 20-compliant. :wink: ("There should be one—and preferably only one—obvious way to do it. Although that way may not be obvious at first unless you're Dutch." Maybe the problem is that I'm not Dutch?)