summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Ippolito <bob@redivi.com>2012-12-29 12:41:55 -0800
committerBob Ippolito <bob@redivi.com>2012-12-29 12:41:55 -0800
commit16ae2381fc14d4e91fa3af5d82e01eda6929572e (patch)
tree4e5c2554bc5083a1a107e706050e99121e35a759
parent83a493db6a8b859ec7b10fa85365dd3fdf144c68 (diff)
downloadsimplejson-16ae2381fc14d4e91fa3af5d82e01eda6929572e.tar.gz
more coverage, decimal key coercion
-rw-r--r--CHANGES.txt2
-rw-r--r--simplejson/_speedups.c5
-rw-r--r--simplejson/encoder.py4
-rw-r--r--simplejson/tests/test_decimal.py21
-rw-r--r--simplejson/tests/test_dump.py25
-rw-r--r--simplejson/tests/test_float.py8
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]: