[Python-checkins] r72963 - in python/branches/py3k: Lib/json/encoder.py Lib/json/tests/test_encode_basestring_ascii.py Modules/_json.c
raymond.hettinger
python-checkins at python.org
Wed May 27 11:58:36 CEST 2009
Author: raymond.hettinger
Date: Wed May 27 11:58:34 2009
New Revision: 72963
Log:
* Fix-up a TODO (support the sort_key option).
* Fix an error where True/False were being written-out
as title-cased strings when used a dictionary keys.
* Speed-up iteration over dicts by looping over items()
rather than keys() followed by value lookups.
* TODO: sort only by keys, not keys and values.
Modified:
python/branches/py3k/Lib/json/encoder.py
python/branches/py3k/Lib/json/tests/test_encode_basestring_ascii.py
python/branches/py3k/Modules/_json.c
Modified: python/branches/py3k/Lib/json/encoder.py
==============================================================================
--- python/branches/py3k/Lib/json/encoder.py (original)
+++ python/branches/py3k/Lib/json/encoder.py Wed May 27 11:58:34 2009
@@ -233,7 +233,7 @@
if (_one_shot and c_make_encoder is not None
- and not self.indent and not self.sort_keys):
+ and not self.indent):
_iterencode = c_make_encoder(
markers, self.default, _encoder, self.indent,
self.key_separator, self.item_separator, self.sort_keys,
Modified: python/branches/py3k/Lib/json/tests/test_encode_basestring_ascii.py
==============================================================================
--- python/branches/py3k/Lib/json/tests/test_encode_basestring_ascii.py (original)
+++ python/branches/py3k/Lib/json/tests/test_encode_basestring_ascii.py Wed May 27 11:58:34 2009
@@ -43,3 +43,8 @@
items = [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]
s = json.dumps(OrderedDict(items))
self.assertEqual(s, '{"one": 1, "two": 2, "three": 3, "four": 4, "five": 5}')
+
+ def test_sorted_dict(self):
+ items = [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]
+ s = json.dumps(dict(items), sort_keys=True)
+ self.assertEqual(s, '{"five": 5, "four": 4, "one": 1, "three": 3, "two": 2}')
Modified: python/branches/py3k/Modules/_json.c
==============================================================================
--- python/branches/py3k/Modules/_json.c (original)
+++ python/branches/py3k/Modules/_json.c Wed May 27 11:58:34 2009
@@ -1334,9 +1334,9 @@
static PyObject *empty_dict = NULL;
PyObject *kstr = NULL;
PyObject *ident = NULL;
- PyObject *key = NULL;
- PyObject *value = NULL;
PyObject *it = NULL;
+ PyObject *items;
+ PyObject *item = NULL;
int skipkeys;
Py_ssize_t idx;
@@ -1379,16 +1379,38 @@
*/
}
- /* TODO: C speedup not implemented for sort_keys */
+ items = PyObject_CallMethod(dct, "items", ""); /* XXX key=itemgetter(0) */
+ if (items == NULL)
+ goto bail;
+ if (PyObject_IsTrue(s->sort_keys)) {
+ PyObject *rv;
+ PyObject *itemlist;
+
+ itemlist = PySequence_List(items);
+ Py_DECREF(items);
+ if (itemlist == NULL)
+ goto bail;
- it = PyObject_GetIter(dct);
- if (it == NULL)
+ rv = PyObject_CallMethod(itemlist, "sort", "");
+ if (rv == NULL) {
+ Py_DECREF(itemlist);
+ goto bail;
+ }
+ items = itemlist;
+ }
+ it = PyObject_GetIter(items);
+ Py_DECREF(items);
+ if (it == NULL)
goto bail;
skipkeys = PyObject_IsTrue(s->skipkeys);
idx = 0;
- while ((key = PyIter_Next(it)) != NULL) {
- PyObject *encoded;
-
+ while ((item = PyIter_Next(it)) != NULL) {
+ PyObject *encoded, *key, *value;
+ if (!PyTuple_Check(item) || Py_SIZE(item) != 2) {
+ PyErr_SetString(PyExc_ValueError, "items must return 2-tuples");
+ goto bail;
+ }
+ key = PyTuple_GET_ITEM(item, 0);
if (PyUnicode_Check(key)) {
Py_INCREF(key);
kstr = key;
@@ -1398,18 +1420,20 @@
if (kstr == NULL)
goto bail;
}
- else if (PyLong_Check(key)) {
- kstr = PyObject_Str(key);
+ else if (key == Py_True || key == Py_False || key == Py_None) {
+ /* This must come before the PyLong_Check because
+ True and False are also 1 and 0.*/
+ kstr = _encoded_const(key);
if (kstr == NULL)
goto bail;
}
- else if (key == Py_True || key == Py_False || key == Py_None) {
- kstr = _encoded_const(key);
+ else if (PyLong_Check(key)) {
+ kstr = PyObject_Str(key);
if (kstr == NULL)
goto bail;
}
else if (skipkeys) {
- Py_DECREF(key);
+ Py_DECREF(item);
continue;
}
else {
@@ -1435,14 +1459,11 @@
if (PyList_Append(rval, s->key_separator))
goto bail;
- value = PyObject_GetItem(dct, key);
- if (value == NULL)
- goto bail;
+ value = PyTuple_GET_ITEM(item, 1);
if (encoder_listencode_obj(s, rval, value, indent_level))
goto bail;
idx += 1;
- Py_CLEAR(value);
- Py_DECREF(key);
+ Py_DECREF(item);
}
if (PyErr_Occurred())
goto bail;
@@ -1466,8 +1487,7 @@
bail:
Py_XDECREF(it);
- Py_XDECREF(key);
- Py_XDECREF(value);
+ Py_XDECREF(item);
Py_XDECREF(kstr);
Py_XDECREF(ident);
return -1;
More information about the Python-checkins
mailing list