ValueError on Python Enum when comma seperated

Question:

Consider the following code.
How does python interpret class RottenFruit when it is comma separated? Is this legal? If yes, what is the use case?

from enum import Enum
class Fruit(Enum):
     Apple = 4
     Orange = 5
     Pear = 6 
a = Fruit(5)

class RottenFruit(Enum):
     Apple = 4,
     Orange = 5,
     Pear = 6
print(Fruit(5))
print(RottenFruit(5))

output:

Fruit.Orange
Traceback (most recent call last):
  File "...testssandbox.py", line 15, in <module>
    print(RottenFruit(5))
  File "...AppDataLocalProgramsPythonPython36libenum.py", line 291, in __call__
    return cls.__new__(cls, value)
  File "...AppDataLocalProgramsPythonPython36libenum.py", line 533, in __new__
    return cls._missing_(value)
  File "...AppDataLocalProgramsPythonPython36libenum.py", line 546, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 5 is not a valid RottenFruit
Asked By: goldcode

||

Answers:

Your second snippet is equivalent to this:

class RottenFruit(Enum):
     Apple = (4,)
     Orange = (5,)
     Pear = 6

In other words, Apple and Orange are each tuples of length one.

Let me add a quick explanation. You are running into the combination of two Python features here. One is that you can assign multiple things at once, like this:

 x = 7
 y = 8
 y, x = x, y  # Now x = 8 and y = 7
 q = [1, 2, 3, 4, 5]
 x, m, *r, y = q  # Even fancier: now x = 1, m = 2, r = [3, 4] and y = 5

The other is that parsing rules of Python always allow a trailing comma in a list; this is useful for having a list spanning multiple lines look a bit cleaner, and allows a one-element tuple to be defined with e.g. (1,). You have found a way to combine these rules in a way that’s not really useful, but isn’t worth preventing.

Answered By: Arthur Tacca
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.