22#include "Python.h"
33#include <stddef.h>
44
5+ #include "pycore_global_objects.h" // _Py_STR
6+ #include "pycore_runtime.h" // _Py_STR
7+
58#include "pycore_template.h"
9+ #include "pycore_interpolation.h"
610
711typedef struct {
812 PyObject_HEAD
@@ -17,16 +21,71 @@ template_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1721 return NULL ;
1822 }
1923
20- static char * kwlist [] = {"args" , NULL };
21- PyObject * selfargs ;
22-
23- if (PyArg_ParseTupleAndKeywords (args , kwds , "O" , kwlist ,
24- & selfargs ) < 0 ) {
25- Py_DECREF (self );
24+ Py_ssize_t argslen = PyTuple_GET_SIZE (args );
25+ Py_ssize_t interleaved_len = 0 ;
26+ int last_was_str = 0 ;
27+
28+ for (Py_ssize_t i = 0 ; i < argslen ; i ++ ) {
29+ PyObject * item = PyTuple_GET_ITEM (args , i );
30+ if (PyUnicode_Check (item )) {
31+ if (!last_was_str ) {
32+ interleaved_len ++ ;
33+ }
34+ last_was_str = 1 ;
35+ }
36+ else if (PyObject_TypeCheck (item , & _PyInterpolation_Type )) {
37+ if (!last_was_str ) {
38+ interleaved_len ++ ;
39+ }
40+ interleaved_len ++ ;
41+ last_was_str = 0 ;
42+ }
43+ else {
44+ PyErr_SetString (PyExc_TypeError , "Template items need to be of type 'str' or 'Interpolation'" );
45+ return NULL ;
46+ }
47+ }
48+ if (!last_was_str ) {
49+ interleaved_len ++ ;
50+ }
51+
52+ PyObject * interleaved = PyTuple_New (interleaved_len );
53+ if (!interleaved ) {
2654 return NULL ;
2755 }
2856
29- Py_XSETREF (self -> args , Py_NewRef (selfargs ));
57+ last_was_str = 0 ;
58+ Py_ssize_t j = 0 ;
59+ for (Py_ssize_t i = 0 ; i < argslen ; i ++ ) {
60+ PyObject * item = PyTuple_GET_ITEM (args , i );
61+ if (PyUnicode_Check (item )) {
62+ if (last_was_str ) {
63+ PyObject * concat = PyUnicode_Concat (PyTuple_GET_ITEM (interleaved , j - 1 ), item );
64+ if (!concat ) {
65+ Py_DECREF (interleaved );
66+ return NULL ;
67+ }
68+ PyTuple_SetItem (interleaved , j - 1 , concat );
69+ }
70+ else {
71+ PyTuple_SET_ITEM (interleaved , j ++ , Py_NewRef (item ));
72+ }
73+ last_was_str = 1 ;
74+ }
75+ else if (PyObject_TypeCheck (item , & _PyInterpolation_Type )) {
76+ if (!last_was_str ) {
77+ PyTuple_SET_ITEM (interleaved , j ++ , & _Py_STR (empty ));
78+ }
79+ PyTuple_SET_ITEM (interleaved , j ++ , Py_NewRef (item ));
80+ last_was_str = 0 ;
81+ }
82+ }
83+ if (!last_was_str ) {
84+ PyTuple_SET_ITEM (interleaved , j ++ , & _Py_STR (empty ));
85+ }
86+
87+ assert (j == interleaved_len );
88+ Py_XSETREF (self -> args , interleaved );
3089 return self ;
3190}
3291
@@ -59,6 +118,12 @@ template_compare(templateobject *self, PyObject *other, int op)
59118 return PyObject_RichCompare (self -> args , ((templateobject * ) other )-> args , op );
60119}
61120
121+ static Py_hash_t
122+ template_hash (templateobject * self )
123+ {
124+ return PyObject_Hash (self -> args );
125+ }
126+
62127static PyObject *
63128template_add_template_str (templateobject * template , PyUnicodeObject * str , int templateleft )
64129{
@@ -81,7 +146,7 @@ template_add_template_str(templateobject *template, PyUnicodeObject *str, int te
81146 PyTuple_SET_ITEM (tuple , i + j , Py_NewRef (str ));
82147 }
83148
84- PyObject * newtemplate = PyObject_CallOneArg ((PyObject * ) & _PyTemplate_Type , tuple );
149+ PyObject * newtemplate = PyObject_CallObject ((PyObject * ) & _PyTemplate_Type , tuple );
85150 Py_DECREF (tuple );
86151 return newtemplate ;
87152}
@@ -105,7 +170,7 @@ template_add_templates(templateobject *self, templateobject *other)
105170 PyTuple_SET_ITEM (tuple , i + j , Py_NewRef (PyTuple_GET_ITEM (other -> args , j )));
106171 }
107172
108- PyObject * newtemplate = PyObject_CallOneArg ((PyObject * ) & _PyTemplate_Type , tuple );
173+ PyObject * newtemplate = PyObject_CallObject ((PyObject * ) & _PyTemplate_Type , tuple );
109174 Py_DECREF (tuple );
110175 return newtemplate ;
111176}
@@ -149,6 +214,7 @@ PyTypeObject _PyTemplate_Type = {
149214 .tp_dealloc = (destructor ) template_dealloc ,
150215 .tp_repr = (reprfunc ) template_repr ,
151216 .tp_richcompare = (richcmpfunc ) template_compare ,
217+ .tp_hash = (hashfunc ) template_hash ,
152218 .tp_members = template_members ,
153219};
154220
@@ -164,7 +230,7 @@ _PyTemplate_Create(PyObject **values, Py_ssize_t oparg)
164230 PyTuple_SET_ITEM (tuple , i , Py_NewRef (values [i ]));
165231 }
166232
167- PyObject * template = PyObject_CallOneArg ((PyObject * ) & _PyTemplate_Type , tuple );
233+ PyObject * template = PyObject_CallObject ((PyObject * ) & _PyTemplate_Type , tuple );
168234 Py_DECREF (tuple );
169235 return template ;
170236}
0 commit comments