diff options
-rw-r--r-- | CHANGES.txt | 2 | ||||
-rw-r--r-- | simplejson/_speedups.c | 5 | ||||
-rw-r--r-- | simplejson/encoder.py | 4 | ||||
-rw-r--r-- | simplejson/tests/test_decimal.py | 21 | ||||
-rw-r--r-- | simplejson/tests/test_dump.py | 25 | ||||
-rw-r--r-- | simplejson/tests/test_float.py | 8 |
6 files changed, 55 insertions, 10 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index a47102b..7992db3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,6 +5,8 @@ Version 3.0.0 released 201X-XX-XX key, rather than the original object. This ensures that the sort only compares string types and makes the behavior consistent between Python 2.x and Python 3.x. +* Like other number types, Decimal instances used as keys are now + coerced to strings when use_decimal is True. Version 2.6.2 released 2012-09-21 diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c index 74fa831..5fbecf2 100644 --- a/simplejson/_speedups.c +++ b/simplejson/_speedups.c @@ -2739,6 +2739,11 @@ encoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ss if (kstr == NULL) goto bail; } + else if (s->use_decimal && PyObject_TypeCheck(key, (PyTypeObject *)s->Decimal)) { + kstr = PyObject_Str(key); + if (kstr == NULL) + goto bail; + } else if (skipkeys) { Py_DECREF(item); continue; diff --git a/simplejson/encoder.py b/simplejson/encoder.py index dad59fc..385c19a 100644 --- a/simplejson/encoder.py +++ b/simplejson/encoder.py @@ -440,7 +440,7 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, del markers[markerid] def _stringify_key(key): - if isinstance(key, string_types): + if isinstance(key, string_types): # pragma: no cover pass elif isinstance(key, binary_type): key = key.decode(_encoding) @@ -454,6 +454,8 @@ def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, key = 'null' elif isinstance(key, integer_types): key = str(key) + elif _use_decimal and isinstance(key, Decimal): + key = str(key) elif _skipkeys: key = None else: diff --git a/simplejson/tests/test_decimal.py b/simplejson/tests/test_decimal.py index 8d76f4e..ed1dada 100644 --- a/simplejson/tests/test_decimal.py +++ b/simplejson/tests/test_decimal.py @@ -28,18 +28,23 @@ class TestDecimal(TestCase): for s in self.NUMS: self.assertEquals(self.loads(s, parse_float=Decimal), Decimal(s)) + def test_stringify_key(self): + for d in map(Decimal, self.NUMS): + v = {d: d} + self.assertEquals( + self.loads( + self.dumps(v, use_decimal=True), parse_float=Decimal), + {str(d): d}) + def test_decimal_roundtrip(self): for d in map(Decimal, self.NUMS): # The type might not be the same (int and Decimal) but they # should still compare equal. - self.assertEquals( - self.loads( - self.dumps(d, use_decimal=True), parse_float=Decimal), - d) - self.assertEquals( - self.loads( - self.dumps([d], use_decimal=True), parse_float=Decimal), - [d]) + for v in [d, [d], {'': d}]: + self.assertEquals( + self.loads( + self.dumps(v, use_decimal=True), parse_float=Decimal), + v) def test_decimal_defaults(self): d = Decimal('1.1') diff --git a/simplejson/tests/test_dump.py b/simplejson/tests/test_dump.py index 9f1e826..04cfc67 100644 --- a/simplejson/tests/test_dump.py +++ b/simplejson/tests/test_dump.py @@ -1,5 +1,5 @@ from unittest import TestCase -from simplejson.compat import StringIO, long_type +from simplejson.compat import StringIO, long_type, b import simplejson as json class TestDump(TestCase): @@ -8,6 +8,29 @@ class TestDump(TestCase): json.dump({}, sio) self.assertEquals(sio.getvalue(), '{}') + def test_constants(self): + for c in [None, True, False]: + self.assert_(json.loads(json.dumps(c)) is c) + self.assert_(json.loads(json.dumps([c]))[0] is c) + self.assert_(json.loads(json.dumps({'a': c}))['a'] is c) + + def test_stringify_key(self): + items = [(b('bytes'), 'bytes'), + (1.0, '1.0'), + (10, '10'), + (True, 'true'), + (False, 'false'), + (None, 'null'), + (long_type(100), '100')] + for k, expect in items: + self.assertEquals( + json.loads(json.dumps({k: expect})), + {expect: expect}) + self.assertRaises(TypeError, json.dumps, {json: 1}) + self.assertEquals( + json.loads(json.dumps({json: 1}, skipkeys=True)), + {}) + def test_dumps(self): self.assertEquals(json.dumps({}), '{}') diff --git a/simplejson/tests/test_float.py b/simplejson/tests/test_float.py index f7e29d6..5d50223 100644 --- a/simplejson/tests/test_float.py +++ b/simplejson/tests/test_float.py @@ -2,8 +2,16 @@ import math from unittest import TestCase from simplejson.compat import long_type, text_type import simplejson as json +from simplejson.decoder import NaN, PosInf, NegInf class TestFloat(TestCase): + def test_degenerates(self): + for inf in (PosInf, NegInf): + self.assertEquals(json.loads(json.dumps(inf)), inf) + # Python 2.5 doesn't have math.isnan + nan = json.loads(json.dumps(NaN)) + self.assert_((0 + nan) != nan) + def test_floats(self): for num in [1617161771.7650001, math.pi, math.pi**100, math.pi**-100, 3.1]: |