@@ -199,6 +199,111 @@ def test_slots_binops(self):
199
199
)
200
200
assert [4 , 2 ] * TestSlotsBinop () == 42
201
201
202
+ def test_inheret_numbers_slots (self ):
203
+ X = CPyExtType ("X_" ,
204
+ '''
205
+ PyObject* test_add_impl(PyObject* a, PyObject* b) {
206
+ return PyLong_FromLong(42);
207
+ }
208
+
209
+ static PyNumberMethods A_number_methods = {
210
+ test_add_impl,
211
+ };
212
+
213
+ PyTypeObject A_Type = {
214
+ PyVarObject_HEAD_INIT(NULL, 0)
215
+ .tp_name = "A",
216
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
217
+ .tp_as_number = &A_number_methods,
218
+ };
219
+
220
+ PyTypeObject B_Type = {
221
+ PyVarObject_HEAD_INIT(NULL, 0)
222
+ .tp_name = "B",
223
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
224
+ .tp_base = &A_Type,
225
+ };
226
+
227
+ static PyObject* create_B(PyObject* cls) {
228
+ return (&B_Type)->tp_alloc(&B_Type, 0);
229
+ }
230
+
231
+ static PyObject* B_has_add_slot(PyObject* cls) {
232
+ return (&B_Type)->tp_as_number != NULL && (&B_Type)->tp_as_number->nb_add != NULL ? Py_True : Py_False;
233
+ }
234
+
235
+ ''' ,
236
+ tp_methods = '''{"create_B", (PyCFunction)create_B, METH_NOARGS | METH_CLASS, ""},
237
+ {"B_has_add_slot", (PyCFunction)B_has_add_slot, METH_NOARGS | METH_CLASS, ""}''' ,
238
+ ready_code = '''
239
+ if (PyType_Ready(&A_Type) < 0)
240
+ return NULL;
241
+
242
+ if (PyType_Ready(&B_Type) < 0)
243
+ return NULL;
244
+ ''' ,
245
+ )
246
+
247
+ Y = CPyExtType ("Y_" ,
248
+ '''
249
+ PyObject* test_C_add_impl(PyObject* a, PyObject* b) {
250
+ return PyLong_FromLong(4242);
251
+ }
252
+
253
+ static PyNumberMethods C_number_methods = {
254
+ test_C_add_impl,
255
+ };
256
+
257
+ PyTypeObject C_Type = {
258
+ PyVarObject_HEAD_INIT(NULL, 0)
259
+ .tp_name = "C",
260
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
261
+ .tp_as_number = &C_number_methods,
262
+ };
263
+
264
+ PyTypeObject D_Type = {
265
+ PyVarObject_HEAD_INIT(NULL, 0)
266
+ .tp_name = "D",
267
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
268
+ .tp_base = &C_Type,
269
+ };
270
+
271
+ PyTypeObject E_Type = {
272
+ PyVarObject_HEAD_INIT(NULL, 0)
273
+ .tp_name = "E",
274
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
275
+ .tp_base = &D_Type,
276
+ };
277
+
278
+ static PyObject* create_E(PyObject* cls) {
279
+ return (&E_Type)->tp_alloc(&E_Type, 0);
280
+ }
281
+
282
+ static PyObject* E_has_add_slot(PyObject* cls) {
283
+ return (&E_Type)->tp_as_number != NULL && (&E_Type)->tp_as_number->nb_add != NULL ? Py_True : Py_False;
284
+ }
285
+ ''' ,
286
+ tp_methods = '''{"create_E", (PyCFunction)create_E, METH_NOARGS | METH_CLASS, ""},
287
+ {"E_has_add_slot", (PyCFunction)E_has_add_slot, METH_NOARGS | METH_CLASS, ""}''' ,
288
+ ready_code = '''
289
+ if (PyType_Ready(&C_Type) < 0)
290
+ return NULL;
291
+
292
+ if (PyType_Ready(&D_Type) < 0)
293
+ return NULL;
294
+
295
+ if (PyType_Ready(&E_Type) < 0)
296
+ return NULL;
297
+ ''' ,
298
+ )
299
+ B = X .create_B ()
300
+ E = Y .create_E ()
301
+ assert B + E == 42
302
+ assert E + B == 4242
303
+ assert X .B_has_add_slot ()
304
+ assert Y .E_has_add_slot ()
305
+
306
+
202
307
def test_index (self ):
203
308
TestIndex = CPyExtType ("TestIndex" ,
204
309
"""
0 commit comments