Add a format specifier %R to PyUnicode_FromFormat(), which embeds · pythoncapi/cpython@7569dfe · GitHub
Skip to content

Commit 7569dfe

Browse files
committed
Add a format specifier %R to PyUnicode_FromFormat(), which embeds
the result of a call to PyObject_Repr() into the string. This makes it possible to simplify many repr implementations. PyUnicode_FromFormat() uses two steps to create the final string: A first pass through the format string determines the size of the final string and a second pass creates the string. To avoid calling PyObject_Repr() twice for each %R specifier, PyObject_Repr() is called during the size calculation step and the results are stored in an array (whose size is determined at the start by counting %R specifiers).
1 parent 94b59bb commit 7569dfe

12 files changed

Lines changed: 125 additions & 149 deletions

Modules/_collectionsmodule.c

Lines changed: 6 additions & 20 deletions

Modules/_elementtree.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,17 +1118,7 @@ element_remove(ElementObject* self, PyObject* args)
11181118
static PyObject*
11191119
element_repr(ElementObject* self)
11201120
{
1121-
PyObject* repr;
1122-
char buffer[100];
1123-
1124-
repr = PyUnicode_FromString("<Element ");
1125-
1126-
PyUnicode_AppendAndDel(&repr, PyObject_Repr(self->tag));
1127-
1128-
sprintf(buffer, " at %p>", self);
1129-
PyUnicode_AppendAndDel(&repr, PyUnicode_FromString(buffer));
1130-
1131-
return repr;
1121+
return PyUnicode_FromFormat("<Element %R at %p>", self->tag, self);
11321122
}
11331123

11341124
static PyObject*

Modules/_tkinter.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -809,10 +809,8 @@ PyTclObject_unicode(PyTclObject *self, void *ignored)
809809
static PyObject *
810810
PyTclObject_repr(PyTclObject *self)
811811
{
812-
char buf[50];
813-
PyOS_snprintf(buf, 50, "<%s object at %p>",
814-
self->value->typePtr->name, self->value);
815-
return PyUnicode_FromString(buf);
812+
return PyUnicode_FromFormat("<%s object at %p>",
813+
self->value->typePtr->name, self->value);
816814
}
817815

818816
static int

Modules/arraymodule.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,29 +1567,23 @@ static PyObject *
15671567
array_repr(arrayobject *a)
15681568
{
15691569
char buf[256], typecode;
1570-
PyObject *s, *t, *v = NULL;
1570+
PyObject *s, *v = NULL;
15711571
Py_ssize_t len;
15721572

15731573
len = a->ob_size;
15741574
typecode = a->ob_descr->typecode;
15751575
if (len == 0) {
1576-
PyOS_snprintf(buf, sizeof(buf), "array('%c')", typecode);
1577-
return PyUnicode_FromString(buf);
1576+
return PyUnicode_FromFormat("array('%c')", typecode);
15781577
}
1579-
15801578
if (typecode == 'c')
15811579
v = array_tostring(a, NULL);
15821580
else if (typecode == 'u')
15831581
v = array_tounicode(a, NULL);
15841582
else
15851583
v = array_tolist(a, NULL);
1586-
t = PyObject_Repr(v);
1587-
Py_XDECREF(v);
15881584

1589-
PyOS_snprintf(buf, sizeof(buf), "array('%c', ", typecode);
1590-
s = PyUnicode_FromString(buf);
1591-
PyUnicode_AppendAndDel(&s, t);
1592-
PyUnicode_AppendAndDel(&s, PyUnicode_FromString(")"));
1585+
s = PyUnicode_FromFormat("array('%c', %R)", typecode, v);
1586+
Py_DECREF(v);
15931587
return s;
15941588
}
15951589

Modules/datetimemodule.c

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1973,19 +1973,19 @@ delta_repr(PyDateTime_Delta *self)
19731973
{
19741974
if (GET_TD_MICROSECONDS(self) != 0)
19751975
return PyUnicode_FromFormat("%s(%d, %d, %d)",
1976-
self->ob_type->tp_name,
1977-
GET_TD_DAYS(self),
1978-
GET_TD_SECONDS(self),
1979-
GET_TD_MICROSECONDS(self));
1976+
self->ob_type->tp_name,
1977+
GET_TD_DAYS(self),
1978+
GET_TD_SECONDS(self),
1979+
GET_TD_MICROSECONDS(self));
19801980
if (GET_TD_SECONDS(self) != 0)
19811981
return PyUnicode_FromFormat("%s(%d, %d)",
1982-
self->ob_type->tp_name,
1983-
GET_TD_DAYS(self),
1984-
GET_TD_SECONDS(self));
1982+
self->ob_type->tp_name,
1983+
GET_TD_DAYS(self),
1984+
GET_TD_SECONDS(self));
19851985

19861986
return PyUnicode_FromFormat("%s(%d)",
1987-
self->ob_type->tp_name,
1988-
GET_TD_DAYS(self));
1987+
self->ob_type->tp_name,
1988+
GET_TD_DAYS(self));
19891989
}
19901990

19911991
static PyObject *
@@ -2402,15 +2402,9 @@ date_subtract(PyObject *left, PyObject *right)
24022402
static PyObject *
24032403
date_repr(PyDateTime_Date *self)
24042404
{
2405-
char buffer[1028];
2406-
const char *type_name;
2407-
2408-
type_name = self->ob_type->tp_name;
2409-
PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
2410-
type_name,
2411-
GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
2412-
2413-
return PyUnicode_FromString(buffer);
2405+
return PyUnicode_FromFormat("%s(%d, %d, %d)",
2406+
self->ob_type->tp_name,
2407+
GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
24142408
}
24152409

24162410
static PyObject *
@@ -3114,7 +3108,6 @@ time_tzname(PyDateTime_Time *self, PyObject *unused) {
31143108
static PyObject *
31153109
time_repr(PyDateTime_Time *self)
31163110
{
3117-
char buffer[100];
31183111
const char *type_name = self->ob_type->tp_name;
31193112
int h = TIME_GET_HOUR(self);
31203113
int m = TIME_GET_MINUTE(self);
@@ -3123,15 +3116,13 @@ time_repr(PyDateTime_Time *self)
31233116
PyObject *result = NULL;
31243117

31253118
if (us)
3126-
PyOS_snprintf(buffer, sizeof(buffer),
3127-
"%s(%d, %d, %d, %d)", type_name, h, m, s, us);
3119+
result = PyUnicode_FromFormat("%s(%d, %d, %d, %d)",
3120+
type_name, h, m, s, us);
31283121
else if (s)
3129-
PyOS_snprintf(buffer, sizeof(buffer),
3130-
"%s(%d, %d, %d)", type_name, h, m, s);
3122+
result = PyUnicode_FromFormat("%s(%d, %d, %d)",
3123+
type_name, h, m, s);
31313124
else
3132-
PyOS_snprintf(buffer, sizeof(buffer),
3133-
"%s(%d, %d)", type_name, h, m);
3134-
result = PyUnicode_FromString(buffer);
3125+
result = PyUnicode_FromFormat("%s(%d, %d)", type_name, h, m);
31353126
if (result != NULL && HASTZINFO(self))
31363127
result = append_keyword_tzinfo(result, self->tzinfo);
31373128
return result;
@@ -4020,7 +4011,7 @@ datetime_repr(PyDateTime_DateTime *self)
40204011
PyObject *baserepr;
40214012

40224013
if (DATE_GET_MICROSECOND(self)) {
4023-
PyOS_snprintf(buffer, sizeof(buffer),
4014+
baserepr = PyUnicode_FromFormat(
40244015
"%s(%d, %d, %d, %d, %d, %d, %d)",
40254016
type_name,
40264017
GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
@@ -4029,21 +4020,20 @@ datetime_repr(PyDateTime_DateTime *self)
40294020
DATE_GET_MICROSECOND(self));
40304021
}
40314022
else if (DATE_GET_SECOND(self)) {
4032-
PyOS_snprintf(buffer, sizeof(buffer),
4023+
baserepr = PyUnicode_FromFormat(
40334024
"%s(%d, %d, %d, %d, %d, %d)",
40344025
type_name,
40354026
GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
40364027
DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
40374028
DATE_GET_SECOND(self));
40384029
}
40394030
else {
4040-
PyOS_snprintf(buffer, sizeof(buffer),
4031+
baserepr = PyUnicode_FromFormat(
40414032
"%s(%d, %d, %d, %d, %d)",
40424033
type_name,
40434034
GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
40444035
DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
40454036
}
4046-
baserepr = PyUnicode_FromString(buffer);
40474037
if (baserepr == NULL || ! HASTZINFO(self))
40484038
return baserepr;
40494039
return append_keyword_tzinfo(baserepr, self->tzinfo);

Modules/itertoolsmodule.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2389,20 +2389,10 @@ repeat_next(repeatobject *ro)
23892389
static PyObject *
23902390
repeat_repr(repeatobject *ro)
23912391
{
2392-
PyObject *result, *objrepr;
2393-
2394-
objrepr = PyObject_Repr(ro->element);
2395-
if (objrepr == NULL)
2396-
return NULL;
2397-
23982392
if (ro->cnt == -1)
2399-
result = PyUnicode_FromFormat("repeat(%U)",
2400-
objrepr);
2393+
return PyUnicode_FromFormat("repeat(%R)", ro->element);
24012394
else
2402-
result = PyUnicode_FromFormat("repeat(%U, %zd)",
2403-
objrepr, ro->cnt);
2404-
Py_DECREF(objrepr);
2405-
return result;
2395+
return PyUnicode_FromFormat("repeat(%R, %zd)", ro->element, ro->cnt);
24062396
}
24072397

24082398
static PyObject *

Objects/classobject.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,9 @@ method_repr(PyMethodObject *a)
261261
result = PyUnicode_FromFormat("<unbound method %s.%s>",
262262
sklassname, sfuncname);
263263
else {
264-
result = PyUnicode_FromFormat("<bound method %s.%s of ",
265-
sklassname, sfuncname);
266-
/* XXX Shouldn't use repr() here! */
267-
PyUnicode_AppendAndDel(&result, PyObject_Repr(self));
268-
PyUnicode_AppendAndDel(&result, PyUnicode_FromString(">"));
264+
/* XXX Shouldn't use repr()/%R here! */
265+
result = PyUnicode_FromFormat("<bound method %s.%s of %R>",
266+
sklassname, sfuncname, self);
269267
}
270268
Py_XDECREF(funcname);
271269
Py_XDECREF(klassname);

Objects/exceptions.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -98,27 +98,14 @@ BaseException_str(PyBaseExceptionObject *self)
9898
static PyObject *
9999
BaseException_repr(PyBaseExceptionObject *self)
100100
{
101-
PyObject *repr_suffix;
102-
PyObject *repr;
103101
char *name;
104102
char *dot;
105103

106-
repr_suffix = PyObject_Repr(self->args);
107-
if (!repr_suffix)
108-
return NULL;
109-
110104
name = (char *)self->ob_type->tp_name;
111105
dot = strrchr(name, '.');
112106
if (dot != NULL) name = dot+1;
113107

114-
repr = PyUnicode_FromString(name);
115-
if (!repr) {
116-
Py_DECREF(repr_suffix);
117-
return NULL;
118-
}
119-
120-
PyUnicode_AppendAndDel(&repr, repr_suffix);
121-
return repr;
108+
return PyUnicode_FromFormat("%s%R", name, self->args);
122109
}
123110

124111
/* Pickling support */

Objects/intobject.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,7 @@ int_print(PyIntObject *v, FILE *fp, int flags)
431431
static PyObject *
432432
int_repr(PyIntObject *v)
433433
{
434-
char buf[64];
435-
PyOS_snprintf(buf, sizeof(buf), "%ld", v->ob_ival);
436-
return PyUnicode_FromString(buf);
434+
return PyUnicode_FromFormat("%ld", v->ob_ival);
437435
}
438436

439437
static int

Objects/setobject.c

Lines changed: 20 additions & 25 deletions

0 commit comments

Comments
 (0)