@@ -85,11 +85,11 @@ encoder_dealloc(PyObject *self);
85
85
static int
86
86
encoder_clear (PyEncoderObject * self );
87
87
static int
88
- encoder_listencode_list (PyEncoderObject * s , _PyUnicodeWriter * writer , PyObject * seq , Py_ssize_t indent_level );
88
+ encoder_listencode_list (PyEncoderObject * s , _PyUnicodeWriter * writer , PyObject * seq , PyObject * newline_indent );
89
89
static int
90
- encoder_listencode_obj (PyEncoderObject * s , _PyUnicodeWriter * writer , PyObject * obj , Py_ssize_t indent_level );
90
+ encoder_listencode_obj (PyEncoderObject * s , _PyUnicodeWriter * writer , PyObject * obj , PyObject * newline_indent );
91
91
static int
92
- encoder_listencode_dict (PyEncoderObject * s , _PyUnicodeWriter * writer , PyObject * dct , Py_ssize_t indent_level );
92
+ encoder_listencode_dict (PyEncoderObject * s , _PyUnicodeWriter * writer , PyObject * dct , PyObject * newline_indent );
93
93
static PyObject *
94
94
_encoded_const (PyObject * obj );
95
95
static void
@@ -1251,6 +1251,17 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1251
1251
return (PyObject * )s ;
1252
1252
}
1253
1253
1254
+ static PyObject *
1255
+ _create_newline_indent (PyObject * indent , Py_ssize_t indent_level )
1256
+ {
1257
+ PyObject * newline_indent = PyUnicode_FromOrdinal ('\n' );
1258
+ if (newline_indent != NULL && indent_level ) {
1259
+ PyUnicode_AppendAndDel (& newline_indent ,
1260
+ PySequence_Repeat (indent , indent_level ));
1261
+ }
1262
+ return newline_indent ;
1263
+ }
1264
+
1254
1265
static PyObject *
1255
1266
encoder_call (PyEncoderObject * self , PyObject * args , PyObject * kwds )
1256
1267
{
@@ -1267,10 +1278,20 @@ encoder_call(PyEncoderObject *self, PyObject *args, PyObject *kwds)
1267
1278
_PyUnicodeWriter_Init (& writer );
1268
1279
writer .overallocate = 1 ;
1269
1280
1270
- if (encoder_listencode_obj (self , & writer , obj , indent_level )) {
1281
+ PyObject * newline_indent = NULL ;
1282
+ if (self -> indent != Py_None ) {
1283
+ newline_indent = _create_newline_indent (self -> indent , indent_level );
1284
+ if (newline_indent == NULL ) {
1285
+ _PyUnicodeWriter_Dealloc (& writer );
1286
+ return NULL ;
1287
+ }
1288
+ }
1289
+ if (encoder_listencode_obj (self , & writer , obj , newline_indent )) {
1271
1290
_PyUnicodeWriter_Dealloc (& writer );
1291
+ Py_XDECREF (newline_indent );
1272
1292
return NULL ;
1273
1293
}
1294
+ Py_XDECREF (newline_indent );
1274
1295
1275
1296
result = PyTuple_New (1 );
1276
1297
if (result == NULL ||
@@ -1358,7 +1379,7 @@ _steal_accumulate(_PyUnicodeWriter *writer, PyObject *stolen)
1358
1379
1359
1380
static int
1360
1381
encoder_listencode_obj (PyEncoderObject * s , _PyUnicodeWriter * writer ,
1361
- PyObject * obj , Py_ssize_t indent_level )
1382
+ PyObject * obj , PyObject * newline_indent )
1362
1383
{
1363
1384
/* Encode Python object obj to a JSON term */
1364
1385
PyObject * newobj ;
@@ -1394,14 +1415,14 @@ encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer,
1394
1415
else if (PyList_Check (obj ) || PyTuple_Check (obj )) {
1395
1416
if (_Py_EnterRecursiveCall (" while encoding a JSON object" ))
1396
1417
return -1 ;
1397
- rv = encoder_listencode_list (s , writer , obj , indent_level );
1418
+ rv = encoder_listencode_list (s , writer , obj , newline_indent );
1398
1419
_Py_LeaveRecursiveCall ();
1399
1420
return rv ;
1400
1421
}
1401
1422
else if (PyDict_Check (obj )) {
1402
1423
if (_Py_EnterRecursiveCall (" while encoding a JSON object" ))
1403
1424
return -1 ;
1404
- rv = encoder_listencode_dict (s , writer , obj , indent_level );
1425
+ rv = encoder_listencode_dict (s , writer , obj , newline_indent );
1405
1426
_Py_LeaveRecursiveCall ();
1406
1427
return rv ;
1407
1428
}
@@ -1435,7 +1456,7 @@ encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer,
1435
1456
Py_XDECREF (ident );
1436
1457
return -1 ;
1437
1458
}
1438
-
10000
rv = encoder_listencode_obj (s , writer , newobj , indent_level );
1459
+ rv = encoder_listencode_obj (s , writer , newobj , newline_indent );
1439
1460
_Py_LeaveRecursiveCall ();
1440
1461
1441
1462
Py_DECREF (newobj );
@@ -1456,7 +1477,9 @@ encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer,
1456
1477
1457
1478
static int
1458
1479
encoder_encode_key_value (PyEncoderObject * s , _PyUnicodeWriter * writer , bool * first ,
1459
- PyObject * key , PyObject * value , Py_ssize_t indent_level )
1480
+ PyObject * key , PyObject * value ,
1481
+ PyObject * newline_indent ,
1482
+ PyObject * item_separator )
1460
1483
{
1461
1484
PyObject * keystr = NULL ;
1462
1485
PyObject * encoded ;
@@ -1493,7 +1516,7 @@ encoder_encode_key_value(PyEncoderObject *s, _PyUnicodeWriter *writer, bool *fir
1493
1516
* first = false;
1494
1517
}
1495
1518
else {
1496
- if (_PyUnicodeWriter_WriteStr (writer , s -> item_separator ) < 0 ) {
1519
+ if (_PyUnicodeWriter_WriteStr (writer , item_separator ) < 0 ) {
1497
1520
Py_DECREF (keystr );
1498
1521
return -1 ;
1499
1522
}
@@ -1511,21 +1534,23 @@ encoder_encode_key_value(PyEncoderObject *s, _PyUnicodeWriter *writer, bool *fir
1511
1534
if (_PyUnicodeWriter_WriteStr (writer , s -> key_separator ) < 0 ) {
1512
1535
return -1 ;
1513
1536
}
1514
- if (encoder_listencode_obj (s , writer , value , indent_level ) < 0 ) {
1537
+ if (encoder_listencode_obj (s , writer , value , newline_indent ) < 0 ) {
1515
1538
return -1 ;
1516
1539
}
1517
1540
return 0 ;
1518
1541
}
1519
1542
1520
1543
static int
1521
1544
encoder_listencode_dict (PyEncoderObject * s , _PyUnicodeWriter * writer ,
1522
- PyObject * dct , Py_ssize_t indent_level )
1545
+ PyObject * dct , PyObject * newline_indent )
1523
1546
{
1524
1547
/* Encode Python dict dct a JSON term */
1525
1548
PyObject * ident = NULL ;
1526
1549
PyObject * items = NULL ;
1527
1550
PyObject * key , * value ;
1528
1551
bool first = true;
1552
+ PyObject * new_newline_indent = NULL ;
1553
+ PyObject * separator_indent = NULL ;
1529
1554
1530
1555
if (PyDict_GET_SIZE (dct ) == 0 ) /* Fast path */
1531
1556
return _PyUnicodeWriter_WriteASCIIString (writer , "{}" , 2 );
@@ -1549,14 +1574,21 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer,
1549
1574
if (_PyUnicodeWriter_WriteChar (writer , '{' ))
1550
1575
goto bail ;
1551
1576
1577
+ PyObject * current_item_separator = s -> item_separator ; // borrowed reference
1552
1578
if (s -> indent != Py_None ) {
1553
- /* TODO: DOES NOT RUN */
1554
- indent_level += 1 ;
1555
- /*
1556
- newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
1557
- separator = _item_separator + newline_indent
1558
- buf += newline_indent
1559
- */
1579
+ new_newline_indent = PyUnicode_Concat (newline_indent , s -> indent );
1580
+ if (new_newline_indent == NULL ) {
1581
+ goto bail ;
1582
+ }
1583
+ separator_indent = PyUnicode_Concat (current_item_separator , new_newline_indent );
1584
+ if (separator_indent == NULL ) {
1585
+ goto bail ;
1586
+ }
1587
+ // update item separator with a borrowed reference
1588
+ current_item_separator = separator_indent ;
1589
+ if (_PyUnicodeWriter_WriteStr (writer , new_newline_indent ) < 0 ) {
1590
+ goto bail ;
1591
+ }
1560
1592
}
1561
1593
1562
1594
if (s -> sort_keys || !PyDict_CheckExact (dct )) {
@@ -1574,15 +1606,19 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer,
1574
1606
1575
1607
key = PyTuple_GET_ITEM (item , 0 );
1576
1608
value = PyTuple_GET_ITEM (item , 1 );
1577
- if (encoder_encode_key_value (s , writer , & first , key , value , indent_level ) < 0 )
1609
+ if (encoder_encode_key_value (s , writer , & first , key , value ,
1610
+ new_newline_indent ,
1611
+ current_item_separator ) < 0 )
1578
1612
goto bail ;
1579
1613
}
1580
1614
Py_CLEAR (items );
1581
1615
1582
1616
} else {
1583
1617
Py_ssize_t pos = 0 ;
1584
1618
while (PyDict_Next (dct , & pos , & key , & value )) {
1585
- if (encoder_encode_key_value (s , writer , & first , key , value , indent_level ) < 0 )
1619
+ if (encoder_encode_key_value (s , writer , & first , key , value ,
1620
+ new_newline_indent ,
1621
+ current_item_separator ) < 0 )
1586
1622
goto bail ;
1587
1623
}
1588
1624
}
@@ -1592,29 +1628,36 @@ encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer,
1592
1628
goto bail ;
1593
1629
Py_CLEAR (ident );
1594
1630
}
1595
- /* TODO DOES NOT RUN; dead code
1596
1631
if (s -> indent != Py_None ) {
1597
- indent_level -= 1;
1632
+ Py_CLEAR (new_newline_indent );
1633
+ Py_CLEAR (separator_indent );
1634
+
1635
+ if (_PyUnicodeWriter_WriteStr (writer , newline_indent ) < 0 ) {
1636
+ goto bail ;
1637
+ }
1638
+ }
1598
1639
1599
- yield '\n' + (' ' * (_indent * _current_indent_level))
1600
- }*/
1601
1640
if (_PyUnicodeWriter_WriteChar (writer , '}' ))
1602
1641
goto bail ;
1603
1642
return 0 ;
1604
1643
1605
1644
bail :
1606
1645
Py_XDECREF (items );
1607
1646
Py_XDECREF (ident );
1647
+ Py_XDECREF (separator_indent );
1648
+ Py_XDECREF (new_newline_indent );
1608
1649
return -1 ;
1609
1650
}
1610
1651
1611
1652
static int
1612
1653
encoder_listencode_list (PyEncoderObject * s , _PyUnicodeWriter * writer ,
1613
- PyObject * seq , Py_ssize_t indent_level )
1654
+ PyObject * seq , PyObject * newline_indent )
1614
1655
{
1615
1656
PyObject * ident = NULL ;
1616
1657
PyObject * s_fast = NULL ;
1617
1658
Py_ssize_t i ;
1659
+ PyObject * new_newline_indent = NULL ;
1660
+ PyObject * separator_indent = NULL ;
1618
1661
1619
1662
ident = NULL ;
1620
1663
s_fast = PySequence_Fast (seq , "_iterencode_list needs a sequence" );
@@ -1643,22 +1686,31 @@ encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer,
1643
1686
1644
1687
if (_PyUnicodeWriter_WriteChar (writer , '[' ))
1645
1688
goto bail ;
1689
+
1690
+ PyObject * separator = s -> item_separator ; // borrowed reference
1646
1691
10000
if (s -> indent != Py_None ) {
1647
- /* TODO: DOES NOT RUN */
1648
- indent_level += 1 ;
1649
- /*
1650
- newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
1651
- separator = _item_separator + newline_indent
1652
- buf += newline_indent
1653
- */
1692
+ new_newline_indent = PyUnicode_Concat (newline_indent , s -> indent );
1693
+ if (new_newline_indent == NULL ) {
1694
+ goto bail ;
1695
+ }
1696
+
1697
+ if (_PyUnicodeWriter_WriteStr (writer , new_newline_indent ) < 0 ) {
1698
+ goto bail ;
1699
+ }
1700
+
1701
+ separator_indent = PyUnicode_Concat (separator , new_newline_indent );
1702
+ if (separator_indent == NULL ) {
1703
+ goto bail ;
1704
+ }
1705
+ separator = separator_indent ; // assign separator with borrowed reference
1654
1706
}
1655
1707
for (i = 0 ; i < PySequence_Fast_GET_SIZE (s_fast ); i ++ ) {
1656
1708
PyObject * obj = PySequence_Fast_GET_ITEM (s_fast , i );
1657
1709
if (i ) {
1658
- if (_PyUnicodeWriter_WriteStr (writer , s -> item_separator ) )
1710
+ if (_PyUnicodeWriter_WriteStr (writer , separator ) < 0 )
1659
1711
goto bail ;
1660
1712
}
1661
- if (encoder_listencode_obj (s , writer , obj , indent_level ))
1713
+ if (encoder_listencode_obj (s , writer , obj , new_newline_indent ))
1662
1714
goto bail ;
1663
1715
}
1664
1716
if (ident != NULL ) {
@@ -1667,12 +1719,14 @@ encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer,
1667
1719
Py_CLEAR (ident );
1668
1720
}
1669
1721
1670
- /* TODO: DOES NOT RUN
1671
1722
if (s -> indent != Py_None ) {
1672
- indent_level -= 1;
1723
+ Py_CLEAR (new_newline_indent );
1724
+ Py_CLEAR (separator_indent );
1725
+ if (_PyUnicodeWriter_WriteStr (writer , newline_indent ) < 0 ) {
1726
+ goto bail ;
1727
+ }
1728
+ }
1673
1729
1674
- yield '\n' + (' ' * (_indent * _current_indent_level))
1675
- }*/
1676
1730
if (_PyUnicodeWriter_WriteChar (writer , ']' ))
1677
1731
goto bail ;
1678
1732
Py_DECREF (s_fast );
@@ -1681,6 +1735,8 @@ encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer,
1681
1735
bail :
1682
1736
Py_XDECREF (ident );
1683
1737
Py_DECREF (s_fast );
1738
+ Py_XDECREF (separator_indent );
1739
+ Py_XDECREF (new_newline_indent );
1684
1740
return -1 ;
1685
1741
}
1686
1742
@@ -1721,7 +1777,7 @@ encoder_clear(PyEncoderObject *self)
1721
1777
return 0 ;
1722
1778
}
1723
1779
1724
- PyDoc_STRVAR (encoder_doc , "_iterencode(obj, _current_indent_level) -> iterable " );
1780
+ PyDoc_STRVAR (encoder_doc , "Encoder(markers, default, encoder, indent, key_separator, item_separator, sort_keys, skipkeys, allow_nan) " );
1725
1781
1726
1782
static PyType_Slot PyEncoderType_slots [] = {
1727
1783
{Py_tp_doc , (void * )encoder_doc },
0 commit comments