classification
Title: enum.IntEnum is not compatible with JSON serialisation
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.4
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: ethan.furman Nosy List: amaury.forgeotdarc, barry, cvrebert, eli.bendersky, eric.snow, ethan.furman, ezio.melotti, giampaolo.rodola, gvanrossum, ncoghlan, pitrou, python-dev, rhettinger
Priority: normal Keywords: patch

Created on 2013-06-19 13:45 by ncoghlan, last changed 2013-08-10 20:01 by python-dev. This issue is now closed.

Files
File name Uploaded Description Edit
issue18264.1-prelim.patch eli.bendersky, 2013-08-02 23:38 review
issue18264.stoneleaf.01.patch ethan.furman, 2013-08-03 18:58 review
issue18264.stoneleaf.02.patch ethan.furman, 2013-08-04 17:48 review
issue18264.stoneleaf.03.patch ethan.furman, 2013-08-04 18:11 review
issue18264.stoneleaf.04.patch ethan.furman, 2013-08-06 12:23 review
issue18264.stoneleaf.05.patch ethan.furman, 2013-08-06 13:06 review
Messages (50)
msg191467 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2013-06-19 13:45
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).
msg191470 - (view) Author: Barry A. Warsaw (barry) * (Python committer) Date: 2013-06-19 13:58
On Jun 19, 2013, at 01:45 PM, Nick Coghlan wrote:

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

Serialization isn't the only issue - you have to know how to deserialize as
well.  I use JSON extensively in Mailman's REST API.  For enums I always
encode them to just the member name, because I always know what enum class
will be used to deserialize them.

(TBH, I wish the json module had better hooks for extending both serialization
and deserialization of non-basic types.)
msg191471 - (view) Author: Eric Snow (eric.snow) * (Python committer) Date: 2013-06-19 14:03
It's for times like this that I wonder if a simple serialization protocol might be worth it--something separate from __str__() but much simpler than the pickle protocol.  __str__() could be the fallback.  In the end, though, I always conclude that it's not worth adding yet another optional protocol to objects.  Still, it would help in this case (at least for anything that knows to make use of the simple serialization protocol).

Alternately, would it make sense to add special handling of enums to the json module?  Do we already with pickle?
msg191473 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2013-06-19 14:09
in encoder.py:
    ...
    elif instance(value, int):
        yield buf + str(value)
    ...
What if we use int(str(value)) instead?
msg191474 - (view) Author: Eric Snow (eric.snow) * (Python committer) Date: 2013-06-19 14:09
> Serialization isn't the only issue - you have to know how
> to deserialize as well.

+1

> (TBH, I wish the json module had better hooks for extending
> both serialization and deserialization of non-basic types.)

+1

There's at least one stdlib module that does this pretty well (sqlite3, I think).  This is where a simple serialization (and deserialization of course) protocol would come in handy.
msg191475 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-06-19 14:12
Nick, in your example it looks like json is using the __str__ for int, but the __repr__ for float -- is this correct?
msg191476 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-06-19 14:13
Eric,

The pickle support is solely in Enum.  No changes were made to pickles.
msg191477 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-06-19 14:21
> What if we use int(str(value)) instead?

You mean str(int(value)). Sounds good to me.
msg191478 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2013-06-19 14:23
> Serialization isn't the only issue - you have to know how to
> deserialize as well.

I think this is pretty much besides the point. IntEnums are meant to be substitutible with plain ints, so you can deserialize as a plain int.

Moreoven, JSON doesn't fill the same use cases as pickle: it is meant to communicate with services written in any languages, and those services won't have the same enum mnemonics as your Python library.
msg191479 - (view) Author: Barry A. Warsaw (barry) * (Python committer) Date: 2013-06-19 14:23
On Jun 19, 2013, at 02:09 PM, Eric Snow wrote:

>There's at least one stdlib module that does this pretty well (sqlite3, I
>think).  This is where a simple serialization (and deserialization of course)
>protocol would come in handy.

Yeah, my database layer also has to be taught how to handle enums!
msg191480 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2013-06-19 14:32
While I agree with forcing int subclasses to true integers in the JSON module, that may not be enough - the problem will affect third party serialisers as well. Whiel the debugging gains won't be as high, we may need to override __str__() in enum.IntEnum to give the "raw" form (leaving the debugging form solely for repr).

As for the float behaviour, the JSON serialiser is almost certainly playing games to avoid the truncation that used to occur in float.__str__ (I don't recall if we actually got rid of that, or if it's just a lot harder to trigger these days - it definitely changed when float.__repr__ was updated to prefer human friendly representations that produce the same floating point number). I'm less concerned about that, since we don't plan to swap out any standard library floats for enums. We may still want to mention the potential compatibility issue somewhere in the docs, though.

Backwards compatibility is such fun, isn't it? :)
msg191481 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-06-19 14:42
I have no problem with leaving __str__ as the inherited type's, and just keeping the __repr__ as the enum add-on; this could be one of the differences between a pure Enum and a hybrid Enum.

Is it safe to change the json behaviour back to using __str__ for floats?  If so, those two updates and we could be good to go.  (Famous last words? ;)
msg191491 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-06-19 20:15
I was unable to find any references to previous problems with json and floats.  A quick-n-dirty patch yields the following:

--> from json import dumps, loads
--> from enum import Enum
--> class FE(float, Enum):
...   pass
... 
--> class Test(FE):
...   one = 1.0
... 
--> Test.one
<Test.one: 1.0>
--> str(Test.one)
'1.0'
--> dumps(Test.one)
'1.0'
--> loads(dumps(Test.one))
1.0

All json and enum tests are still passing.

If this is an acceptable solution I'll create a nicer patch and post for review.
msg191498 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-06-20 01:48
Here's the relevant routine from _json.c:
-----------------------------------------

static PyObject *
encoder_encode_float(PyEncoderObject *s, PyObject *obj)
{
    /* Return the JSON representation of a PyFloat */
    double i = PyFloat_AS_DOUBLE(obj);
    if (!Py_IS_FINITE(i)) {
        if (!s->allow_nan) {
            PyErr_SetString(PyExc_ValueError, "Out of range float values are not JSON compliant");
            return NULL;
        }
        if (i > 0) {
            return PyUnicode_FromString("Infinity");
        }
        else if (i < 0) {
            return PyUnicode_FromString("-Infinity");
        }
        else {
            return PyUnicode_FromString("NaN");
        }
    }
    /* Use a better float format here? */
    return PyObject_Repr(obj);
}


Possible solutions
------------------

  - Use PyObject_Str() instead of PyObject_Repr()

    I was unable to find any references to why it isn't currently PyObject_Str(), but switching over to it did not break any tests

  - Coerce the obj to a PyFloat, and take the repr of that (just use the `i`)

    float subclasses would always lose the subclass status, but that is lost on deserialization anyway unless a custom decoder is used; and if a custom decoder is being used I would think a custom encoder is also being used?


Summary
-------

Having hybrid Enums not change __str__ would solve most of the json serialization issues;
either of the above two changes will solve the json issue of enumerated floats.

Thoughts on which route to take for json?
msg191586 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2013-06-21 14:49
The proposal to change json from using repr() to str() has unknown dangers.

I don't want the str() of IntEnum to return just the decimal string (e.g. "42"), since that breaks half of the usefulness of using the enum in the first place -- people will write print(x) and be confused.

Unfortunately the json module doesn't have a way to define *in the object* how to customize its serialization -- this is always done in the json encoder/decoder.  Maybe we can add something to the JSON encoder and decoder class that looks for a special method, e.g. __json_encode__ etc.?  (OR maybe this would be a use case for PEP 443?)
msg191587 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2013-06-21 14:50
Modifying json to use str(int(value)) (if it detects isinstance(value, int)) is fine with me too.
msg191588 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2013-06-21 14:51
And similar for floats, really.
msg191601 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-06-21 17:35
I'd be in favor of the __protocol__ route first and the PEP 443 route second.

The problem with just tacking in `str(int(value))` or `str(float(value))` is where does it stop?  StrEnum, TupleEnum, BytesEnum, ComplexEnum, SomeOtherInterestingConstantEnum, etc., etc..

If we go the __protocol__ route we add one method to Enum which returns the `str` of its `.value`, and we're set for every Enum.*  As a bonus, any other object that needs special json (or yaml or whatever) consideration has a fairly easy way to make it happen.

*Every normal Enum, anyway. ;)
msg191625 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2013-06-22 01:08
Can I vote for something like "__builtin__" as the protocol, rather than
something entirely specific to serialisation? As in "return the most
appropriate builtin type with the same value"? Then a converter
("operator.builtin"?) could coerce builtin subclasses to their base classes
by default, rather than needing to implement the protocol on every type.

Such a design would need a PEP, of course.
msg191626 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2013-06-22 01:17
Hm. Then I prefer just calling the appropriate builtin, e.g. int().

--Guido van Rossum (sent from Android phone)
On Jun 21, 2013 6:08 PM, "Nick Coghlan" <report@bugs.python.org> wrote:

>
> Nick Coghlan added the comment:
>
> Can I vote for something like "__builtin__" as the protocol, rather than
> something entirely specific to serialisation? As in "return the most
> appropriate builtin type with the same value"? Then a converter
> ("operator.builtin"?) could coerce builtin subclasses to their base classes
> by default, rather than needing to implement the protocol on every type.
>
> Such a design would need a PEP, of course.
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue18264>
> _______________________________________
>
msg191628 - (view) Author: Barry A. Warsaw (barry) * (Python committer) Date: 2013-06-22 01:59
On Jun 22, 2013, at 01:08 AM, Nick Coghlan wrote:

>Can I vote for something like "__builtin__" as the protocol, rather than
>something entirely specific to serialisation? As in "return the most
>appropriate builtin type with the same value"? Then a converter
>("operator.builtin"?) could coerce builtin subclasses to their base classes
>by default, rather than needing to implement the protocol on every type.

Such a protocol needs a way to deserialize as well.  You can't necessarily
assume (or shouldn't impose) that the __init__() can do that conversion.  In
any case...

>Such a design would need a PEP, of course.

...yes, definitely.
msg191630 - (view) Author: Eli Bendersky (eli.bendersky) * (Python committer) Date: 2013-06-22 02:45
On Fri, Jun 21, 2013 at 6:59 PM, Barry A. Warsaw <report@bugs.python.org>wrote:

>
> Barry A. Warsaw added the comment:
>
> On Jun 22, 2013, at 01:08 AM, Nick Coghlan wrote:
>
> >Can I vote for something like "__builtin__" as the protocol, rather than
> >something entirely specific to serialisation? As in "return the most
> >appropriate builtin type with the same value"? Then a converter
> >("operator.builtin"?) could coerce builtin subclasses to their base
> classes
> >by default, rather than needing to implement the protocol on every type.
>
> Such a protocol needs a way to deserialize as well.  You can't necessarily
> assume (or shouldn't impose) that the __init__() can do that conversion.
>  In
> any case...
>
> >Such a design would need a PEP, of course.
>
> ...yes, definitely.

Practically speaking, what should be done to make enum play well with JSON
without writing new PEPs? I think we still want to convert those stdlib
constants to IntEnums...

Eli
msg191631 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2013-06-22 02:49
Change json to call int() first.

--Guido van Rossum (sent from Android phone)
On Jun 21, 2013 7:45 PM, "Eli Bendersky" <report@bugs.python.org> wrote:

>
> Eli Bendersky added the comment:
>
> On Fri, Jun 21, 2013 at 6:59 PM, Barry A. Warsaw <report@bugs.python.org
> >wrote:
>
> >
> > Barry A. Warsaw added the comment:
> >
> > On Jun 22, 2013, at 01:08 AM, Nick Coghlan wrote:
> >
> > >Can I vote for something like "__builtin__" as the protocol, rather than
> > >something entirely specific to serialisation? As in "return the most
> > >appropriate builtin type with the same value"? Then a converter
> > >("operator.builtin"?) could coerce builtin subclasses to their base
> > classes
> > >by default, rather than needing to implement the protocol on every type.
> >
> > Such a protocol needs a way to deserialize as well.  You can't
> necessarily
> > assume (or shouldn't impose) that the __init__() can do that conversion.
> >  In
> > any case...
> >
> > >Such a design would need a PEP, of course.
> >
> > ...yes, definitely.
>
> Practically speaking, what should be done to make enum play well with JSON
> without writing new PEPs? I think we still want to convert those stdlib
> constants to IntEnums...
>
> Eli
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue18264>
> _______________________________________
>
msg191632 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-06-22 03:23
On 06/21/2013 07:49 PM, Guido van Rossum wrote:
> Eli Bendersky added the comment:
>>
>> Practically speaking, what should be done to make enum play well with JSON
>> without writing new PEPs? I think we still want to convert those stdlib
>> constants to IntEnums...
>
> Change json to call int() first.

Should we have json call float() and str() first as well?  I'm thinking less of the stdlib and more of the unsuspecting 
user.
msg191633 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2013-06-22 04:55
Yes for float() -- but for str() it would seem redundant? (Or what's
the context?)

On Fri, Jun 21, 2013 at 8:23 PM, Ethan Furman <report@bugs.python.org> wrote:
>
> Ethan Furman added the comment:
>
> On 06/21/2013 07:49 PM, Guido van Rossum wrote:
>> Eli Bendersky added the comment:
>>>
>>> Practically speaking, what should be done to make enum play well with JSON
>>> without writing new PEPs? I think we still want to convert those stdlib
>>> constants to IntEnums...
>>
>> Change json to call int() first.
>
> Should we have json call float() and str() first as well?  I'm thinking less of the stdlib and more of the unsuspecting
> user.
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue18264>
> _______________________________________
msg191634 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-06-22 05:08
Guido van Rossum added the comment:
>
> Yes for float() -- but for str() it would seem redundant? (Or what's
> the context?)

If a user has

     class Color(StrEnum):
         red = 'ff0000'
         green = '00ff00'
         blue = '0000ff'

..
..
..

oh.  `str()` isn't going to give is the `value`'s string, is it?

Hmmm...

Instead of calling int() or float() on an enum member, perhaps we could make json smart enough to use the `value`?  That 
would also cover pure Enums.
msg191635 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2013-06-22 05:23
Whatever we do needs to be something third party serialisation libraries
can also adopt with minimal compatibility risk for older versions of Python.

Yes, that serialisation will lose the new debugging information. That's
fine - if people want to map from a standard format like JSON to enums,
they have to handle that themselves anyway.
msg194219 - (view) Author: Eli Bendersky (eli.bendersky) * (Python committer) Date: 2013-08-02 23:38
I've been reading the discussion again to figure out what we need to move forward; it appears that a simple approach of using str(int(obj)) in json encoding when isinstance(obj, int) was acceptable for many of the participants, and it helps solve the most common problem - the one with IntEnum. We can solve it now, move on to converting socket.* and other constants to IntEnum and perhaps change the solution to something more grandiose later.

I'm attaching a proof-of-concept (probably incomplete) patch that implements this for the Python and C implementations of json.

With it applied, Nick's example goes like this:

>>> from enum import IntEnum
>>> import json
>>> class Example(IntEnum): x = 1
... 
>>> json.dumps(Example.x)
'1'
>>> json.loads(json.dumps(Example.x))
1
>>> 

When thinking about the more generic approaches, we must consider what was raised here already - JSON interoperates with other languages, for which Python's enum is meaningless (think of JavaScript, for instance). So the only logical way to JSON-encode a IntEnum is str(int(...)).
msg194220 - (view) Author: Eli Bendersky (eli.bendersky) * (Python committer) Date: 2013-08-02 23:39
[please note that the patch is POC/hacky at best - it's likely to leak memory and be careless and incomplete in other ways. I'm just trying to demonstrate the approach]
msg194222 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-08-02 23:55
I'll check you patch later against big numbers (which is where I had difficulties).  If it works I'll try to make it more complete.  If it doesn't, I've been working on just extraction the Enum member's value and using that (works fine on the Python side ;) .

Big Question:  if the Enum member was used as a key, do we use .name or .value?  The decision I went with was to compare the hashes of the member name vs the member itself -- if they're the same, use the .name, otherwise use the value.
msg194223 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-08-03 00:05
I don't think my idea of always extracting .value is grandiose (and didn't take that long to implement on the Python side), but it is definitely forcing me to learn more about C and how Python is put together.

It this point I have successfully imported Enum into the _json module; now I'm working on a function to quietly replace the object being encoded with its .value if it is, in fact, an Enum member.

Just been real short on time lately.  :/

Thank goodness for C API section of the docs!
msg194266 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-08-03 14:46
Eli, your method is good.  I thought I had tried something similar but I obviously had the wrong PyLong constructor.

I'll get it implemented.
msg194280 - (view) Author: Eli Bendersky (eli.bendersky) * (Python committer) Date: 2013-08-03 18:19
Yes, AFAIU PyNumber_Long is the equivalent of Python-level int(obj). With other constructors of PyLong you are limited by long long (while Python integers may be arbitrarily large).

Ethan - If you're still short on time I can pretty up this patch and put it for review with some tests. Let me know what you prefer.
msg194283 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-08-03 18:21
Thanks for the offer, Eli, but I almost have the tests done.  :)
msg194289 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-08-03 18:58
Okay, patch attached with C code (thanks, Eli!), more python code, and some new tests.

Only the `int` case is handled.
msg194306 - (view) Author: Eli Bendersky (eli.bendersky) * (Python committer) Date: 2013-08-03 22:00
Posted a Rietveld code review
msg194322 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2013-08-04 01:53
It occurs to me that operator.index() (without a preceding type check) is
likely the more ducktyping friendly option here.
msg194327 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-08-04 07:21
I don't understand.

Type checks are already performed throughout the code (int, float, True, False, NaN, Inf, etc.).

What will opereator.index buy us?
msg194330 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2013-08-04 07:49
The two "isinstance" checks that bother me are the ones for int and float. However, given that the JSON serialiser *already* includes those explicit checks, I now think it makes sense to just do the minimal fix of coercing subclasses to the base type for both of those cases, especially since such a change should be able to be ported to simplejson as well.

Anything more elaborate (including making JSON explicitly enum aware, or else offering a new encoder that supports singledispatch) should be handled in a separate issue.
msg194360 - (view) Author: Eli Bendersky (eli.bendersky) * (Python committer) Date: 2013-08-04 12:42
I also think that exchanging the explicit type checks by __index__ merits more thought and is outside the scope of this local fix. The proposed patch does not add any new type checks, but acts within the bounds of code for which the type is already established.
msg194401 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-08-04 17:48
This patch handles both float and int subclasses, and includes fixes/improvements from the review.
msg194403 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-08-04 18:11
Forgot to add float tests.  Included in this patch.
msg194536 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-08-06 12:23
Hopefully the final patch.  :)
msg194539 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-08-06 13:06
Forgot to back out core dump tests before creating previous patch.  This one even passes the tests.  :/
msg194541 - (view) Author: Eli Bendersky (eli.bendersky) * (Python committer) Date: 2013-08-06 13:11
LGTM now. Make sure to run the test(s) in refleak mode and let's wait for a couple of days before committing, in case someone else has comments.
msg194543 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-08-06 13:41
I'll plan on committing no sooner than Friday unless somebody else has comments/corrections.

Thanks, Eli.
msg194554 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2013-08-06 14:50
> Eli Bendersky added the comment:
>
> Make sure to run the test(s) in refleak mode . . .

How extensive should testing be?

I plan on always running the refleak mode tests (now that I know how ;) .

Should I also run non-refleak tests?

Should I run tests with a python built without --with-pydebug?
msg194556 - (view) Author: Eli Bendersky (eli.bendersky) * (Python committer) Date: 2013-08-06 15:31
IMHO it's very much dependent on the change. When making C code changes, I usually run the relevant tests with refleaks, and then run the whole test suite; all of this --with-pydebug. Personally I've not encountered cases where non-debug builds failed where debug suceeded for CPython, but for very significant changes I may do some extra runs in the release mode as well (or try to test it on a specific OS). It's very important to watch the bots after committing, because they run a wide variety of configurations you'll be hard pressed to reproduce on your own - so they exercise the change pretty well.
msg194558 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2013-08-06 15:33
> I plan on always running the refleak mode tests (now that I know how ;) 

FWIW `make patchcheck` should remind you about that.
msg194828 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2013-08-10 20:01
New changeset ae1a7c420f08 by Ethan Furman in branch 'default':
Close #18264: int- and float-derived enums now converted to int or float.
http://hg.python.org/cpython/rev/ae1a7c420f08
History
Date User Action Args
2013-08-10 20:01:54python-devsetstatus: open -> closed

nosy: + python-dev
messages: + msg194828

resolution: fixed
stage: patch review -> resolved
2013-08-06 15:33:57ezio.melottisettype: enhancement
messages: + msg194558
stage: patch review
2013-08-06 15:31:35eli.benderskysetmessages: + msg194556
2013-08-06 14:50:28ethan.furmansetmessages: + msg194554
2013-08-06 13:41:14ethan.furmansetmessages: + msg194543
2013-08-06 13:11:31eli.benderskysetmessages: + msg194541
2013-08-06 13:06:06ethan.furmansetfiles: + issue18264.stoneleaf.05.patch

messages: + msg194539
2013-08-06 12:23:49ethan.furmansetfiles: + issue18264.stoneleaf.04.patch

messages: + msg194536
2013-08-04 18:11:14ethan.furmansetfiles: + issue18264.stoneleaf.03.patch

messages: + msg194403
2013-08-04 17:48:43ethan.furmansetfiles: + issue18264.stoneleaf.02.patch

messages: + msg194401
2013-08-04 12:42:13eli.benderskysetmessages: + msg194360
2013-08-04 07:49:06ncoghlansetmessages: + msg194330
2013-08-04 07:21:43ethan.furmansetmessages: + msg194327
2013-08-04 01:53:07ncoghlansetmessages: + msg194322
2013-08-03 22:00:28eli.benderskysetmessages: + msg194306
2013-08-03 18:58:04ethan.furmansetfiles: + issue18264.stoneleaf.01.patch

messages: + msg194289
2013-08-03 18:21:52ethan.furmansetmessages: + msg194283
2013-08-03 18:19:06eli.benderskysetmessages: + msg194280
2013-08-03 14:46:39ethan.furmansetmessages: + msg194266
2013-08-03 00:05:57ethan.furmansetmessages: + msg194223
2013-08-02 23:55:58ethan.furmansetmessages: + msg194222
2013-08-02 23:39:57eli.benderskysetmessages: + msg194220
2013-08-02 23:38:45eli.benderskysetfiles: + issue18264.1-prelim.patch
keywords: + patch
messages: + msg194219
2013-07-19 00:32:15cvrebertsetnosy: + cvrebert
2013-07-18 23:11:40giampaolo.rodolasetnosy: + giampaolo.rodola
2013-06-22 05:23:35ncoghlansetmessages: + msg191635
2013-06-22 05:08:17ethan.furmansetmessages: + msg191634
2013-06-22 04:55:33gvanrossumsetmessages: + msg191633
2013-06-22 03:23:26ethan.furmansetmessages: + msg191632
2013-06-22 02:49:12gvanrossumsetmessages: + msg191631
2013-06-22 02:45:35eli.benderskysetmessages: + msg191630
2013-06-22 01:59:05barrysetmessages: + msg191628
2013-06-22 01:17:52gvanrossumsetmessages: + msg191626
2013-06-22 01:08:31ncoghlansetmessages: + msg191625
2013-06-21 17:35:59ethan.furmansetmessages: + msg191601
2013-06-21 14:51:51gvanrossumsetmessages: + msg191588
2013-06-21 14:50:57gvanrossumsetmessages: + msg191587
2013-06-21 14:49:03gvanrossumsetnosy: + gvanrossum
messages: + msg191586
2013-06-20 01:48:06ethan.furmansetmessages: + msg191498
2013-06-19 21:30:01ethan.furmansetnosy: + rhettinger, ezio.melotti
2013-06-19 20:15:25ethan.furmansetmessages: + msg191491
2013-06-19 14:42:01ethan.furmansetmessages: + msg191481
2013-06-19 14:32:19ncoghlansetmessages: + msg191480
2013-06-19 14:23:13barrysetmessages: + msg191479
2013-06-19 14:23:12pitrousetmessages: + msg191478
2013-06-19 14:21:52pitrousetnosy: + pitrou
messages: + msg191477
2013-06-19 14:13:46ethan.furmansetmessages: + msg191476
2013-06-19 14:12:06ethan.furmansetassignee: ethan.furman

messages: + msg191475
nosy: + eli.bendersky, ethan.furman
2013-06-19 14:09:36eric.snowsetmessages: + msg191474
2013-06-19 14:09:00amaury.forgeotdarcsetnosy: + amaury.forgeotdarc
messages: + msg191473
2013-06-19 14:03:01eric.snowsetnosy: + eric.snow
messages: + msg191471
2013-06-19 13:58:04barrysetmessages: + msg191470
2013-06-19 13:55:29barrysetnosy: + barry
2013-06-19 13:45:41ncoghlancreate