1212#include "Python.h"
1313#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
1414#include "structmember.h" // PyMemberDef
15+ #include <stdbool.h> // bool
1516
1617
1718typedef struct _PyScannerObject {
@@ -1491,17 +1492,79 @@ encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer,
14911492 }
14921493}
14931494
1495+ static int
1496+ encoder_encode_key_value (PyEncoderObject * s , _PyUnicodeWriter * writer , bool * first ,
1497+ PyObject * key , PyObject * value , Py_ssize_t indent_level )
1498+ {
1499+ PyObject * keystr = NULL ;
1500+ PyObject * encoded ;
1501+
1502+ if (PyUnicode_Check (key )) {
1503+ Py_INCREF (key );
1504+ keystr = key ;
1505+ }
1506+ else if (PyFloat_Check (key )) {
1507+ keystr = encoder_encode_float (s , key );
1508+ }
1509+ else if (key == Py_True || key == Py_False || key == Py_None ) {
1510+ /* This must come before the PyLong_Check because
1511+ True and False are also 1 and 0.*/
1512+ keystr = _encoded_const (key );
1513+ }
1514+ else if (PyLong_Check (key )) {
1515+ keystr = PyLong_Type .tp_repr (key );
1516+ }
1517+ else if (s -> skipkeys ) {
1518+ return 0 ;
1519+ }
1520+ else {
1521+ PyErr_Format (PyExc_TypeError ,
1522+ "keys must be str, int, float, bool or None, "
1523+ "not %.100s" , Py_TYPE (key )-> tp_name );
1524+ return -1 ;
1525+ }
1526+
1527+ if (keystr == NULL ) {
1528+ return -1 ;
1529+ }
1530+
1531+ if (* first ) {
1532+ * first = false;
1533+ }
1534+ else {
1535+ if (_PyUnicodeWriter_WriteStr (writer , s -> item_separator ) < 0 ) {
1536+ Py_DECREF (keystr );
1537+ return -1 ;
1538+ }
1539+ }
1540+
1541+ encoded = encoder_encode_string (s , keystr );
1542+ Py_DECREF (keystr );
1543+ if (encoded == NULL ) {
1544+ return -1 ;
1545+ }
1546+
1547+ if (_steal_accumulate (writer , encoded ) < 0 ) {
1548+ return -1 ;
1549+ }
1550+ if (_PyUnicodeWriter_WriteStr (writer , s -> key_separator ) < 0 ) {
1551+ return -1 ;
1552+ }
1553+ if (encoder_listencode_obj (s , writer , value , indent_level ) < 0 ) {
1554+ return -1 ;
1555+ }
1556+ return 0 ;
1557+ }
1558+
14941559static int
14951560encoder_listencode_dict (PyEncoderObject * s , _PyUnicodeWriter * writer ,
14961561 PyObject * dct , Py_ssize_t indent_level )
14971562{
14981563 /* Encode Python dict dct a JSON term */
1499- PyObject * kstr = NULL ;
15001564 PyObject * ident = NULL ;
1501- PyObject * it = NULL ;
1502- PyObject * items ;
1503- PyObject * item = NULL ;
1504- Py_ssize_t idx ;
1565+ PyObject * items = NULL ;
1566+ PyObject * key , * value ;
1567+ bool first = true;
15051568
15061569 if (PyDict_GET_SIZE (dct ) == 0 ) /* Fast path */
15071570 return _PyUnicodeWriter_WriteASCIIString (writer , "{}" , 2 );
@@ -1535,84 +1598,34 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer,
15351598 */
15361599 }
15371600
1538- items = PyMapping_Items (dct );
1539- if (items == NULL )
1540- goto bail ;
1541- if (s -> sort_keys && PyList_Sort (items ) < 0 ) {
1542- Py_DECREF (items );
1543- goto bail ;
1544- }
1545- it = PyObject_GetIter (items );
1546- Py_DECREF (items );
1547- if (it == NULL )
1548- goto bail ;
1549- idx = 0 ;
1550- while ((item = PyIter_Next (it )) != NULL ) {
1551- PyObject * encoded , * key , * value ;
1552- if (!PyTuple_Check (item ) || PyTuple_GET_SIZE (item ) != 2 ) {
1553- PyErr_SetString (PyExc_ValueError , "items must return 2-tuples" );
1601+ if (s -> sort_keys ) {
1602+
1603+ items = PyDict_Items (dct );
1604+ if (items == NULL || PyList_Sort (items ) < 0 )
15541605 goto bail ;
1555- }
1556- key = PyTuple_GET_ITEM (item , 0 );
1557- if (PyUnicode_Check (key )) {
1558- Py_INCREF (key );
1559- kstr = key ;
1560- }
1561- else if (PyFloat_Check (key )) {
1562- kstr = encoder_encode_float (s , key );
1563- if (kstr == NULL )
1564- goto bail ;
1565- }
1566- else if (key == Py_True || key == Py_False || key == Py_None ) {
1567- /* This must come before the PyLong_Check because
1568- True and False are also 1 and 0.*/
1569- kstr = _encoded_const (key );
1570- if (kstr == NULL )
1571- goto bail ;
1572- }
1573- else if (PyLong_Check (key )) {
1574- kstr = PyLong_Type .tp_repr (key );
1575- if (kstr == NULL ) {
1606+
1607+ for (Py_ssize_t i = 0 ; i < PyList_GET_SIZE (items ); i ++ ) {
1608+ PyObject * item = PyList_GET_ITEM (items , i );
1609+
1610+ if (!PyTuple_Check (item ) || PyTuple_GET_SIZE (item ) != 2 ) {
1611+ PyErr_SetString (PyExc_ValueError , "items must return 2-tuples" );
15761612 goto bail ;
15771613 }
1578- }
1579- else if (s -> skipkeys ) {
1580- Py_DECREF (item );
1581- continue ;
1582- }
1583- else {
1584- PyErr_Format (PyExc_TypeError ,
1585- "keys must be str, int, float, bool or None, "
1586- "not %.100s" , Py_TYPE (key )-> tp_name );
1587- goto bail ;
1588- }
15891614
1590- if (idx ) {
1591- if (_PyUnicodeWriter_WriteStr (writer , s -> item_separator ))
1615+ key = PyTuple_GET_ITEM (item , 0 );
1616+ value = PyTuple_GET_ITEM (item , 1 );
1617+ if (encoder_encode_key_value (s , writer , & first , key , value , indent_level ) < 0 )
15921618 goto bail ;
15931619 }
1620+ Py_CLEAR (items );
15941621
1595- encoded = encoder_encode_string (s , kstr );
1596- Py_CLEAR (kstr );
1597- if (encoded == NULL )
1598- goto bail ;
1599- if (_PyUnicodeWriter_WriteStr (writer , encoded )) {
1600- Py_DECREF (encoded );
1601- goto bail ;
1622+ } else {
1623+ Py_ssize_t pos = 0 ;
1624+ while (PyDict_Next (dct , & pos , & key , & value )) {
1625+ if (encoder_encode_key_value (s , writer , & first , key , value , indent_level ) < 0 )
1626+ goto bail ;
16021627 }
1603- Py_DECREF (encoded );
1604- if (_PyUnicodeWriter_WriteStr (writer , s -> key_separator ))
1605- goto bail ;
1606-
1607- value = PyTuple_GET_ITEM (item , 1 );
1608- if (encoder_listencode_obj (s , writer , value , indent_level ))
1609- goto bail ;
1610- idx += 1 ;
1611- Py_DECREF (item );
16121628 }
1613- if (PyErr_Occurred ())
1614- goto bail ;
1615- Py_CLEAR (it );
16161629
16171630 if (ident != NULL ) {
16181631 if (PyDict_DelItem (s -> markers , ident ))
@@ -1630,14 +1643,11 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer,
16301643 return 0 ;
16311644
16321645bail :
1633- Py_XDECREF (it );
1634- Py_XDECREF (item );
1635- Py_XDECREF (kstr );
1646+ Py_XDECREF (items );
16361647 Py_XDECREF (ident );
16371648 return -1 ;
16381649}
16391650
1640-
16411651static int
16421652encoder_listencode_list (PyEncoderObject * s , _PyUnicodeWriter * writer ,
16431653 PyObject * seq , Py_ssize_t indent_level )
0 commit comments