@@ -50,18 +50,92 @@ template_repr(templateobject *self)
50
50
self -> args );
51
51
}
52
52
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
+
53
122
static PyMemberDef template_members [] = {
54
123
{"args" , Py_T_OBJECT_EX , offsetof(templateobject , args ), Py_READONLY , "Args" },
55
124
{NULL }
56
125
};
57
126
127
+ static PyNumberMethods template_as_number = {
128
+ .nb_add = template_add
129
+ };
130
+
58
131
PyTypeObject _PyTemplate_Type = {
59
132
PyVarObject_HEAD_INIT (NULL , 0 )
60
133
.tp_name = "templatelib.Template" ,
61
134
.tp_doc = PyDoc_STR ("Template object" ),
62
135
.tp_basicsize = sizeof (templateobject ),
63
136
.tp_itemsize = 0 ,
64
137
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | _Py_TPFLAGS_MATCH_SELF ,
138
+ .tp_as_number = & template_as_number ,
65
139
.tp_new = (newfunc ) template_new ,
66
140
.tp_dealloc = (destructor ) template_dealloc ,
67
141
.tp_repr = (reprfunc ) template_repr ,
0 commit comments