diff -r 2b3b873e2b19 Lib/json/encoder.py --- a/Lib/json/encoder.py Tue Jul 30 12:24:25 2013 -0700 +++ b/Lib/json/encoder.py Sat Aug 03 11:55:25 2013 -0700 @@ -291,21 +291,21 @@ def _make_iterencode(markers, _default, buf = separator if isinstance(value, str): yield buf + _encoder(value) elif value is None: yield buf + 'null' elif value is True: yield buf + 'true' elif value is False: yield buf + 'false' elif isinstance(value, int): - yield buf + str(value) + yield buf + str(int(value)) elif isinstance(value, float): yield buf + _floatstr(value) else: yield buf if isinstance(value, (list, tuple)): chunks = _iterencode_list(value, _current_indent_level) elif isinstance(value, dict): chunks = _iterencode_dict(value, _current_indent_level) else: chunks = _iterencode(value, _current_indent_level) @@ -347,41 +347,41 @@ def _make_iterencode(markers, _default, # also allow them. Many encoders seem to do something like this. elif isinstance(key, float): key = _floatstr(key) elif key is True: key = 'true' elif key is False: key = 'false' elif key is None: key = 'null' elif isinstance(key, int): - key = str(key) + key = str(int(key)) elif _skipkeys: continue else: raise TypeError("key " + repr(key) + " is not a string") if first: first = False else: yield item_separator yield _encoder(key) yield _key_separator if isinstance(value, str): yield _encoder(value) elif value is None: yield 'null' elif value is True: yield 'true' elif value is False: yield 'false' elif isinstance(value, int): - yield str(value) + yield str(int(value)) elif isinstance(value, float): yield _floatstr(value) else: if isinstance(value, (list, tuple)): chunks = _iterencode_list(value, _current_indent_level) elif isinstance(value, dict): chunks = _iterencode_dict(value, _current_indent_level) else: chunks = _iterencode(value, _current_indent_level) yield from chunks @@ -395,21 +395,21 @@ def _make_iterencode(markers, _default, def _iterencode(o, _current_indent_level): if isinstance(o, str): yield _encoder(o) elif o is None: yield 'null' elif o is True: yield 'true' elif o is False: yield 'false' elif isinstance(o, int): - yield str(o) + yield str(int(o)) elif isinstance(o, float): yield _floatstr(o) elif isinstance(o, (list, tuple)): yield from _iterencode_list(o, _current_indent_level) elif isinstance(o, dict): yield from _iterencode_dict(o, _current_indent_level) else: if markers is not None: markerid = id(o) if markerid in markers: diff -r 2b3b873e2b19 Lib/test/json_tests/test_enum.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/test/json_tests/test_enum.py Sat Aug 03 11:55:25 2013 -0700 @@ -0,0 +1,41 @@ +from enum import IntEnum +from test.json_tests import PyTest, CTest + + +class BigNum(IntEnum): + small = 1 + big = 1<<32 + huge = 1<<64 + really_huge = 1<<96 + + +class TestEnum: + + def test_ints(self): + for enum in BigNum: + self.assertEqual(self.dumps(enum), str(enum.value)) + self.assertEqual(int(self.dumps(enum)), enum) + self.assertEqual(self.loads(self.dumps(enum)), enum) + + def test_list(self): + self.assertEqual(self.dumps(list(BigNum)), '[1, 4294967296, 18446744073709551616, 79228162514264337593543950336]') + + def test_dict_keys(self): + s, b, h, r = BigNum + d = {s:'tiny', b:'large', h:'larger', r:'largest'} + nd = self.loads(self.dumps(d)) + self.assertEqual(nd['1'], 'tiny') + self.assertEqual(nd['4294967296'], 'large') + self.assertEqual(nd['18446744073709551616'], 'larger') + self.assertEqual(nd['79228162514264337593543950336'], 'largest') + + def test_dict_values(self): + d = dict(tiny=BigNum.small, large=BigNum.big, larger=BigNum.huge, largest=BigNum.really_huge) + nd = self.loads(self.dumps(d)) + self.assertEqual(nd['tiny'], 1) + self.assertEqual(nd['large'], 4294967296) + self.assertEqual(nd['larger'], 18446744073709551616) + self.assertEqual(nd['largest'], 79228162514264337593543950336) + +class TestPyEnum(TestEnum, PyTest): pass +class TestCEnum(TestEnum, CTest): pass diff -r 2b3b873e2b19 Modules/_json.c --- a/Modules/_json.c Tue Jul 30 12:24:25 2013 -0700 +++ b/Modules/_json.c Sat Aug 03 11:55:25 2013 -0700 @@ -1359,23 +1359,29 @@ encoder_listencode_obj(PyEncoderObject * return _steal_accumulate(acc, cstr); } else if (PyUnicode_Check(obj)) { PyObject *encoded = encoder_encode_string(s, obj); if (encoded == NULL) return -1; return _steal_accumulate(acc, encoded); } else if (PyLong_Check(obj)) { - PyObject *encoded = PyObject_Str(obj); - if (encoded == NULL) + PyObject *encoded; + PyObject *longobj = PyNumber_Long(obj); + if (longobj == NULL) + return -1; + encoded = PyObject_Str(longobj); + if (encoded == NULL) { + Py_DECREF(longobj); return -1; + } return _steal_accumulate(acc, encoded); } else if (PyFloat_Check(obj)) { PyObject *encoded = encoder_encode_float(s, obj); if (encoded == NULL) return -1; return _steal_accumulate(acc, encoded); } else if (PyList_Check(obj) || PyTuple_Check(obj)) { if (Py_EnterRecursiveCall(" while encoding a JSON object")) @@ -1544,23 +1550,28 @@ encoder_listencode_dict(PyEncoderObject goto bail; } else if (key == Py_True || key == Py_False || key == Py_None) { /* This must come before the PyLong_Check because True and False are also 1 and 0.*/ kstr = _encoded_const(key); if (kstr == NULL) goto bail; } else if (PyLong_Check(key)) { - kstr = PyObject_Str(key); - if (kstr == NULL) + PyObject *longobj = PyNumber_Long(key); + if (longobj == NULL) + goto bail; + kstr = PyObject_Str(longobj); + if (kstr == NULL) { + Py_DECREF(longobj); goto bail; + } } else if (skipkeys) { Py_DECREF(item); continue; } else { /* TODO: include repr of key */ PyErr_SetString(PyExc_TypeError, "keys must be a string"); goto bail; }