@@ -1334,9 +1334,9 @@ encoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ss
13341334 static PyObject * empty_dict = NULL ;
13351335 PyObject * kstr = NULL ;
13361336 PyObject * ident = NULL ;
1337- PyObject * key = NULL ;
1338- PyObject * value = NULL ;
13391337 PyObject * it = NULL ;
1338+ PyObject * items ;
1339+ PyObject * item = NULL ;
13401340 int skipkeys ;
13411341 Py_ssize_t idx ;
13421342
@@ -1379,16 +1379,38 @@ encoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ss
13791379 */
13801380 }
13811381
1382- /* TODO: C speedup not implemented for sort_keys */
1382+ items = PyObject_CallMethod (dct , "items" , "" ); /* XXX key=itemgetter(0) */
1383+ if (items == NULL )
1384+ goto bail ;
1385+ if (PyObject_IsTrue (s -> sort_keys )) {
1386+ PyObject * rv ;
1387+ PyObject * itemlist ;
1388+
1389+ itemlist = PySequence_List (items );
1390+ Py_DECREF (items );
1391+ if (itemlist == NULL )
1392+ goto bail ;
13831393
1384- it = PyObject_GetIter (dct );
1385- if (it == NULL )
1394+ rv = PyObject_CallMethod (itemlist , "sort" , "" );
1395+ if (rv == NULL ) {
1396+ Py_DECREF (itemlist );
1397+ goto bail ;
1398+ }
1399+ items = itemlist ;
1400+ }
1401+ it = PyObject_GetIter (items );
1402+ Py_DECREF (items );
1403+ if (it == NULL )
13861404 goto bail ;
13871405 skipkeys = PyObject_IsTrue (s -> skipkeys );
13881406 idx = 0 ;
1389- while ((key = PyIter_Next (it )) != NULL ) {
1390- PyObject * encoded ;
1391-
1407+ while ((item = PyIter_Next (it )) != NULL ) {
1408+ PyObject * encoded , * key , * value ;
1409+ if (!PyTuple_Check (item ) || Py_SIZE (item ) != 2 ) {
1410+ PyErr_SetString (PyExc_ValueError , "items must return 2-tuples" );
1411+ goto bail ;
1412+ }
1413+ key = PyTuple_GET_ITEM (item , 0 );
13921414 if (PyUnicode_Check (key )) {
13931415 Py_INCREF (key );
13941416 kstr = key ;
@@ -1398,18 +1420,20 @@ encoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ss
13981420 if (kstr == NULL )
13991421 goto bail ;
14001422 }
1401- else if (PyLong_Check (key )) {
1402- kstr = PyObject_Str (key );
1423+ else if (key == Py_True || key == Py_False || key == Py_None ) {
1424+ /* This must come before the PyLong_Check because
1425+ True and False are also 1 and 0.*/
1426+ kstr = _encoded_const (key );
14031427 if (kstr == NULL )
14041428 goto bail ;
14051429 }
1406- else if (key == Py_True || key == Py_False || key == Py_None ) {
1407- kstr = _encoded_const (key );
1430+ else if (PyLong_Check ( key ) ) {
1431+ kstr = PyObject_Str (key );
14081432 if (kstr == NULL )
14091433 goto bail ;
14101434 }
14111435 else if (skipkeys ) {
1412- Py_DECREF (key );
1436+ Py_DECREF (item );
14131437 continue ;
14141438 }
14151439 else {
@@ -1435,14 +1459,11 @@ encoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ss
14351459 if (PyList_Append (rval , s -> key_separator ))
14361460 goto bail ;
14371461
1438- value = PyObject_GetItem (dct , key );
1439- if (value == NULL )
1440- goto bail ;
1462+ value = PyTuple_GET_ITEM (item , 1 );
14411463 if (encoder_listencode_obj (s , rval , value , indent_level ))
14421464 goto bail ;
14431465 idx += 1 ;
1444- Py_CLEAR (value );
1445- Py_DECREF (key );
1466+ Py_DECREF (item );
14461467 }
14471468 if (PyErr_Occurred ())
14481469 goto bail ;
@@ -1466,8 +1487,7 @@ encoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ss
14661487
14671488bail :
14681489 Py_XDECREF (it );
1469- Py_XDECREF (key );
1470- Py_XDECREF (value );
1490+ Py_XDECREF (item );
14711491 Py_XDECREF (kstr );
14721492 Py_XDECREF (ident );
14731493 return -1 ;
0 commit comments