@@ -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+
53122static 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+
58131PyTypeObject _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