8000 Support explicit concatenation of template and str · python/cpython@f742d45 · GitHub
[go: up one dir, main page]

Skip to content

Commit f742d45

Browse files
committed
Support explicit concatenation of template and str
1 parent 499d70c commit f742d45

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

Objects/templateobject.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,92 @@ template_repr(templateobject *self)
5050
self->args);
5151
}
5252

53+
static PyObject *
54+
template_add_template_str(templateobject *template, PyUnicodeObject *str, int templateleft)
55+
{
56+
Py_ssize_t templatesize = PyTuple_GET_SIZE(template->args);
57+
58+
PyObject *tuple = PyTuple_New(templatesize + 1);
59+
if (!tuple) {
60+
return NULL;
61+
}
62+
63+
Py_ssize_t i = 0;
64+
Py_ssize_t j = 0;
65+
if (!templateleft) {
66+
PyTuple_SET_ITEM(tuple, i++, Py_NewRef(str));
67+
}
68+
for (j = 0; j < templatesize; j++) {
69+
PyTuple_SET_ITEM(tuple, i + j, Py_NewRef(PyTuple_GET_ITEM(template->args, j)));
70+
}
71+
if (templateleft) {
72+
PyTuple_SET_ITEM(tuple, i + j, Py_NewRef(str));
73+
}
74+
75+
PyObject *newtemplate = PyObject_CallOneArg((PyObject *) &_PyTemplate_Type, tuple);
76+
Py_DECREF(tuple);
77+
return newtemplate;
78+
}
79+
80+
static PyObject *
81+
template_add_templates(templateobject *self, templateobject *other)
82+
{
83+
Py_ssize_t selfsize = PyTuple_GET_SIZE(self->args);
84+
Py_ssize_t othersize = PyTuple_GET_SIZE(other->args);
85+
86+
PyObject *tuple = PyTuple_New(selfsize + othersize);
87+
if (!tuple) {
88+
return NULL;
89+
}
90+
91+
Py_ssize_t i;
92+
for (i = 0; i < selfsize; i++) {
93+
PyTuple_SET_ITEM(tuple, i, Py_NewRef(PyTuple_GET_ITEM(self->args, i)));
94+
}
95+
for (Py_ssize_t j = 0; j < othersize; j++) {
96+
PyTuple_SET_ITEM(tuple, i + j, Py_NewRef(PyTuple_GET_ITEM(other->args, j)));
97+
}
98+
99+
PyObject *newtemplate = PyObject_CallOneArg((PyObject *) &_PyTemplate_Type, tuple);
100+
Py_DECREF(tuple);
101+
return newtemplate;
102+
}
103+
104+
static PyObject *
105+
template_add(PyObject *self, PyObject *other)
106+
{
107+
if (PyObject_TypeCheck(self, &_PyTemplate_Type) &&
108+
PyObject_TypeCheck(other, &_PyTemplate_Type)) {
109+
return template_add_templates((templateobject *) self, (templateobject *) other);
110+
}
111+
else if (PyObject_TypeCheck(self, &_PyTemplate_Type) && PyUnicode_Check(other)) {
112+
return template_add_template_str((templateobject *) self, (PyUnicodeObject *) other, 1);
113+
}
114+
else if (PyUnicode_Check(self) && PyObject_TypeCheck(other, &_PyTemplate_Type)) {
115+
return template_add_template_str((templateobject *) other, (PyUnicodeObject *) self, 0);
116+
}
117+
else {
118+
Py_RETURN_NOTIMPLEMENTED;
119+
}
120+
}
121+
53122
static PyMemberDef template_members[] = {
54123
{"args", Py_T_OBJECT_EX, offsetof(templateobject, args), Py_READONLY, "Args"},
55124
{NULL}
56125
};
57126

127+
static PyNumberMethods template_as_number = {
128+
.nb_add = template_add
129+
};
130+
58131
PyTypeObject _PyTemplate_Type = {
59132
PyVarObject_HEAD_INIT(NULL, 0)
60133
.tp_name = "templatelib.Template",
61134
.tp_doc = PyDoc_STR("Template object"),
62135
.tp_basicsize = sizeof(templateobject),
63136
.tp_itemsize = 0,
64137
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | _Py_TPFLAGS_MATCH_SELF,
138+
.tp_as_number = &template_as_number,
65139
.tp_new = (newfunc) template_new,
66140
.tp_dealloc = (destructor) template_dealloc,
67141
.tp_repr = (reprfunc) template_repr,

0 commit comments

Comments
 (0)
0