From 6b89292e5e7275c02c53bae97785cdbed5d24354 Mon Sep 17 00:00:00 2001 From: Mike Krieger Date: Tue, 3 Jan 2012 16:33:34 -0800 Subject: [PATCH] Allow a kwarg to be passed in specifying the double precision --- python/objToJSON.c | 19 ++++++++++--------- python/tests.py | 35 ++++++++++++++++++++++++++++++++--- python/ujson.c | 2 +- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/python/objToJSON.c b/python/objToJSON.c index a45b91a..7af0c7f 100644 --- a/python/objToJSON.c +++ b/python/objToJSON.c @@ -681,14 +681,22 @@ char *Object_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen) PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = { "obj", "ensure_ascii", NULL}; + static char *kwlist[] = { "obj", "ensure_ascii", "double_precision", NULL}; char buffer[65536]; char *ret; PyObject *newobj; PyObject *oinput = NULL; PyObject *oensureAscii = NULL; + int idoublePrecision = 5; // default double precision setting + PRINTMARK(); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi", kwlist, &oinput, &oensureAscii, &idoublePrecision)) + { + return NULL; + } + JSONObjectEncoder encoder = { Object_beginTypeContext, //void (*beginTypeContext)(JSOBJ obj, JSONTypeContext *tc); @@ -707,17 +715,10 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs) PyObject_Realloc, //JSPFN_REALLOC realloc; PyObject_Free, //JSPFN_FREE free; -1, //recursionMax - 5, //default decimal precision + idoublePrecision, 1, //forceAscii }; - PRINTMARK(); - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, &oinput, &oensureAscii)) - { - return NULL; - } - if (oensureAscii != NULL && !PyObject_IsTrue(oensureAscii)) { encoder.forceASCII = 0; diff --git a/python/tests.py b/python/tests.py index 4eafa2f..caabee6 100644 --- a/python/tests.py +++ b/python/tests.py @@ -29,7 +29,6 @@ class UltraJSONTests(TestCase): output = ujson.encode(input) self.assertEquals(round(input, 5), round(json.loads(output), 5)) self.assertEquals(round(input, 5), round(ujson.decode(output), 5)) - pass def test_encodeWithDecimal(self): input = 1.0 @@ -41,7 +40,6 @@ class UltraJSONTests(TestCase): output = ujson.encode(input) self.assertEquals(round(input, 5), round(json.loads(output), 5)) self.assertEquals(round(input, 5), round(ujson.decode(output), 5)) - pass def test_encodeArrayOfNestedArrays(self): input = [[[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]] ] @@ -56,7 +54,39 @@ class UltraJSONTests(TestCase): self.assertEquals(input, json.loads(output)) #self.assertEquals(output, json.dumps(input)) self.assertEquals(input, ujson.decode(output)) + + def test_doublePrecisionTest(self): + input = 30.012345678 + output = ujson.encode(input, double_precision = 9) + self.assertEquals(input, json.loads(output)) + self.assertEquals(input, ujson.decode(output)) + output = ujson.encode(input, double_precision = 3) + self.assertEquals(round(input, 3), json.loads(output)) + self.assertEquals(round(input, 3), ujson.decode(output)) + + output = ujson.encode(input) + self.assertEquals(round(input, 5), json.loads(output)) + self.assertEquals(round(input, 5), ujson.decode(output)) + + def test_invalidDoublePrecision(self): + input = 30.12345678901234567890 + output = ujson.encode(input, double_precision = 20) + # should snap to the max, which is 9 + self.assertEquals(round(input, 9), json.loads(output)) + self.assertEquals(round(input, 9), ujson.decode(output)) + + output = ujson.encode(input, double_precision = -1) + # also should snap to the max, which is 9 + self.assertEquals(round(input, 9), json.loads(output)) + self.assertEquals(round(input, 9), ujson.decode(output)) + + # will throw typeError + self.assertRaises(TypeError, ujson.encode, input, double_precision = '9') + # will throw typeError + self.assertRaises(TypeError, ujson.encode, input, double_precision = None) + + def test_encodeStringConversion(self): input = "A string \\ / \b \f \n \r \t" output = ujson.encode(input) @@ -676,4 +706,3 @@ if __name__ == '__main__': unittest.main() heap = hp.heapu() print heap - \ No newline at end of file diff --git a/python/ujson.c b/python/ujson.c index e3d8827..eb1d0bb 100644 --- a/python/ujson.c +++ b/python/ujson.c @@ -16,7 +16,7 @@ PyObject* JSONFileToObj(PyObject* self, PyObject *file); static PyMethodDef ujsonMethods[] = { - {"encode", objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursivly into JSON. Use ensure_ascii=false to output UTF-8"}, + {"encode", objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursivly into JSON. Use ensure_ascii=false to output UTF-8. Pass in double_precision to alter the maximum digit precision with doubles"}, {"decode", JSONToObj, METH_O, "Converts JSON as string to dict object structure"}, {"dumps", objToJSON, METH_VARARGS | METH_KEYWORDS, "Converts arbitrary object recursivly into JSON. Use ensure_ascii=false to output UTF-8"}, {"loads", JSONToObj, METH_O, "Converts JSON as string to dict object structure"},