@@ -1435,8 +1435,230 @@ def visitModule(self, mod):
14351435 {NULL}
14361436};
14371437
1438+ static PyObject *
1439+ ast_repr_max_depth(AST_object *self, int depth);
1440+
1441+ /* Format list and tuple properties of AST nodes.
1442+ Note that, only the first and last elements are shown.
1443+ Anything in between is represented with an ellipsis ('...').
1444+ For example, the list [1, 2, 3] is formatted as
1445+ 'List(elts=[Constant(1), ..., Constant(3)])'. */
1446+ static PyObject *
1447+ ast_repr_list(PyObject *list, int depth)
1448+ {
1449+ assert(PyList_Check(list) || PyTuple_Check(list));
1450+
1451+ struct ast_state *state = get_ast_state();
1452+ if (state == NULL) {
1453+ return NULL;
1454+ }
1455+
1456+ Py_ssize_t length = PySequence_Size(list);
1457+ if (length < 0) {
1458+ return NULL;
1459+ }
1460+ else if (length == 0) {
1461+ return PyObject_Repr(list);
1462+ }
1463+
1464+ _PyUnicodeWriter writer;
1465+ _PyUnicodeWriter_Init(&writer);
1466+ writer.overallocate = 1;
1467+ PyObject *items[2] = {NULL, NULL};
1468+
1469+ items[0] = PySequence_GetItem(list, 0);
1470+ if (!items[0]) {
1471+ goto error;
1472+ }
1473+ if (length > 1) {
1474+ items[1] = PySequence_GetItem(list, length - 1);
1475+ if (!items[1]) {
1476+ goto error;
1477+ }
1478+ }
1479+
1480+ bool is_list = PyList_Check(list);
1481+ if (_PyUnicodeWriter_WriteChar(&writer, is_list ? '[' : '(') < 0) {
1482+ goto error;
1483+ }
1484+
1485+ for (Py_ssize_t i = 0; i < Py_MIN(length, 2); i++) {
1486+ PyObject *item = items[i];
1487+ PyObject *item_repr;
1488+
1489+ if (PyType_IsSubtype(Py_TYPE(item), (PyTypeObject *)state->AST_type)) {
1490+ item_repr = ast_repr_max_depth((AST_object*)item, depth - 1);
1491+ } else {
1492+ item_repr = PyObject_Repr(item);
1493+ }
1494+ if (!item_repr) {
1495+ goto error;
1496+ }
1497+ if (i > 0) {
1498+ if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) {
1499+ goto error;
1500+ }
1501+ }
1502+ if (_PyUnicodeWriter_WriteStr(&writer, item_repr) < 0) {
1503+ Py_DECREF(item_repr);
1504+ goto error;
1505+ }
1506+ if (i == 0 && length > 2) {
1507+ if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ...", 5) < 0) {
1508+ Py_DECREF(item_repr);
1509+ goto error;
1510+ }
1511+ }
1512+ Py_DECREF(item_repr);
1513+ }
1514+
1515+ if (_PyUnicodeWriter_WriteChar(&writer, is_list ? ']' : ')') < 0) {
1516+ goto error;
1517+ }
1518+
1519+ Py_XDECREF(items[0]);
1520+ Py_XDECREF(items[1]);
1521+ return _PyUnicodeWriter_Finish(&writer);
1522+
1523+ error:
1524+ Py_XDECREF(items[0]);
1525+ Py_XDECREF(items[1]);
1526+ _PyUnicodeWriter_Dealloc(&writer);
1527+ return NULL;
1528+ }
1529+
1530+ static PyObject *
1531+ ast_repr_max_depth(AST_object *self, int depth)
1532+ {
1533+ struct ast_state *state = get_ast_state();
1534+ if (state == NULL) {
1535+ return NULL;
1536+ }
1537+
1538+ if (depth <= 0) {
1539+ return PyUnicode_FromFormat("%s(...)", Py_TYPE(self)->tp_name);
1540+ }
1541+
1542+ int status = Py_ReprEnter((PyObject *)self);
1543+ if (status != 0) {
1544+ if (status < 0) {
1545+ return NULL;
1546+ }
1547+ return PyUnicode_FromFormat("%s(...)", Py_TYPE(self)->tp_name);
1548+ }
1549+
1550+ PyObject *fields;
1551+ if (PyObject_GetOptionalAttr((PyObject *)Py_TYPE(self), state->_fields, &fields) < 0) {
1552+ Py_ReprLeave((PyObject *)self);
1553+ return NULL;
1554+ }
1555+
1556+ Py_ssize_t numfields = PySequence_Size(fields);
1557+ if (numfields < 0) {
1558+ Py_ReprLeave((PyObject *)self);
1559+ Py_DECREF(fields);
1560+ return NULL;
1561+ }
1562+
1563+ if (numfields == 0) {
1564+ Py_ReprLeave((PyObject *)self);
1565+ Py_DECREF(fields);
1566+ return PyUnicode_FromFormat("%s()", Py_TYPE(self)->tp_name);
1567+ }
1568+
1569+ const char* tp_name = Py_TYPE(self)->tp_name;
1570+ _PyUnicodeWriter writer;
1571+ _PyUnicodeWriter_Init(&writer);
1572+ writer.overallocate = 1;
1573+
1574+ if (_PyUnicodeWriter_WriteASCIIString(&writer, tp_name, strlen(tp_name)) < 0) {
1575+ goto error;
1576+ }
1577+ if (_PyUnicodeWriter_WriteChar(&writer, '(') < 0) {
1578+ goto error;
1579+ }
1580+
1581+ for (Py_ssize_t i = 0; i < numfields; i++) {
1582+ PyObject *name = PySequence_GetItem(fields, i);
1583+ if (!name) {
1584+ goto error;
1585+ }
1586+
1587+ PyObject *value = PyObject_GetAttr((PyObject *)self, name);
1588+ if (!value) {
1589+ Py_DECREF(name);
1590+ goto error;
1591+ }
1592+
1593+ PyObject *value_repr;
1594+ if (PyList_Check(value) || PyTuple_Check(value)) {
1595+ value_repr = ast_repr_list(value, depth);
1596+ }
1597+ else if (PyType_IsSubtype(Py_TYPE(value), (PyTypeObject *)state->AST_type)) {
1598+ value_repr = ast_repr_max_depth((AST_object*)value, depth - 1);
1599+ }
1600+ else {
1601+ value_repr = PyObject_Repr(value);
1602+ }
1603+
1604+ Py_DECREF(value);
1605+
1606+ if (!value_repr) {
1607+ Py_DECREF(name);
1608+ Py_DECREF(value);
1609+ goto error;
1610+ }
1611+
1612+ if (i > 0) {
1613+ if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) {
1614+ Py_DECREF(name);
1615+ Py_DECREF(value_repr);
1616+ goto error;
1617+ }
1618+ }
1619+ if (_PyUnicodeWriter_WriteStr(&writer, name) < 0) {
1620+ Py_DECREF(name);
1621+ Py_DECREF(value_repr);
1622+ goto error;
1623+ }
1624+
1625+ Py_DECREF(name);
1626+
1627+ if (_PyUnicodeWriter_WriteChar(&writer, '=') < 0) {
1628+ Py_DECREF(value_repr);
1629+ goto error;
1630+ }
1631+ if (_PyUnicodeWriter_WriteStr(&writer, value_repr) < 0) {
1632+ Py_DECREF(value_repr);
1633+ goto error;
1634+ }
1635+
1636+ Py_DECREF(value_repr);
1637+ }
1638+
1639+ if (_PyUnicodeWriter_WriteChar(&writer, ')') < 0) {
1640+ goto error;
1641+ }
1642+ Py_ReprLeave((PyObject *)self);
1643+ Py_DECREF(fields);
1644+ return _PyUnicodeWriter_Finish(&writer);
1645+
1646+ error:
1647+ Py_ReprLeave((PyObject *)self);
1648+ Py_DECREF(fields);
1649+ _PyUnicodeWriter_Dealloc(&writer);
1650+ return NULL;
1651+ }
1652+
1653+ static PyObject *
1654+ ast_repr(AST_object *self)
1655+ {
1656+ return ast_repr_max_depth(self, 3);
1657+ }
1658+
14381659static PyType_Slot AST_type_slots[] = {
14391660 {Py_tp_dealloc, ast_dealloc},
1661+ {Py_tp_repr, ast_repr},
14401662 {Py_tp_getattro, PyObject_GenericGetAttr},
14411663 {Py_tp_setattro, PyObject_GenericSetAttr},
14421664 {Py_tp_traverse, ast_traverse},
0 commit comments