Skip to content

Support Python 3.4 Enum #529

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

Closed
JukkaL opened this issue Dec 12, 2014 · 19 comments
Closed

Support Python 3.4 Enum #529

JukkaL opened this issue Dec 12, 2014 · 19 comments
Labels

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Dec 12, 2014

This requires some special casing in the type checker.

@JukkaL JukkaL added the feature label Dec 12, 2014
@pbdeuchler
Copy link

Apologies if you don't want these sorts of comments, but if possible I'd love to +1 this feature... I use enums extensively and # type: ignore is making me a sad panda

@spkersten
Copy link
Contributor

@pbdeuchler I can't speak for Jukka, but I like hearing that people want to use mypy.

In PR #715 I've added some very rudimentary support for Enum's. It will not check much, but should at least remove the need for the ignore annotation. Check it out if you wish, to see if it makes mypy work better on your enums.

@JukkaL
Copy link
Collaborator Author

JukkaL commented Jun 23, 2015

It's always great to get feedback on which features would be useful for mypy users.

@spkersten And thanks for helping with this!

@pbdeuchler
Copy link

@spkersten looks awesome, does it have support for functionally created Enums?

@spkersten
Copy link
Contributor

@pbdeuchler what are functionally created Enums? Do you have a (minimal) example?

@pbdeuchler
Copy link

A common use case for me is parsing some sort of input and creating an enum on the fly with user defined options... for example:

Color = Enum('Color', 'red orange yellow green blue indigo violet ' + ' '.join(user_input_array))

@refi64
Copy link
Contributor

refi64 commented Jun 24, 2015

@pbdeuchler I don't think that's really possible without running the program.

@refi64
Copy link
Contributor

refi64 commented Jun 24, 2015

@pbdeuchler I'm slightly curious how you're actually using that at runtime, though. getattr?

@berdario
Copy link

berdario commented May 5, 2016

I'd really like this to work :/

The functional api is not only useful to create Enums at runtime, but it's also the simpler api that allows you to define one without having to specify superfluous values, e.g compare:

class Color(Enum):
    red = 1
    green = 2
    blue = 3

against

 Color = Enum('Color', 'red green blue')

At the moment, even specifying # type: ignore will yield down errors down the line when actually using the enum (forcing to litter all the code with Anys)

@JukkaL
Copy link
Collaborator Author

JukkaL commented May 5, 2016

The form Enum('Color', 'red green blue') with all literal arguments wouldn't be very hard to support, though it's probably not going to be implemented in the next few releases at least, since there is a workaround (even if it's pretty verbose) -- unless somebody wishes to contribute an implementation :-)

@gvanrossum
Copy link
Member

Personally I think that if you believe in static typing you should be using the full form

class Color(Enum):
    red = 1
    green = 2
    blue = 3

@graingert
Copy link
Contributor

@gvanrossum true, I think mypy should report an error saying to write out the Enum in full.

@berdario
Copy link

Uhm, I don't quite agree:

I find Enum useful as a poor man's sum type, to detect errors earlier than by simply using string/integer constants and document all the allowed values. From this point of view there's nothing to be gained by specifying the values, because the values themselves will never be used.

It's another matter if the idea is to use it as an Enumerative to actually map something to integers (or other values).

Anyhow, reporting an error to let users know that mypy actually supports other syntaxes for Enum is surely welcome.

@pbdeuchler
Copy link

@kirbyfan64 sorry for the late response, but yes, I'm using getattr.

@gvanrossum does this essentially mean that functionally created types are at odds with static typing in general? I don't necessarily disagree with you but it would be cool if we could hack it somehow since it's such a large part of python

@graingert @berdario i don't necessarily think an error is the right way to go here, especially given there will be mixed codebases without uniform type hinting

@gvanrossum
Copy link
Member

Well, what do you call "functionally created"? Certainly anything of this
form won't fly:

x = 'a b c'  # stands in for actual dynamic generation of list of field
names
t = namedtuple('t', x)

The only things that static typing could easily support would be if the
argument were a string literal. But then it's not so different from just
writing

t = namedtuple('t', ['a', 'b', 'c'])

Also the right thing to use is probably typing.NamedTuple which lets you
specify the types, as follows:

t = typing.NamedTuple('t', [('a', int), ('b', str), ('c', Any)])

@bbc2
Copy link
Contributor

bbc2 commented Oct 24, 2016

Full form enums are not well understood by mypy (0.4.5). Or did I do something wrong?

import enum


class Colors(enum.Enum):
    RED = 0
    BLUE = 1


print([color.name for color in Colors])
> python3 color.py 
['RED', 'BLUE']
> mypy color.py 
color.py:9: error: Iterable expected
color.py:9: error: "Colors" has no attribute "__iter__"

@gvanrossum
Copy link
Member

The issue in that last example is that mypy doesn't understand that for classes derived from Enum, the class object itself is iterable (and yields instances). mypy understands the class definition just fine:

from enum import Enum
class Color(Enum):
    RED = 1
    GREEN = 2
a = Color.RED
reveal_type(a)
a + Color.GREEN

produces

__tmp__.py:6: error: Revealed type is '__tmp__.Color'
__tmp__.py:7: error: Unsupported left operand type for + ("Color")

TBH I would much rather see two separate (new) issues, so we can close this one:

  • support for Color = Enum('Color', 'RED GREEN') (and the tuple variant)
  • support for x in Color: ...

@bbc2
Copy link
Contributor

bbc2 commented Oct 24, 2016

Makes sense. I just created a follow-up issue (#2305).

@gvanrossum
Copy link
Member

I've also created #2306. Closing this one since basic support is present.

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

No branches or pull requests

8 participants