7

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 "...\tests\sandbox.py", line 15, in <module>
    print(RottenFruit(5))
  File "...\AppData\Local\Programs\Python\Python36\lib\enum.py", line 291, in __call__
    return cls.__new__(cls, value)
  File "...\AppData\Local\Programs\Python\Python36\lib\enum.py", line 533, in __new__
    return cls._missing_(value)
  File "...\AppData\Local\Programs\Python\Python36\lib\enum.py", line 546, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 5 is not a valid RottenFruit
Neuron
  • 5,141
  • 5
  • 38
  • 59
goldcode
  • 633
  • 8
  • 21
  • I disagree with the "put on hold as off-topic" assessment. The OP is asking why they don't just get a simple syntax error for their use of commas. This is interesting and I didn't get it at first either. Edit: now it has been marked as a duplicate, but there is no link to the supposed original question. – Arthur Tacca Feb 09 '17 at 09:27

1 Answers1

9

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.

Arthur Tacca
  • 8,833
  • 2
  • 31
  • 49