-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Support enum iteration #1136
Support enum iteration #1136
Conversation
stdlib/3.4/enum.pyi
Outdated
|
||
class Enum: | ||
def __new__(cls, value: Any) -> None: ... | ||
class EnumMeta(abc.ABCMeta, Iterable[Enum]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, let me see if that works.
This should do it. |
@@ -20,8 +21,6 @@ class Enum: | |||
class IntEnum(int, Enum): | |||
value = ... # type: int | |||
|
|||
_T = TypeVar('_T') | |||
|
|||
def unique(enumeration: _T) -> _T: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$ 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, so it works differently when used as a decorator. That seems like a mypy bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
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.)