Skip to content

Support Python 3.4 Enum #529

Closed
Closed

Description

@JukkaL

This requires some special casing in the type checker.

Activity

  1. pbdeuchler commented on Jun 22, 2015

    @pbdeuchler

    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

  2. spkersten commented on Jun 22, 2015

    @spkersten
    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.

  3. JukkaL commented on Jun 23, 2015

    @JukkaL
    CollaboratorAuthor

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

    @spkersten And thanks for helping with this!

  4. pbdeuchler commented on Jun 23, 2015

    @pbdeuchler

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

  5. spkersten commented on Jun 24, 2015

    @spkersten
    Contributor

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

  6. pbdeuchler commented on Jun 24, 2015

    @pbdeuchler

    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))
  7. refi64 commented on Jun 24, 2015

    @refi64
    Contributor

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

  8. refi64 commented on Jun 24, 2015

    @refi64
    Contributor

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

  9. berdario commented on May 5, 2016

    @berdario

    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)

  10. JukkaL commented on May 5, 2016

    @JukkaL
    CollaboratorAuthor

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

  11. gvanrossum commented on May 5, 2016

    @gvanrossum
    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
    
  12. graingert commented on May 11, 2016

    @graingert
    Contributor

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

  13. berdario commented on May 11, 2016

    @berdario

    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.

  14. pbdeuchler commented on May 11, 2016

    @pbdeuchler

    @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

  15. gvanrossum commented on May 11, 2016

    @gvanrossum
    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)])
    
  16. bbc2 commented on Oct 24, 2016

    @bbc2
    Contributor

    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__"
    
  17. gvanrossum commented on Oct 24, 2016

    @gvanrossum
    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: ...
  18. bbc2 commented on Oct 24, 2016

    @bbc2
    Contributor

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

  19. gvanrossum commented on Oct 24, 2016

    @gvanrossum
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions