summaryrefslogtreecommitdiff
blob: 37270d41e3b101670757ac581f1f01bd9788b144 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
commit c9f8318bd823ae9d44797b6b881a2b3e22cdbade
Author: Joakim Hamren <joakim.hamren@gmail.com>
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.