Author ncoghlan
Recipients ncoghlan
Date 2013-06-19.13:45:40
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1371649541.07.0.776235119954.issue18264@psf.upfronthosting.co.za>
In-reply-to
Content
Replacing an integer constant with the current incarnation of enum.IntEnum breaks JSON serialisation:

>>> from enum import Enum
>>> from enum import Enum, IntEnum
>>> class Example(IntEnum):
...     x = 1
... 
>>> import json
>>> json.dumps(1)
'1'
>>> json.loads(json.dumps(1))
1
>>> json.dumps(Example.x)
'Example.x'
>>> json.loads(json.dumps(Example.x))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/ncoghlan/devel/py3k/Lib/json/__init__.py", line 316, in loads
    return _default_decoder.decode(s)
  File "/home/ncoghlan/devel/py3k/Lib/json/decoder.py", line 344, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/home/ncoghlan/devel/py3k/Lib/json/decoder.py", line 362, in raw_decode
    raise ValueError(errmsg("Expecting value", s, err.value)) from None
ValueError: Expecting value: line 1 column 1 (char 0)

It breaks for floats as well, but in a slightly different way:

>>> class FloatExample(float, Enum):
...     x = 1.0
... 
>>> json.dumps(FloatExample.x)
'<FloatExample.x: 1.0>'

Allowing __str__ to be inherited from Enum rather than from the concrete type will similarly break any serialisation protocol that relies on str() to handle integers. The float case is even trickier, since failing to inherit __repr__ would rather miss the point of the whole exercise...

We're going to have to be *very* careful with swapping out existing constants with enums, and we should be warning about the pitfalls in the docs too (where we can't change enum to avoid them).
History
Date User Action Args
2013-06-19 13:45:41ncoghlansetrecipients: + ncoghlan
2013-06-19 13:45:41ncoghlansetmessageid: <1371649541.07.0.776235119954.issue18264@psf.upfronthosting.co.za>
2013-06-19 13:45:41ncoghlanlinkissue18264 messages
2013-06-19 13:45:40ncoghlancreate