Skip to content
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

Merged
merged 2 commits into from
Apr 4, 2017
Merged

Support enum iteration #1136

merged 2 commits into from
Apr 4, 2017

Conversation

gvanrossum
Copy link
Member

Fixes python/mypy#2305.

Example:

import enum
class Colors(enum.Enum):
    RED = 0
    BLUE = 1
print([color.name for color in Colors])  # This used to fail, now it works

(I found this unfinished project. Maybe it was waiting for some mypy improvement, or maybe I got distracted. Anyway, it seems to work now.)


class Enum:
def __new__(cls, value: Any) -> None: ...
class EnumMeta(abc.ABCMeta, Iterable[Enum]):
Copy link
Member

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?

Copy link
Member Author

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.

@gvanrossum
Copy link
Member Author

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: ...
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member Author

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.)

Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member

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.

@JelleZijlstra JelleZijlstra merged commit 7027c3e into master Apr 4, 2017
@JelleZijlstra
Copy link
Member

Thanks! This will fix some # type: ignores in my code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants