commit c9f8318bd823ae9d44797b6b881a2b3e22cdbade Author: Joakim Hamren Date: Tue Feb 7 02:02:38 2017 +0100 Fix for incorrect order when using OrderedDict diff --git a/python/objToJSON.c b/python/objToJSON.c index abe6588..9e6a390 100644 --- a/python/objToJSON.c +++ b/python/objToJSON.c @@ -253,8 +253,13 @@ static int Dict_iterNext(JSOBJ obj, JSONTypeContext *tc) GET_TC(tc)->itemName = NULL; } + if (!(GET_TC(tc)->itemName = PyIter_Next(GET_TC(tc)->iterator))) + { + PRINTMARK(); + return 0; + } - if (!PyDict_Next ( (PyObject *)GET_TC(tc)->dictObj, &GET_TC(tc)->index, &GET_TC(tc)->itemName, &GET_TC(tc)->itemValue)) + if (!(GET_TC(tc)->itemValue = PyObject_GetItem(GET_TC(tc)->dictObj, GET_TC(tc)->itemName))) { PRINTMARK(); return 0; @@ -295,6 +300,7 @@ static void Dict_iterEnd(JSOBJ obj, JSONTypeContext *tc) Py_DECREF(GET_TC(tc)->itemName); GET_TC(tc)->itemName = NULL; } + Py_CLEAR(GET_TC(tc)->iterator); Py_DECREF(GET_TC(tc)->dictObj); PRINTMARK(); } @@ -425,20 +431,23 @@ static char *SortedDict_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outL static void SetupDictIter(PyObject *dictObj, TypeContext *pc, JSONObjectEncoder *enc) { - if (enc->sortKeys) { + pc->dictObj = dictObj; + if (enc->sortKeys) + { pc->iterEnd = SortedDict_iterEnd; pc->iterNext = SortedDict_iterNext; pc->iterGetValue = SortedDict_iterGetValue; pc->iterGetName = SortedDict_iterGetName; + pc->index = 0; } - else { + else + { pc->iterEnd = Dict_iterEnd; pc->iterNext = Dict_iterNext; pc->iterGetValue = Dict_iterGetValue; pc->iterGetName = Dict_iterGetName; + pc->iterator = PyObject_GetIter(dictObj); } - pc->dictObj = dictObj; - pc->index = 0; } static void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc, JSONObjectEncoder *enc) @@ -446,7 +455,8 @@ static void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc, JSONObject PyObject *obj, *objRepr, *exc; TypeContext *pc; PRINTMARK(); - if (!_obj) { + if (!_obj) + { tc->type = JT_INVALID; return; } diff --git a/tests/tests.py b/tests/tests.py index cd928e6..b7e46af 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -10,6 +10,8 @@ import json import math import time import pytz +from collections import OrderedDict + if six.PY2: import unittest2 as unittest else: @@ -383,6 +385,10 @@ class UltraJSONTests(unittest.TestCase): input = -float('inf') self.assertRaises(OverflowError, ujson.encode, input) + def test_encodeOrderedDict(self): + input = OrderedDict([(1, 1), (0, 0), (8, 8), (2, 2)]) + self.assertEqual('{"1":1,"0":0,"8":8,"2":2}', ujson.encode(input)) + def test_decodeJibberish(self): input = "fdsa sda v9sa fdsa" self.assertRaises(ValueError, ujson.decode, input) @@ -668,7 +674,7 @@ class UltraJSONTests(unittest.TestCase): d = {u'key': JSONTest()} output = ujson.encode(d) dec = ujson.decode(output) - self.assertEquals(dec, {u'key': output_text}) + self.assertEqual(dec, {u'key': output_text}) def test_object_with_json_unicode(self): # If __json__ returns a string, then that string @@ -681,7 +687,7 @@ class UltraJSONTests(unittest.TestCase): d = {u'key': JSONTest()} output = ujson.encode(d) dec = ujson.decode(output) - self.assertEquals(dec, {u'key': output_text}) + self.assertEqual(dec, {u'key': output_text}) def test_object_with_complex_json(self): # If __json__ returns a string, then that string @@ -694,7 +700,7 @@ class UltraJSONTests(unittest.TestCase): d = {u'key': JSONTest()} output = ujson.encode(d) dec = ujson.decode(output) - self.assertEquals(dec, {u'key': obj}) + self.assertEqual(dec, {u'key': obj}) def test_object_with_json_type_error(self): # __json__ must return a string, otherwise it should raise an error.