Support enum iteration#1136
Conversation
|
|
||
| class Enum: | ||
| def __new__(cls, value: Any) -> None: ... | ||
| class EnumMeta(abc.ABCMeta, Iterable[Enum]): |
There was a problem hiding this comment.
In the enum.py code it inherits from type, not ABCMeta. Is there a reason to use ABCMeta here?
There was a problem hiding this comment.
Good point, let me see if that works.
|
This should do it. |
|
|
||
| _T = TypeVar('_T') | ||
|
|
||
| def unique(enumeration: _T) -> _T: ... |
There was a problem hiding this comment.
I thought this might break because of the new bound on _T, since this decorator applies to Enum classes, not Enum instances. But I tried it and it seems to work with mypy.
There was a problem hiding this comment.
Oh, hm, that might be by accident, or because something defaults to Any when mypy doesn't understand it. Would be nice to try this and see what the reveal_type(unique(Color)) actually says.
There was a problem hiding this comment.
$ cat ../bin/enumu.py
import enum
@enum.unique
class X(enum.Enum):
a = 1
b = 2
reveal_type(X)
$ mypy --custom-typeshed-dir . ../bin/enumu.py
../bin/enumu.py:7: error: Revealed type is 'def (value: Any) -> enumu.X'
This looks right to me.
There was a problem hiding this comment.
Hm...
import enum
class Colors(enum.Enum):
RED = 1
GREEN = 2
BLUE= 3
X = unique(Colors)
reveal_type(X)
Gives
__tmp__.py:12: error: Type argument 1 of "unique" has incompatible value "Colors"
__tmp__.py:13: error: Revealed type is 'def (value: Any) -> __tmp__.Colors'
(Sorry the line numbers are offset, it's about the last two lines.)
There was a problem hiding this comment.
Interesting, so it works differently when used as a decorator. That seems like a mypy bug.
There was a problem hiding this comment.
Oh, that's not how it's supposed to be used. As a class decorator it does indeed work as expected. Not sure why or how.
There was a problem hiding this comment.
Maybe to be safe we should give unique its own TypeVar for now.
|
Thanks! This will fix some |
* Use a separate type variable for unique() See #1136 (comment) * actually use the new typevar
Looks like this is in `typing.__all__` but was missed out of `typing_extensions.__all__`
Fixes python/mypy#2305.
Example:
(I found this unfinished project. Maybe it was waiting for some mypy improvement, or maybe I got distracted. Anyway, it seems to work now.)