12
12
#include "Python.h"
13
13
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
14
14
#include "structmember.h" // PyMemberDef
15
+ #include <stdbool.h> // bool
15
16
16
17
17
18
typedef struct _PyScannerObject {
@@ -1491,17 +1492,79 @@ encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer,
1491
1492
}
1492
1493
}
1493
1494
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
+
1494
1559
static int
1495
1560
encoder_listencode_dict (PyEncoderObject * s , _PyUnicodeWriter * writer ,
1496
1561
PyObject * dct , Py_ssize_t indent_level )
1497
1562
{
1498
1563
/* Encode Python dict dct a JSON term */
1499
- PyObject * kstr = NULL ;
1500
1564
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;
1505
1568
1506
1569
if (PyDict_GET_SIZE (dct ) == 0 ) /* Fast path */
1507
1570
return _PyUnicodeWriter_WriteASCIIString (writer , "{}" , 2 );
@@ -1535,84 +1598,34 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer,
1535
1598
*/
1536
1599
}
1537
1600
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 )
1554
1605
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" );
1576
1612
goto bail ;
1577
1613
}
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
- }
1589
1614
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 )
1592
1618
goto bail ;
1593
1619
}
1620
+ Py_CLEAR (items );
1594
1621
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 ;
1602
1627
}
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 );
1612
1628
}
1613
- if (PyErr_Occurred ())
1614
- goto bail ;
1615
- Py_CLEAR (it );
1616
1629
1617
1630
if (ident != NULL ) {
1618
1631
if (PyDict_DelItem (s -> markers , ident ))
@@ -1630,14 +1643,11 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer,
1630
1643
return 0 ;
1631
1644
1632
1645
bail :
1633
- Py_XDECREF (it );
1634
- Py_XDECREF (item );
1635
- Py_XDECREF (kstr );
1646
+ Py_XDECREF (items );
1636
1647
Py_XDECREF (ident );
1637
1648
return -1 ;
1638
1649
}
1639
1650
1640
-
1641
1651
static int
1642
1652
encoder_listencode_list (PyEncoderObject * s , _PyUnicodeWriter * writer ,
1643
1653
PyObject * seq , Py_ssize_t indent_level )
0 commit comments