Skip to content

Commit 5782897

Browse files
AA-Turnerpicnixz
andauthored
t-strings: Reduce undefined behaviour and general improvements (#72)
Co-authored-by: Bénédikt Tran <[email protected]>
1 parent 4c6cb47 commit 5782897

File tree

7 files changed

+51
-41
lines changed

7 files changed

+51
-41
lines changed

Include/internal/pycore_interpolation.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ extern "C" {
1313

1414
extern PyTypeObject _PyInterpolation_Type;
1515

16-
#define _PyInterpolation_Check(op) PyObject_TypeCheck((op), &_PyInterpolation_Type)
1716
#define _PyInterpolation_CheckExact(op) Py_IS_TYPE((op), &_PyInterpolation_Type)
1817

1918
PyAPI_FUNC(PyObject *) _PyInterpolation_FromStackRefStealOnSuccess(_PyStackRef *values);

Include/internal/pycore_template.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ extern "C" {
1212
extern PyTypeObject _PyTemplate_Type;
1313
extern PyTypeObject _PyTemplateIter_Type;
1414

15-
#define _PyTemplate_Check(op) PyObject_TypeCheck((op), &_PyTemplate_Type)
1615
#define _PyTemplate_CheckExact(op) Py_IS_TYPE((op), &_PyTemplate_Type)
1716

1817
extern PyObject *_PyTemplate_Concat(PyObject *self, PyObject *other);

Makefile.pre.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,7 @@ OBJECT_OBJS= \
542542
Objects/floatobject.o \
543543
Objects/frameobject.o \
544544
Objects/funcobject.o \
545+
Objects/interpolationobject.o \
545546
Objects/iterobject.o \
546547
Objects/listobject.o \
547548
Objects/longobject.o \
@@ -558,15 +559,14 @@ OBJECT_OBJS= \
558559
Objects/setobject.o \
559560
Objects/sliceobject.o \
560561
Objects/structseq.o \
562+
Objects/templateobject.o \
561563
Objects/tupleobject.o \
562564
Objects/typeobject.o \
563565
Objects/typevarobject.o \
564566
Objects/unicodeobject.o \
565567
Objects/unicodectype.o \
566568
Objects/unionobject.o \
567569
Objects/weakrefobject.o \
568-
Objects/interpolationobject.o \
569-
Objects/templateobject.o \
570570
@PERF_TRAMPOLINE_OBJ@
571571

572572
##########################################################################

Modules/Setup.bootstrap.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ _io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io
2121
itertools itertoolsmodule.c
2222
_sre _sre/sre.c
2323
_sysconfig _sysconfig.c
24+
_templatelib _templatelibmodule.c
2425
_thread _threadmodule.c
2526
time timemodule.c
2627
_types _typesmodule.c
2728
_typing _typingmodule.c
2829
_weakref _weakref.c
29-
_templatelib _templatelibmodule.c
3030

3131
# commonly used core modules
3232
_abc _abc.c

Objects/interpolationobject.c

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ _conversion_converter(PyObject *arg, PyObject **conversion)
1313

1414
if (!PyUnicode_Check(arg)) {
1515
PyErr_Format(PyExc_TypeError,
16-
"%.200s() %.200s must be %.50s, not %.50s",
17-
"Interpolation", "argument 'conversion'", "str",
18-
arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
16+
"Interpolation() argument 'conversion' must be str, not %T",
17+
arg);
1918
return 0;
2019
}
2120

@@ -46,6 +45,9 @@ typedef struct {
4645
PyObject *format_spec;
4746
} interpolationobject;
4847

48+
#define interpolationobject_CAST(op) \
49+
(assert(_PyInterpolation_CheckExact(op)), _Py_CAST(interpolationobject*, (op)))
50+
4951
/*[clinic input]
5052
@classmethod
5153
Interpolation.__new__ as interpolation_new
@@ -75,8 +77,9 @@ interpolation_new_impl(PyTypeObject *type, PyObject *value,
7577
}
7678

7779
static void
78-
interpolation_dealloc(interpolationobject *self)
80+
interpolation_dealloc(PyObject *op)
7981
{
82+
interpolationobject *self = interpolationobject_CAST(op);
8083
PyObject_GC_UnTrack(self);
8184
Py_CLEAR(self->value);
8285
Py_CLEAR(self->expression);
@@ -86,8 +89,9 @@ interpolation_dealloc(interpolationobject *self)
8689
}
8790

8891
static int
89-
interpolation_traverse(interpolationobject *self, visitproc visit, void *arg)
92+
interpolation_traverse(PyObject *op, visitproc visit, void *arg)
9093
{
94+
interpolationobject *self = interpolationobject_CAST(op);
9195
Py_VISIT(self->value);
9296
Py_VISIT(self->expression);
9397
Py_VISIT(self->conversion);
@@ -96,11 +100,11 @@ interpolation_traverse(interpolationobject *self, visitproc visit, void *arg)
96100
}
97101

98102
static PyObject *
99-
interpolation_repr(interpolationobject *self)
103+
interpolation_repr(PyObject *op)
100104
{
101-
return PyUnicode_FromFormat("%s(%R, %R, %R, %R)",
102-
_PyType_Name(Py_TYPE(self)),
103-
self->value, self->expression,
105+
interpolationobject *self = interpolationobject_CAST(op);
106+
return PyUnicode_FromFormat("%T(%R, %R, %R, %R)",
107+
self, self->value, self->expression,
104108
self->conversion, self->format_spec);
105109
}
106110

@@ -119,13 +123,13 @@ PyTypeObject _PyInterpolation_Type = {
119123
.tp_basicsize = sizeof(interpolationobject),
120124
.tp_itemsize = 0,
121125
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
122-
.tp_new = (newfunc) interpolation_new,
126+
.tp_new = interpolation_new,
123127
.tp_alloc = PyType_GenericAlloc,
124-
.tp_dealloc = (destructor) interpolation_dealloc,
128+
.tp_dealloc = interpolation_dealloc,
125129
.tp_free = PyObject_GC_Del,
126-
.tp_repr = (reprfunc) interpolation_repr,
130+
.tp_repr = interpolation_repr,
127131
.tp_members = interpolation_members,
128-
.tp_traverse = (traverseproc) interpolation_traverse,
132+
.tp_traverse = interpolation_traverse,
129133
};
130134

131135
static PyObject *
@@ -213,5 +217,5 @@ _PyInterpolation_FromStackRefStealOnSuccess(_PyStackRef *values)
213217
PyObject *
214218
_PyInterpolation_GetValue(PyObject *interpolation)
215219
{
216-
return ((interpolationobject *) interpolation)->value;
220+
return interpolationobject_CAST(interpolation)->value;
217221
}

Objects/templateobject.c

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* t-string Template object implementation */
22

33
#include "Python.h"
4-
#include "pycore_interpolation.h" // _PyInterpolation_Check()
4+
#include "pycore_interpolation.h" // _PyInterpolation_CheckExact()
55
#include "pycore_template.h"
66

77
typedef struct {
@@ -67,6 +67,9 @@ typedef struct {
6767
PyObject *interpolations;
6868
} templateobject;
6969

70+
#define templateobject_CAST(op) \
71+
(assert(_PyTemplate_CheckExact(op)), _Py_CAST(templateobject*, (op)))
72+
7073
static templateobject *
7174
template_from_strings_interpolations(PyTypeObject *type, PyObject *strings, PyObject *interpolations)
7275
{
@@ -80,7 +83,7 @@ template_from_strings_interpolations(PyTypeObject *type, PyObject *strings, PyOb
8083
return template;
8184
}
8285

83-
static templateobject *
86+
static PyObject *
8487
template_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
8588
{
8689
if (kwds != NULL) {
@@ -101,7 +104,7 @@ template_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
101104
}
102105
last_was_str = 1;
103106
}
104-
else if (_PyInterpolation_Check(item)) {
107+
else if (_PyInterpolation_CheckExact(item)) {
105108
if (!last_was_str) {
106109
stringslen++;
107110
}
@@ -149,7 +152,7 @@ template_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
149152
}
150153
last_was_str = 1;
151154
}
152-
else if (_PyInterpolation_Check(item)) {
155+
else if (_PyInterpolation_CheckExact(item)) {
153156
if (!last_was_str) {
154157
PyTuple_SET_ITEM(strings, stringsidx++, &_Py_STR(empty));
155158
}
@@ -164,38 +167,42 @@ template_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
164167
templateobject *template = template_from_strings_interpolations(type, strings, interpolations);
165168
Py_DECREF(strings);
166169
Py_DECREF(interpolations);
167-
return template;
170+
return (PyObject *)template;
168171
}
169172

170173
static void
171-
template_dealloc(templateobject *self)
174+
template_dealloc(PyObject *op)
172175
{
176+
templateobject *self = templateobject_CAST(op);
173177
PyObject_GC_UnTrack(self);
174178
Py_CLEAR(self->strings);
175179
Py_CLEAR(self->interpolations);
176180
Py_TYPE(self)->tp_free(self);
177181
}
178182

179183
static int
180-
template_traverse(templateobject *self, visitproc visit, void *arg)
184+
template_traverse(PyObject *op, visitproc visit, void *arg)
181185
{
186+
templateobject *self = templateobject_CAST(op);
182187
Py_VISIT(self->strings);
183188
Py_VISIT(self->interpolations);
184189
return 0;
185190
}
186191

187192
static PyObject *
188-
template_repr(templateobject *self)
193+
template_repr(PyObject *op)
189194
{
195+
templateobject *self = templateobject_CAST(op);
190196
return PyUnicode_FromFormat("%s(strings=%R, interpolations=%R)",
191197
_PyType_Name(Py_TYPE(self)),
192198
self->strings,
193199
self->interpolations);
194200
}
195201

196-
static templateiterobject *
197-
template_iter(templateobject *self)
202+
static PyObject *
203+
template_iter(PyObject *op)
198204
{
205+
templateobject *self = templateobject_CAST(op);
199206
templateiterobject *iter = PyObject_GC_New(templateiterobject, &_PyTemplateIter_Type);
200207
if (iter == NULL) {
201208
return NULL;
@@ -218,7 +225,7 @@ template_iter(templateobject *self)
218225
iter->interpolationsiter = interpolationsiter;
219226
iter->from_strings = 1;
220227
PyObject_GC_Track(iter);
221-
return iter;
228+
return (PyObject *)iter;
222229
}
223230

224231
static PyObject *
@@ -398,13 +405,13 @@ template_concat_str_template(templateobject *self, PyObject *other)
398405
PyObject *
399406
_PyTemplate_Concat(PyObject *self, PyObject *other)
400407
{
401-
if (_PyTemplate_Check(self) && _PyTemplate_Check(other)) {
408+
if (_PyTemplate_CheckExact(self) && _PyTemplate_CheckExact(other)) {
402409
return template_concat_templates((templateobject *) self, (templateobject *) other);
403410
}
404-
else if ((_PyTemplate_Check(self)) && PyUnicode_Check(other)) {
411+
else if ((_PyTemplate_CheckExact(self)) && PyUnicode_Check(other)) {
405412
return template_concat_template_str((templateobject *) self, other);
406413
}
407-
else if (PyUnicode_Check(self) && (_PyTemplate_Check(other))) {
414+
else if (PyUnicode_Check(self) && (_PyTemplate_CheckExact(other))) {
408415
return template_concat_str_template((templateobject *) other, self);
409416
}
410417
else {
@@ -413,8 +420,9 @@ _PyTemplate_Concat(PyObject *self, PyObject *other)
413420
}
414421

415422
static PyObject *
416-
template_values_get(templateobject *self, void *Py_UNUSED(data))
423+
template_values_get(PyObject *op, void *Py_UNUSED(data))
417424
{
425+
templateobject *self = templateobject_CAST(op);
418426
PyObject *values = PyTuple_New(PyTuple_GET_SIZE(self->interpolations));
419427
if (values == NULL) {
420428
return NULL;
@@ -448,7 +456,7 @@ static PyMemberDef template_members[] = {
448456
};
449457

450458
static PyGetSetDef template_getset[] = {
451-
{"values", (getter) template_values_get, NULL, "Values of interpolations", NULL},
459+
{"values", template_values_get, NULL, "Values of interpolations", NULL},
452460
{NULL},
453461
};
454462

@@ -464,15 +472,15 @@ PyTypeObject _PyTemplate_Type = {
464472
.tp_itemsize = 0,
465473
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
466474
.tp_as_sequence = &template_as_sequence,
467-
.tp_new = (newfunc) template_new,
475+
.tp_new = template_new,
468476
.tp_alloc = PyType_GenericAlloc,
469-
.tp_dealloc = (destructor) template_dealloc,
477+
.tp_dealloc = template_dealloc,
470478
.tp_free = PyObject_GC_Del,
471-
.tp_repr = (reprfunc) template_repr,
479+
.tp_repr = template_repr,
472480
.tp_members = template_members,
473481
.tp_getset = template_getset,
474-
.tp_iter = (getiterfunc) template_iter,
475-
.tp_traverse = (traverseproc) template_traverse,
482+
.tp_iter = template_iter,
483+
.tp_traverse = template_traverse,
476484
};
477485

478486
PyObject *

Objects/unicodeobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11618,7 +11618,7 @@ PyUnicode_Concat(PyObject *left, PyObject *right)
1161811618
return NULL;
1161911619

1162011620
if (!PyUnicode_Check(right)) {
11621-
if (_PyTemplate_Check(right)) {
11621+
if (_PyTemplate_CheckExact(right)) {
1162211622
// str + tstring is implemented in the tstring type
1162311623
return _PyTemplate_Concat(left, right);
1162411624
}

0 commit comments

Comments
 (0)