Branch data Line data Source code
1 : : #include "parts.h"
2 : : #include "structmember.h" // PyMemberDef
3 : :
4 : : static struct PyModuleDef *_testcapimodule = NULL; // set at initialization
5 : :
6 : : /* Tests for heap types (PyType_From*) */
7 : :
8 : 0 : static PyObject *pytype_fromspec_meta(PyObject* self, PyObject *meta)
9 : : {
10 [ # # ]: 0 : if (!PyType_Check(meta)) {
11 : 0 : PyErr_SetString(
12 : : PyExc_TypeError,
13 : : "pytype_fromspec_meta: must be invoked with a type argument!");
14 : 0 : return NULL;
15 : : }
16 : :
17 : 0 : PyType_Slot HeapCTypeViaMetaclass_slots[] = {
18 : : {0},
19 : : };
20 : :
21 : 0 : PyType_Spec HeapCTypeViaMetaclass_spec = {
22 : : "_testcapi.HeapCTypeViaMetaclass",
23 : : sizeof(PyObject),
24 : : 0,
25 : : Py_TPFLAGS_DEFAULT,
26 : : HeapCTypeViaMetaclass_slots
27 : : };
28 : :
29 : 0 : return PyType_FromMetaclass(
30 : : (PyTypeObject *) meta, NULL, &HeapCTypeViaMetaclass_spec, NULL);
31 : : }
32 : :
33 : :
34 : : static PyType_Slot empty_type_slots[] = {
35 : : {0, 0},
36 : : };
37 : :
38 : : static PyType_Spec MinimalMetaclass_spec = {
39 : : .name = "_testcapi.MinimalMetaclass",
40 : : .basicsize = sizeof(PyHeapTypeObject),
41 : : .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
42 : : .slots = empty_type_slots,
43 : : };
44 : :
45 : : static PyType_Spec MinimalType_spec = {
46 : : .name = "_testcapi.MinimalSpecType",
47 : : .basicsize = 0, // Updated later
48 : : .flags = Py_TPFLAGS_DEFAULT,
49 : : .slots = empty_type_slots,
50 : : };
51 : :
52 : :
53 : : static PyObject *
54 : 0 : test_from_spec_metatype_inheritance(PyObject *self, PyObject *Py_UNUSED(ignored))
55 : : {
56 : 0 : PyObject *metaclass = NULL;
57 : 0 : PyObject *class = NULL;
58 : 0 : PyObject *new = NULL;
59 : 0 : PyObject *subclasses = NULL;
60 : 0 : PyObject *result = NULL;
61 : : int r;
62 : :
63 : 0 : metaclass = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type);
64 [ # # ]: 0 : if (metaclass == NULL) {
65 : 0 : goto finally;
66 : : }
67 : 0 : class = PyObject_CallFunction(metaclass, "s(){}", "TestClass");
68 [ # # ]: 0 : if (class == NULL) {
69 : 0 : goto finally;
70 : : }
71 : :
72 : 0 : MinimalType_spec.basicsize = (int)(((PyTypeObject*)class)->tp_basicsize);
73 : 0 : new = PyType_FromSpecWithBases(&MinimalType_spec, class);
74 [ # # ]: 0 : if (new == NULL) {
75 : 0 : goto finally;
76 : : }
77 [ # # ]: 0 : if (Py_TYPE(new) != (PyTypeObject*)metaclass) {
78 : 0 : PyErr_SetString(PyExc_AssertionError,
79 : : "Metaclass not set properly!");
80 : 0 : goto finally;
81 : : }
82 : :
83 : : /* Assert that __subclasses__ is updated */
84 : 0 : subclasses = PyObject_CallMethod(class, "__subclasses__", "");
85 [ # # ]: 0 : if (!subclasses) {
86 : 0 : goto finally;
87 : : }
88 : 0 : r = PySequence_Contains(subclasses, new);
89 [ # # ]: 0 : if (r < 0) {
90 : 0 : goto finally;
91 : : }
92 [ # # ]: 0 : if (r == 0) {
93 : 0 : PyErr_SetString(PyExc_AssertionError,
94 : : "subclasses not set properly!");
95 : 0 : goto finally;
96 : : }
97 : :
98 : 0 : result = Py_NewRef(Py_None);
99 : :
100 : 0 : finally:
101 : 0 : Py_XDECREF(metaclass);
102 : 0 : Py_XDECREF(class);
103 : 0 : Py_XDECREF(new);
104 : 0 : Py_XDECREF(subclasses);
105 : 0 : return result;
106 : : }
107 : :
108 : :
109 : : static PyObject *
110 : 0 : test_from_spec_invalid_metatype_inheritance(PyObject *self, PyObject *Py_UNUSED(ignored))
111 : : {
112 : 0 : PyObject *metaclass_a = NULL;
113 : 0 : PyObject *metaclass_b = NULL;
114 : 0 : PyObject *class_a = NULL;
115 : 0 : PyObject *class_b = NULL;
116 : 0 : PyObject *bases = NULL;
117 : 0 : PyObject *new = NULL;
118 : 0 : PyObject *meta_error_string = NULL;
119 : 0 : PyObject *exc = NULL;
120 : 0 : PyObject *result = NULL;
121 : 0 : PyObject *message = NULL;
122 : 0 : PyObject *args = NULL;
123 : :
124 : 0 : metaclass_a = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type);
125 [ # # ]: 0 : if (metaclass_a == NULL) {
126 : 0 : goto finally;
127 : : }
128 : 0 : metaclass_b = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type);
129 [ # # ]: 0 : if (metaclass_b == NULL) {
130 : 0 : goto finally;
131 : : }
132 : 0 : class_a = PyObject_CallFunction(metaclass_a, "s(){}", "TestClassA");
133 [ # # ]: 0 : if (class_a == NULL) {
134 : 0 : goto finally;
135 : : }
136 : :
137 : 0 : class_b = PyObject_CallFunction(metaclass_b, "s(){}", "TestClassB");
138 [ # # ]: 0 : if (class_b == NULL) {
139 : 0 : goto finally;
140 : : }
141 : :
142 : 0 : bases = PyTuple_Pack(2, class_a, class_b);
143 [ # # ]: 0 : if (bases == NULL) {
144 : 0 : goto finally;
145 : : }
146 : :
147 : : /*
148 : : * The following should raise a TypeError due to a MetaClass conflict.
149 : : */
150 : 0 : new = PyType_FromSpecWithBases(&MinimalType_spec, bases);
151 [ # # ]: 0 : if (new != NULL) {
152 : 0 : PyErr_SetString(PyExc_AssertionError,
153 : : "MetaType conflict not recognized by PyType_FromSpecWithBases");
154 : 0 : goto finally;
155 : : }
156 : :
157 : : // Assert that the correct exception was raised
158 [ # # ]: 0 : if (PyErr_ExceptionMatches(PyExc_TypeError)) {
159 : 0 : exc = PyErr_GetRaisedException();
160 : 0 : args = PyException_GetArgs(exc);
161 [ # # # # ]: 0 : if (!PyTuple_Check(args) || PyTuple_Size(args) != 1) {
162 : 0 : PyErr_SetString(PyExc_AssertionError,
163 : : "TypeError args are not a one-tuple");
164 : 0 : goto finally;
165 : : }
166 [ # # ]: 0 : message = Py_NewRef(PyTuple_GET_ITEM(args, 0));
167 : 0 : meta_error_string = PyUnicode_FromString("metaclass conflict:");
168 [ # # ]: 0 : if (meta_error_string == NULL) {
169 : 0 : goto finally;
170 : : }
171 : 0 : int res = PyUnicode_Contains(message, meta_error_string);
172 [ # # ]: 0 : if (res < 0) {
173 : 0 : goto finally;
174 : : }
175 [ # # ]: 0 : if (res == 0) {
176 : 0 : PyErr_SetString(PyExc_AssertionError,
177 : : "TypeError did not inlclude expected message.");
178 : 0 : goto finally;
179 : : }
180 : 0 : result = Py_NewRef(Py_None);
181 : : }
182 : 0 : finally:
183 : 0 : Py_XDECREF(metaclass_a);
184 : 0 : Py_XDECREF(metaclass_b);
185 : 0 : Py_XDECREF(bases);
186 : 0 : Py_XDECREF(new);
187 : 0 : Py_XDECREF(meta_error_string);
188 : 0 : Py_XDECREF(exc);
189 : 0 : Py_XDECREF(message);
190 : 0 : Py_XDECREF(class_a);
191 : 0 : Py_XDECREF(class_b);
192 : 0 : Py_XDECREF(args);
193 : 0 : return result;
194 : : }
195 : :
196 : :
197 : : static PyObject *
198 : 0 : simple_str(PyObject *self) {
199 : 0 : return PyUnicode_FromString("<test>");
200 : : }
201 : :
202 : :
203 : : static PyObject *
204 : 0 : test_type_from_ephemeral_spec(PyObject *self, PyObject *Py_UNUSED(ignored))
205 : : {
206 : : // Test that a heap type can be created from a spec that's later deleted
207 : : // (along with all its contents).
208 : : // All necessary data must be copied and held by the class
209 : 0 : PyType_Spec *spec = NULL;
210 : 0 : char *name = NULL;
211 : 0 : char *doc = NULL;
212 : 0 : PyType_Slot *slots = NULL;
213 : 0 : PyObject *class = NULL;
214 : 0 : PyObject *instance = NULL;
215 : 0 : PyObject *obj = NULL;
216 : 0 : PyObject *result = NULL;
217 : :
218 : : /* create a spec (and all its contents) on the heap */
219 : :
220 : 0 : const char NAME[] = "testcapi._Test";
221 : 0 : const char DOC[] = "a test class";
222 : :
223 : 0 : spec = PyMem_New(PyType_Spec, 1);
224 [ # # ]: 0 : if (spec == NULL) {
225 : 0 : PyErr_NoMemory();
226 : 0 : goto finally;
227 : : }
228 : 0 : name = PyMem_New(char, sizeof(NAME));
229 [ # # ]: 0 : if (name == NULL) {
230 : 0 : PyErr_NoMemory();
231 : 0 : goto finally;
232 : : }
233 : 0 : memcpy(name, NAME, sizeof(NAME));
234 : :
235 : 0 : doc = PyMem_New(char, sizeof(DOC));
236 [ # # ]: 0 : if (doc == NULL) {
237 : 0 : PyErr_NoMemory();
238 : 0 : goto finally;
239 : : }
240 : 0 : memcpy(doc, DOC, sizeof(DOC));
241 : :
242 : 0 : spec->name = name;
243 : 0 : spec->basicsize = sizeof(PyObject);
244 : 0 : spec->itemsize = 0;
245 : 0 : spec->flags = Py_TPFLAGS_DEFAULT;
246 : 0 : slots = PyMem_New(PyType_Slot, 3);
247 [ # # ]: 0 : if (slots == NULL) {
248 : 0 : PyErr_NoMemory();
249 : 0 : goto finally;
250 : : }
251 : 0 : slots[0].slot = Py_tp_str;
252 : 0 : slots[0].pfunc = simple_str;
253 : 0 : slots[1].slot = Py_tp_doc;
254 : 0 : slots[1].pfunc = doc;
255 : 0 : slots[2].slot = 0;
256 : 0 : slots[2].pfunc = NULL;
257 : 0 : spec->slots = slots;
258 : :
259 : : /* create the class */
260 : :
261 : 0 : class = PyType_FromSpec(spec);
262 [ # # ]: 0 : if (class == NULL) {
263 : 0 : goto finally;
264 : : }
265 : :
266 : : /* deallocate the spec (and all contents) */
267 : :
268 : : // (Explicitly ovewrite memory before freeing,
269 : : // so bugs show themselves even without the debug allocator's help.)
270 : 0 : memset(spec, 0xdd, sizeof(PyType_Spec));
271 : 0 : PyMem_Del(spec);
272 : 0 : spec = NULL;
273 : 0 : memset(name, 0xdd, sizeof(NAME));
274 : 0 : PyMem_Del(name);
275 : 0 : name = NULL;
276 : 0 : memset(doc, 0xdd, sizeof(DOC));
277 : 0 : PyMem_Del(doc);
278 : 0 : doc = NULL;
279 : 0 : memset(slots, 0xdd, 3 * sizeof(PyType_Slot));
280 : 0 : PyMem_Del(slots);
281 : 0 : slots = NULL;
282 : :
283 : : /* check that everything works */
284 : :
285 : 0 : PyTypeObject *class_tp = (PyTypeObject *)class;
286 : 0 : PyHeapTypeObject *class_ht = (PyHeapTypeObject *)class;
287 [ # # ]: 0 : assert(strcmp(class_tp->tp_name, "testcapi._Test") == 0);
288 [ # # ]: 0 : assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_name), "_Test") == 0);
289 [ # # ]: 0 : assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_qualname), "_Test") == 0);
290 [ # # ]: 0 : assert(strcmp(class_tp->tp_doc, "a test class") == 0);
291 : :
292 : : // call and check __str__
293 : 0 : instance = PyObject_CallNoArgs(class);
294 [ # # ]: 0 : if (instance == NULL) {
295 : 0 : goto finally;
296 : : }
297 : 0 : obj = PyObject_Str(instance);
298 [ # # ]: 0 : if (obj == NULL) {
299 : 0 : goto finally;
300 : : }
301 [ # # ]: 0 : assert(strcmp(PyUnicode_AsUTF8(obj), "<test>") == 0);
302 [ # # ]: 0 : Py_CLEAR(obj);
303 : :
304 : 0 : result = Py_NewRef(Py_None);
305 : 0 : finally:
306 : 0 : PyMem_Del(spec);
307 : 0 : PyMem_Del(name);
308 : 0 : PyMem_Del(doc);
309 : 0 : PyMem_Del(slots);
310 : 0 : Py_XDECREF(class);
311 : 0 : Py_XDECREF(instance);
312 : 0 : Py_XDECREF(obj);
313 : 0 : return result;
314 : : }
315 : :
316 : : PyType_Slot repeated_doc_slots[] = {
317 : : {Py_tp_doc, "A class used for testsĀ·"},
318 : : {Py_tp_doc, "A class used for tests"},
319 : : {0, 0},
320 : : };
321 : :
322 : : PyType_Spec repeated_doc_slots_spec = {
323 : : .name = "RepeatedDocSlotClass",
324 : : .basicsize = sizeof(PyObject),
325 : : .slots = repeated_doc_slots,
326 : : };
327 : :
328 : : typedef struct {
329 : : PyObject_HEAD
330 : : int data;
331 : : } HeapCTypeWithDataObject;
332 : :
333 : :
334 : : static struct PyMemberDef members_to_repeat[] = {
335 : : {"T_INT", T_INT, offsetof(HeapCTypeWithDataObject, data), 0, NULL},
336 : : {NULL}
337 : : };
338 : :
339 : : PyType_Slot repeated_members_slots[] = {
340 : : {Py_tp_members, members_to_repeat},
341 : : {Py_tp_members, members_to_repeat},
342 : : {0, 0},
343 : : };
344 : :
345 : : PyType_Spec repeated_members_slots_spec = {
346 : : .name = "RepeatedMembersSlotClass",
347 : : .basicsize = sizeof(HeapCTypeWithDataObject),
348 : : .slots = repeated_members_slots,
349 : : };
350 : :
351 : : static PyObject *
352 : 0 : create_type_from_repeated_slots(PyObject *self, PyObject *variant_obj)
353 : : {
354 : 0 : PyObject *class = NULL;
355 : 0 : int variant = PyLong_AsLong(variant_obj);
356 [ # # ]: 0 : if (PyErr_Occurred()) {
357 : 0 : return NULL;
358 : : }
359 [ # # # ]: 0 : switch (variant) {
360 : 0 : case 0:
361 : 0 : class = PyType_FromSpec(&repeated_doc_slots_spec);
362 : 0 : break;
363 : 0 : case 1:
364 : 0 : class = PyType_FromSpec(&repeated_members_slots_spec);
365 : 0 : break;
366 : 0 : default:
367 : 0 : PyErr_SetString(PyExc_ValueError, "bad test variant");
368 : 0 : break;
369 : : }
370 : 0 : return class;
371 : : }
372 : :
373 : :
374 : :
375 : : static PyObject *
376 : 0 : make_immutable_type_with_base(PyObject *self, PyObject *base)
377 : : {
378 [ # # ]: 0 : assert(PyType_Check(base));
379 : 0 : PyType_Spec ImmutableSubclass_spec = {
380 : : .name = "ImmutableSubclass",
381 : 0 : .basicsize = (int)((PyTypeObject*)base)->tp_basicsize,
382 : : .slots = empty_type_slots,
383 : : .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE,
384 : : };
385 : 0 : return PyType_FromSpecWithBases(&ImmutableSubclass_spec, base);
386 : : }
387 : :
388 : :
389 : : static PyMethodDef TestMethods[] = {
390 : : {"pytype_fromspec_meta", pytype_fromspec_meta, METH_O},
391 : : {"test_type_from_ephemeral_spec", test_type_from_ephemeral_spec, METH_NOARGS},
392 : : {"create_type_from_repeated_slots",
393 : : create_type_from_repeated_slots, METH_O},
394 : : {"test_from_spec_metatype_inheritance", test_from_spec_metatype_inheritance,
395 : : METH_NOARGS},
396 : : {"test_from_spec_invalid_metatype_inheritance",
397 : : test_from_spec_invalid_metatype_inheritance,
398 : : METH_NOARGS},
399 : : {"make_immutable_type_with_base", make_immutable_type_with_base, METH_O},
400 : : {NULL},
401 : : };
402 : :
403 : :
404 : : PyDoc_STRVAR(heapdocctype__doc__,
405 : : "HeapDocCType(arg1, arg2)\n"
406 : : "--\n"
407 : : "\n"
408 : : "somedoc");
409 : :
410 : : typedef struct {
411 : : PyObject_HEAD
412 : : } HeapDocCTypeObject;
413 : :
414 : : static PyType_Slot HeapDocCType_slots[] = {
415 : : {Py_tp_doc, (char*)heapdocctype__doc__},
416 : : {0},
417 : : };
418 : :
419 : : static PyType_Spec HeapDocCType_spec = {
420 : : "_testcapi.HeapDocCType",
421 : : sizeof(HeapDocCTypeObject),
422 : : 0,
423 : : Py_TPFLAGS_DEFAULT,
424 : : HeapDocCType_slots
425 : : };
426 : :
427 : : typedef struct {
428 : : PyObject_HEAD
429 : : } NullTpDocTypeObject;
430 : :
431 : : static PyType_Slot NullTpDocType_slots[] = {
432 : : {Py_tp_doc, NULL},
433 : : {0, 0},
434 : : };
435 : :
436 : : static PyType_Spec NullTpDocType_spec = {
437 : : "_testcapi.NullTpDocType",
438 : : sizeof(NullTpDocTypeObject),
439 : : 0,
440 : : Py_TPFLAGS_DEFAULT,
441 : : NullTpDocType_slots
442 : : };
443 : :
444 : :
445 : : PyDoc_STRVAR(heapgctype__doc__,
446 : : "A heap type with GC, and with overridden dealloc.\n\n"
447 : : "The 'value' attribute is set to 10 in __init__.");
448 : :
449 : : typedef struct {
450 : : PyObject_HEAD
451 : : int value;
452 : : } HeapCTypeObject;
453 : :
454 : : static struct PyMemberDef heapctype_members[] = {
455 : : {"value", T_INT, offsetof(HeapCTypeObject, value)},
456 : : {NULL} /* Sentinel */
457 : : };
458 : :
459 : : static int
460 : 0 : heapctype_init(PyObject *self, PyObject *args, PyObject *kwargs)
461 : : {
462 : 0 : ((HeapCTypeObject *)self)->value = 10;
463 : 0 : return 0;
464 : : }
465 : :
466 : : static int
467 : 0 : heapgcctype_traverse(HeapCTypeObject *self, visitproc visit, void *arg)
468 : : {
469 [ # # # # ]: 0 : Py_VISIT(Py_TYPE(self));
470 : 0 : return 0;
471 : : }
472 : :
473 : : static void
474 : 0 : heapgcctype_dealloc(HeapCTypeObject *self)
475 : : {
476 : 0 : PyTypeObject *tp = Py_TYPE(self);
477 : 0 : PyObject_GC_UnTrack(self);
478 : 0 : PyObject_GC_Del(self);
479 : 0 : Py_DECREF(tp);
480 : 0 : }
481 : :
482 : : static PyType_Slot HeapGcCType_slots[] = {
483 : : {Py_tp_init, heapctype_init},
484 : : {Py_tp_members, heapctype_members},
485 : : {Py_tp_dealloc, heapgcctype_dealloc},
486 : : {Py_tp_traverse, heapgcctype_traverse},
487 : : {Py_tp_doc, (char*)heapgctype__doc__},
488 : : {0, 0},
489 : : };
490 : :
491 : : static PyType_Spec HeapGcCType_spec = {
492 : : "_testcapi.HeapGcCType",
493 : : sizeof(HeapCTypeObject),
494 : : 0,
495 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
496 : : HeapGcCType_slots
497 : : };
498 : :
499 : : PyDoc_STRVAR(heapctype__doc__,
500 : : "A heap type without GC, but with overridden dealloc.\n\n"
501 : : "The 'value' attribute is set to 10 in __init__.");
502 : :
503 : : static void
504 : 0 : heapctype_dealloc(HeapCTypeObject *self)
505 : : {
506 : 0 : PyTypeObject *tp = Py_TYPE(self);
507 : 0 : PyObject_Free(self);
508 : 0 : Py_DECREF(tp);
509 : 0 : }
510 : :
511 : : static PyType_Slot HeapCType_slots[] = {
512 : : {Py_tp_init, heapctype_init},
513 : : {Py_tp_members, heapctype_members},
514 : : {Py_tp_dealloc, heapctype_dealloc},
515 : : {Py_tp_doc, (char*)heapctype__doc__},
516 : : {0, 0},
517 : : };
518 : :
519 : : static PyType_Spec HeapCType_spec = {
520 : : "_testcapi.HeapCType",
521 : : sizeof(HeapCTypeObject),
522 : : 0,
523 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
524 : : HeapCType_slots
525 : : };
526 : :
527 : : PyDoc_STRVAR(heapctypesubclass__doc__,
528 : : "Subclass of HeapCType, without GC.\n\n"
529 : : "__init__ sets the 'value' attribute to 10 and 'value2' to 20.");
530 : :
531 : : typedef struct {
532 : : HeapCTypeObject base;
533 : : int value2;
534 : : } HeapCTypeSubclassObject;
535 : :
536 : : static int
537 : 0 : heapctypesubclass_init(PyObject *self, PyObject *args, PyObject *kwargs)
538 : : {
539 : : /* Call __init__ of the superclass */
540 [ # # ]: 0 : if (heapctype_init(self, args, kwargs) < 0) {
541 : 0 : return -1;
542 : : }
543 : : /* Initialize additional element */
544 : 0 : ((HeapCTypeSubclassObject *)self)->value2 = 20;
545 : 0 : return 0;
546 : : }
547 : :
548 : : static struct PyMemberDef heapctypesubclass_members[] = {
549 : : {"value2", T_INT, offsetof(HeapCTypeSubclassObject, value2)},
550 : : {NULL} /* Sentinel */
551 : : };
552 : :
553 : : static PyType_Slot HeapCTypeSubclass_slots[] = {
554 : : {Py_tp_init, heapctypesubclass_init},
555 : : {Py_tp_members, heapctypesubclass_members},
556 : : {Py_tp_doc, (char*)heapctypesubclass__doc__},
557 : : {0, 0},
558 : : };
559 : :
560 : : static PyType_Spec HeapCTypeSubclass_spec = {
561 : : "_testcapi.HeapCTypeSubclass",
562 : : sizeof(HeapCTypeSubclassObject),
563 : : 0,
564 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
565 : : HeapCTypeSubclass_slots
566 : : };
567 : :
568 : : PyDoc_STRVAR(heapctypewithbuffer__doc__,
569 : : "Heap type with buffer support.\n\n"
570 : : "The buffer is set to [b'1', b'2', b'3', b'4']");
571 : :
572 : : typedef struct {
573 : : HeapCTypeObject base;
574 : : char buffer[4];
575 : : } HeapCTypeWithBufferObject;
576 : :
577 : : static int
578 : 0 : heapctypewithbuffer_getbuffer(HeapCTypeWithBufferObject *self, Py_buffer *view, int flags)
579 : : {
580 : 0 : self->buffer[0] = '1';
581 : 0 : self->buffer[1] = '2';
582 : 0 : self->buffer[2] = '3';
583 : 0 : self->buffer[3] = '4';
584 : 0 : return PyBuffer_FillInfo(
585 : 0 : view, (PyObject*)self, (void *)self->buffer, 4, 1, flags);
586 : : }
587 : :
588 : : static void
589 : 0 : heapctypewithbuffer_releasebuffer(HeapCTypeWithBufferObject *self, Py_buffer *view)
590 : : {
591 [ # # ]: 0 : assert(view->obj == (void*) self);
592 : 0 : }
593 : :
594 : : static PyType_Slot HeapCTypeWithBuffer_slots[] = {
595 : : {Py_bf_getbuffer, heapctypewithbuffer_getbuffer},
596 : : {Py_bf_releasebuffer, heapctypewithbuffer_releasebuffer},
597 : : {Py_tp_doc, (char*)heapctypewithbuffer__doc__},
598 : : {0, 0},
599 : : };
600 : :
601 : : static PyType_Spec HeapCTypeWithBuffer_spec = {
602 : : "_testcapi.HeapCTypeWithBuffer",
603 : : sizeof(HeapCTypeWithBufferObject),
604 : : 0,
605 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
606 : : HeapCTypeWithBuffer_slots
607 : : };
608 : :
609 : : PyDoc_STRVAR(heapctypesubclasswithfinalizer__doc__,
610 : : "Subclass of HeapCType with a finalizer that reassigns __class__.\n\n"
611 : : "__class__ is set to plain HeapCTypeSubclass during finalization.\n"
612 : : "__init__ sets the 'value' attribute to 10 and 'value2' to 20.");
613 : :
614 : : static int
615 : 0 : heapctypesubclasswithfinalizer_init(PyObject *self, PyObject *args, PyObject *kwargs)
616 : : {
617 : 0 : PyTypeObject *base = (PyTypeObject *)PyType_GetSlot(Py_TYPE(self), Py_tp_base);
618 : 0 : initproc base_init = PyType_GetSlot(base, Py_tp_init);
619 : 0 : base_init(self, args, kwargs);
620 : 0 : return 0;
621 : : }
622 : :
623 : : static void
624 : 0 : heapctypesubclasswithfinalizer_finalize(PyObject *self)
625 : : {
626 : 0 : PyObject *oldtype = NULL, *newtype = NULL, *refcnt = NULL;
627 : :
628 : : /* Save the current exception, if any. */
629 : 0 : PyObject *exc = PyErr_GetRaisedException();
630 : :
631 [ # # ]: 0 : if (_testcapimodule == NULL) {
632 : 0 : goto cleanup_finalize;
633 : : }
634 : 0 : PyObject *m = PyState_FindModule(_testcapimodule);
635 [ # # ]: 0 : if (m == NULL) {
636 : 0 : goto cleanup_finalize;
637 : : }
638 : 0 : oldtype = PyObject_GetAttrString(m, "HeapCTypeSubclassWithFinalizer");
639 : 0 : newtype = PyObject_GetAttrString(m, "HeapCTypeSubclass");
640 [ # # # # ]: 0 : if (oldtype == NULL || newtype == NULL) {
641 : 0 : goto cleanup_finalize;
642 : : }
643 : :
644 [ # # ]: 0 : if (PyObject_SetAttrString(self, "__class__", newtype) < 0) {
645 : 0 : goto cleanup_finalize;
646 : : }
647 : 0 : refcnt = PyLong_FromSsize_t(Py_REFCNT(oldtype));
648 [ # # ]: 0 : if (refcnt == NULL) {
649 : 0 : goto cleanup_finalize;
650 : : }
651 [ # # ]: 0 : if (PyObject_SetAttrString(oldtype, "refcnt_in_del", refcnt) < 0) {
652 : 0 : goto cleanup_finalize;
653 : : }
654 : 0 : Py_DECREF(refcnt);
655 : 0 : refcnt = PyLong_FromSsize_t(Py_REFCNT(newtype));
656 [ # # ]: 0 : if (refcnt == NULL) {
657 : 0 : goto cleanup_finalize;
658 : : }
659 [ # # ]: 0 : if (PyObject_SetAttrString(newtype, "refcnt_in_del", refcnt) < 0) {
660 : 0 : goto cleanup_finalize;
661 : : }
662 : :
663 : 0 : cleanup_finalize:
664 : 0 : Py_XDECREF(oldtype);
665 : 0 : Py_XDECREF(newtype);
666 : 0 : Py_XDECREF(refcnt);
667 : :
668 : : /* Restore the saved exception. */
669 : 0 : PyErr_SetRaisedException(exc);
670 : 0 : }
671 : :
672 : : static PyType_Slot HeapCTypeSubclassWithFinalizer_slots[] = {
673 : : {Py_tp_init, heapctypesubclasswithfinalizer_init},
674 : : {Py_tp_members, heapctypesubclass_members},
675 : : {Py_tp_finalize, heapctypesubclasswithfinalizer_finalize},
676 : : {Py_tp_doc, (char*)heapctypesubclasswithfinalizer__doc__},
677 : : {0, 0},
678 : : };
679 : :
680 : : static PyType_Spec HeapCTypeSubclassWithFinalizer_spec = {
681 : : "_testcapi.HeapCTypeSubclassWithFinalizer",
682 : : sizeof(HeapCTypeSubclassObject),
683 : : 0,
684 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
685 : : HeapCTypeSubclassWithFinalizer_slots
686 : : };
687 : :
688 : : static PyType_Slot HeapCTypeMetaclass_slots[] = {
689 : : {0},
690 : : };
691 : :
692 : : static PyType_Spec HeapCTypeMetaclass_spec = {
693 : : "_testcapi.HeapCTypeMetaclass",
694 : : sizeof(PyHeapTypeObject),
695 : : sizeof(PyMemberDef),
696 : : Py_TPFLAGS_DEFAULT,
697 : : HeapCTypeMetaclass_slots
698 : : };
699 : :
700 : : static PyObject *
701 : 0 : heap_ctype_metaclass_custom_tp_new(PyTypeObject *tp, PyObject *args, PyObject *kwargs)
702 : : {
703 : 0 : return PyType_Type.tp_new(tp, args, kwargs);
704 : : }
705 : :
706 : : static PyType_Slot HeapCTypeMetaclassCustomNew_slots[] = {
707 : : { Py_tp_new, heap_ctype_metaclass_custom_tp_new },
708 : : {0},
709 : : };
710 : :
711 : : static PyType_Spec HeapCTypeMetaclassCustomNew_spec = {
712 : : "_testcapi.HeapCTypeMetaclassCustomNew",
713 : : sizeof(PyHeapTypeObject),
714 : : sizeof(PyMemberDef),
715 : : Py_TPFLAGS_DEFAULT,
716 : : HeapCTypeMetaclassCustomNew_slots
717 : : };
718 : :
719 : :
720 : : typedef struct {
721 : : PyObject_HEAD
722 : : PyObject *dict;
723 : : } HeapCTypeWithDictObject;
724 : :
725 : : static void
726 : 0 : heapctypewithdict_dealloc(HeapCTypeWithDictObject* self)
727 : : {
728 : :
729 : 0 : PyTypeObject *tp = Py_TYPE(self);
730 : 0 : Py_XDECREF(self->dict);
731 : 0 : PyObject_Free(self);
732 : 0 : Py_DECREF(tp);
733 : 0 : }
734 : :
735 : : static PyGetSetDef heapctypewithdict_getsetlist[] = {
736 : : {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
737 : : {NULL} /* Sentinel */
738 : : };
739 : :
740 : : static struct PyMemberDef heapctypewithdict_members[] = {
741 : : {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)},
742 : : {"__dictoffset__", T_PYSSIZET, offsetof(HeapCTypeWithDictObject, dict), READONLY},
743 : : {NULL} /* Sentinel */
744 : : };
745 : :
746 : : static PyType_Slot HeapCTypeWithDict_slots[] = {
747 : : {Py_tp_members, heapctypewithdict_members},
748 : : {Py_tp_getset, heapctypewithdict_getsetlist},
749 : : {Py_tp_dealloc, heapctypewithdict_dealloc},
750 : : {0, 0},
751 : : };
752 : :
753 : : static PyType_Spec HeapCTypeWithDict_spec = {
754 : : "_testcapi.HeapCTypeWithDict",
755 : : sizeof(HeapCTypeWithDictObject),
756 : : 0,
757 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
758 : : HeapCTypeWithDict_slots
759 : : };
760 : :
761 : : static PyType_Spec HeapCTypeWithDict2_spec = {
762 : : "_testcapi.HeapCTypeWithDict2",
763 : : sizeof(HeapCTypeWithDictObject),
764 : : 0,
765 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
766 : : HeapCTypeWithDict_slots
767 : : };
768 : :
769 : : static int
770 : 0 : heapmanaged_traverse(HeapCTypeObject *self, visitproc visit, void *arg)
771 : : {
772 [ # # # # ]: 0 : Py_VISIT(Py_TYPE(self));
773 : 0 : return _PyObject_VisitManagedDict((PyObject *)self, visit, arg);
774 : : }
775 : :
776 : : static int
777 : 0 : heapmanaged_clear(HeapCTypeObject *self)
778 : : {
779 : 0 : _PyObject_ClearManagedDict((PyObject *)self);
780 : 0 : return 0;
781 : : }
782 : :
783 : : static void
784 : 0 : heapmanaged_dealloc(HeapCTypeObject *self)
785 : : {
786 : 0 : PyTypeObject *tp = Py_TYPE(self);
787 : 0 : _PyObject_ClearManagedDict((PyObject *)self);
788 : 0 : PyObject_GC_UnTrack(self);
789 : 0 : PyObject_GC_Del(self);
790 : 0 : Py_DECREF(tp);
791 : 0 : }
792 : :
793 : : static PyType_Slot HeapCTypeWithManagedDict_slots[] = {
794 : : {Py_tp_traverse, heapmanaged_traverse},
795 : : {Py_tp_getset, heapctypewithdict_getsetlist},
796 : : {Py_tp_clear, heapmanaged_clear},
797 : : {Py_tp_dealloc, heapmanaged_dealloc},
798 : : {0, 0},
799 : : };
800 : :
801 : : static PyType_Spec HeapCTypeWithManagedDict_spec = {
802 : : "_testcapi.HeapCTypeWithManagedDict",
803 : : sizeof(PyObject),
804 : : 0,
805 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT,
806 : : HeapCTypeWithManagedDict_slots
807 : : };
808 : :
809 : : static void
810 : 0 : heapctypewithmanagedweakref_dealloc(PyObject* self)
811 : : {
812 : :
813 : 0 : PyTypeObject *tp = Py_TYPE(self);
814 : 0 : PyObject_ClearWeakRefs(self);
815 : 0 : PyObject_GC_UnTrack(self);
816 : 0 : PyObject_GC_Del(self);
817 : 0 : Py_DECREF(tp);
818 : 0 : }
819 : :
820 : : static PyType_Slot HeapCTypeWithManagedWeakref_slots[] = {
821 : : {Py_tp_traverse, heapgcctype_traverse},
822 : : {Py_tp_getset, heapctypewithdict_getsetlist},
823 : : {Py_tp_dealloc, heapctypewithmanagedweakref_dealloc},
824 : : {0, 0},
825 : : };
826 : :
827 : : static PyType_Spec HeapCTypeWithManagedWeakref_spec = {
828 : : "_testcapi.HeapCTypeWithManagedWeakref",
829 : : sizeof(PyObject),
830 : : 0,
831 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_WEAKREF,
832 : : HeapCTypeWithManagedWeakref_slots
833 : : };
834 : :
835 : : static struct PyMemberDef heapctypewithnegativedict_members[] = {
836 : : {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)},
837 : : {"__dictoffset__", T_PYSSIZET, -(Py_ssize_t)sizeof(void*), READONLY},
838 : : {NULL} /* Sentinel */
839 : : };
840 : :
841 : : static PyType_Slot HeapCTypeWithNegativeDict_slots[] = {
842 : : {Py_tp_members, heapctypewithnegativedict_members},
843 : : {Py_tp_getset, heapctypewithdict_getsetlist},
844 : : {Py_tp_dealloc, heapctypewithdict_dealloc},
845 : : {0, 0},
846 : : };
847 : :
848 : : static PyType_Spec HeapCTypeWithNegativeDict_spec = {
849 : : "_testcapi.HeapCTypeWithNegativeDict",
850 : : sizeof(HeapCTypeWithDictObject),
851 : : 0,
852 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
853 : : HeapCTypeWithNegativeDict_slots
854 : : };
855 : :
856 : : typedef struct {
857 : : PyObject_HEAD
858 : : PyObject *weakreflist;
859 : : } HeapCTypeWithWeakrefObject;
860 : :
861 : : static struct PyMemberDef heapctypewithweakref_members[] = {
862 : : {"weakreflist", T_OBJECT, offsetof(HeapCTypeWithWeakrefObject, weakreflist)},
863 : : {"__weaklistoffset__", T_PYSSIZET,
864 : : offsetof(HeapCTypeWithWeakrefObject, weakreflist), READONLY},
865 : : {NULL} /* Sentinel */
866 : : };
867 : :
868 : : static void
869 : 0 : heapctypewithweakref_dealloc(HeapCTypeWithWeakrefObject* self)
870 : : {
871 : :
872 : 0 : PyTypeObject *tp = Py_TYPE(self);
873 [ # # ]: 0 : if (self->weakreflist != NULL)
874 : 0 : PyObject_ClearWeakRefs((PyObject *) self);
875 : 0 : Py_XDECREF(self->weakreflist);
876 : 0 : PyObject_Free(self);
877 : 0 : Py_DECREF(tp);
878 : 0 : }
879 : :
880 : : static PyType_Slot HeapCTypeWithWeakref_slots[] = {
881 : : {Py_tp_members, heapctypewithweakref_members},
882 : : {Py_tp_dealloc, heapctypewithweakref_dealloc},
883 : : {0, 0},
884 : : };
885 : :
886 : : static PyType_Spec HeapCTypeWithWeakref_spec = {
887 : : "_testcapi.HeapCTypeWithWeakref",
888 : : sizeof(HeapCTypeWithWeakrefObject),
889 : : 0,
890 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
891 : : HeapCTypeWithWeakref_slots
892 : : };
893 : :
894 : : static PyType_Spec HeapCTypeWithWeakref2_spec = {
895 : : "_testcapi.HeapCTypeWithWeakref2",
896 : : sizeof(HeapCTypeWithWeakrefObject),
897 : : 0,
898 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
899 : : HeapCTypeWithWeakref_slots
900 : : };
901 : :
902 : : PyDoc_STRVAR(heapctypesetattr__doc__,
903 : : "A heap type without GC, but with overridden __setattr__.\n\n"
904 : : "The 'value' attribute is set to 10 in __init__ and updated via attribute setting.");
905 : :
906 : : typedef struct {
907 : : PyObject_HEAD
908 : : long value;
909 : : } HeapCTypeSetattrObject;
910 : :
911 : : static struct PyMemberDef heapctypesetattr_members[] = {
912 : : {"pvalue", T_LONG, offsetof(HeapCTypeSetattrObject, value)},
913 : : {NULL} /* Sentinel */
914 : : };
915 : :
916 : : static int
917 : 0 : heapctypesetattr_init(PyObject *self, PyObject *args, PyObject *kwargs)
918 : : {
919 : 0 : ((HeapCTypeSetattrObject *)self)->value = 10;
920 : 0 : return 0;
921 : : }
922 : :
923 : : static void
924 : 0 : heapctypesetattr_dealloc(HeapCTypeSetattrObject *self)
925 : : {
926 : 0 : PyTypeObject *tp = Py_TYPE(self);
927 : 0 : PyObject_Free(self);
928 : 0 : Py_DECREF(tp);
929 : 0 : }
930 : :
931 : : static int
932 : 0 : heapctypesetattr_setattro(HeapCTypeSetattrObject *self, PyObject *attr, PyObject *value)
933 : : {
934 : 0 : PyObject *svalue = PyUnicode_FromString("value");
935 [ # # ]: 0 : if (svalue == NULL)
936 : 0 : return -1;
937 : 0 : int eq = PyObject_RichCompareBool(svalue, attr, Py_EQ);
938 : 0 : Py_DECREF(svalue);
939 [ # # ]: 0 : if (eq < 0)
940 : 0 : return -1;
941 [ # # ]: 0 : if (!eq) {
942 : 0 : return PyObject_GenericSetAttr((PyObject*) self, attr, value);
943 : : }
944 [ # # ]: 0 : if (value == NULL) {
945 : 0 : self->value = 0;
946 : 0 : return 0;
947 : : }
948 : 0 : PyObject *ivalue = PyNumber_Long(value);
949 [ # # ]: 0 : if (ivalue == NULL)
950 : 0 : return -1;
951 : 0 : long v = PyLong_AsLong(ivalue);
952 : 0 : Py_DECREF(ivalue);
953 [ # # # # ]: 0 : if (v == -1 && PyErr_Occurred())
954 : 0 : return -1;
955 : 0 : self->value = v;
956 : 0 : return 0;
957 : : }
958 : :
959 : : static PyType_Slot HeapCTypeSetattr_slots[] = {
960 : : {Py_tp_init, heapctypesetattr_init},
961 : : {Py_tp_members, heapctypesetattr_members},
962 : : {Py_tp_setattro, heapctypesetattr_setattro},
963 : : {Py_tp_dealloc, heapctypesetattr_dealloc},
964 : : {Py_tp_doc, (char*)heapctypesetattr__doc__},
965 : : {0, 0},
966 : : };
967 : :
968 : : static PyType_Spec HeapCTypeSetattr_spec = {
969 : : "_testcapi.HeapCTypeSetattr",
970 : : sizeof(HeapCTypeSetattrObject),
971 : : 0,
972 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
973 : : HeapCTypeSetattr_slots
974 : : };
975 : :
976 : : int
977 : 2 : _PyTestCapi_Init_Heaptype(PyObject *m) {
978 : 2 : _testcapimodule = PyModule_GetDef(m);
979 : :
980 [ - + ]: 2 : if (PyModule_AddFunctions(m, TestMethods) < 0) {
981 : 0 : return -1;
982 : : }
983 : :
984 : 2 : PyObject *HeapDocCType = PyType_FromSpec(&HeapDocCType_spec);
985 [ - + ]: 2 : if (HeapDocCType == NULL) {
986 : 0 : return -1;
987 : : }
988 : 2 : PyModule_AddObject(m, "HeapDocCType", HeapDocCType);
989 : :
990 : : /* bpo-41832: Add a new type to test PyType_FromSpec()
991 : : now can accept a NULL tp_doc slot. */
992 : 2 : PyObject *NullTpDocType = PyType_FromSpec(&NullTpDocType_spec);
993 [ - + ]: 2 : if (NullTpDocType == NULL) {
994 : 0 : return -1;
995 : : }
996 : 2 : PyModule_AddObject(m, "NullTpDocType", NullTpDocType);
997 : :
998 : 2 : PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec);
999 [ - + ]: 2 : if (HeapGcCType == NULL) {
1000 : 0 : return -1;
1001 : : }
1002 : 2 : PyModule_AddObject(m, "HeapGcCType", HeapGcCType);
1003 : :
1004 : 2 : PyObject *HeapCType = PyType_FromSpec(&HeapCType_spec);
1005 [ - + ]: 2 : if (HeapCType == NULL) {
1006 : 0 : return -1;
1007 : : }
1008 : 2 : PyObject *subclass_bases = PyTuple_Pack(1, HeapCType);
1009 [ - + ]: 2 : if (subclass_bases == NULL) {
1010 : 0 : return -1;
1011 : : }
1012 : 2 : PyObject *HeapCTypeSubclass = PyType_FromSpecWithBases(&HeapCTypeSubclass_spec, subclass_bases);
1013 [ - + ]: 2 : if (HeapCTypeSubclass == NULL) {
1014 : 0 : return -1;
1015 : : }
1016 : 2 : Py_DECREF(subclass_bases);
1017 : 2 : PyModule_AddObject(m, "HeapCTypeSubclass", HeapCTypeSubclass);
1018 : :
1019 : 2 : PyObject *HeapCTypeWithDict = PyType_FromSpec(&HeapCTypeWithDict_spec);
1020 [ - + ]: 2 : if (HeapCTypeWithDict == NULL) {
1021 : 0 : return -1;
1022 : : }
1023 : 2 : PyModule_AddObject(m, "HeapCTypeWithDict", HeapCTypeWithDict);
1024 : :
1025 : 2 : PyObject *HeapCTypeWithDict2 = PyType_FromSpec(&HeapCTypeWithDict2_spec);
1026 [ - + ]: 2 : if (HeapCTypeWithDict2 == NULL) {
1027 : 0 : return -1;
1028 : : }
1029 : 2 : PyModule_AddObject(m, "HeapCTypeWithDict2", HeapCTypeWithDict2);
1030 : :
1031 : 2 : PyObject *HeapCTypeWithNegativeDict = PyType_FromSpec(&HeapCTypeWithNegativeDict_spec);
1032 [ - + ]: 2 : if (HeapCTypeWithNegativeDict == NULL) {
1033 : 0 : return -1;
1034 : : }
1035 : 2 : PyModule_AddObject(m, "HeapCTypeWithNegativeDict", HeapCTypeWithNegativeDict);
1036 : :
1037 : 2 : PyObject *HeapCTypeWithManagedDict = PyType_FromSpec(&HeapCTypeWithManagedDict_spec);
1038 [ - + ]: 2 : if (HeapCTypeWithManagedDict == NULL) {
1039 : 0 : return -1;
1040 : : }
1041 : 2 : PyModule_AddObject(m, "HeapCTypeWithManagedDict", HeapCTypeWithManagedDict);
1042 : :
1043 : 2 : PyObject *HeapCTypeWithManagedWeakref = PyType_FromSpec(&HeapCTypeWithManagedWeakref_spec);
1044 [ - + ]: 2 : if (HeapCTypeWithManagedWeakref == NULL) {
1045 : 0 : return -1;
1046 : : }
1047 : 2 : PyModule_AddObject(m, "HeapCTypeWithManagedWeakref", HeapCTypeWithManagedWeakref);
1048 : :
1049 : 2 : PyObject *HeapCTypeWithWeakref = PyType_FromSpec(&HeapCTypeWithWeakref_spec);
1050 [ - + ]: 2 : if (HeapCTypeWithWeakref == NULL) {
1051 : 0 : return -1;
1052 : : }
1053 : 2 : PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref);
1054 : :
1055 : 2 : PyObject *HeapCTypeWithWeakref2 = PyType_FromSpec(&HeapCTypeWithWeakref2_spec);
1056 [ - + ]: 2 : if (HeapCTypeWithWeakref2 == NULL) {
1057 : 0 : return -1;
1058 : : }
1059 : 2 : PyModule_AddObject(m, "HeapCTypeWithWeakref2", HeapCTypeWithWeakref2);
1060 : :
1061 : 2 : PyObject *HeapCTypeWithBuffer = PyType_FromSpec(&HeapCTypeWithBuffer_spec);
1062 [ - + ]: 2 : if (HeapCTypeWithBuffer == NULL) {
1063 : 0 : return -1;
1064 : : }
1065 : 2 : PyModule_AddObject(m, "HeapCTypeWithBuffer", HeapCTypeWithBuffer);
1066 : :
1067 : 2 : PyObject *HeapCTypeSetattr = PyType_FromSpec(&HeapCTypeSetattr_spec);
1068 [ - + ]: 2 : if (HeapCTypeSetattr == NULL) {
1069 : 0 : return -1;
1070 : : }
1071 : 2 : PyModule_AddObject(m, "HeapCTypeSetattr", HeapCTypeSetattr);
1072 : :
1073 : 2 : PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass);
1074 [ - + ]: 2 : if (subclass_with_finalizer_bases == NULL) {
1075 : 0 : return -1;
1076 : : }
1077 : 2 : PyObject *HeapCTypeSubclassWithFinalizer = PyType_FromSpecWithBases(
1078 : : &HeapCTypeSubclassWithFinalizer_spec, subclass_with_finalizer_bases);
1079 [ - + ]: 2 : if (HeapCTypeSubclassWithFinalizer == NULL) {
1080 : 0 : return -1;
1081 : : }
1082 : 2 : Py_DECREF(subclass_with_finalizer_bases);
1083 : 2 : PyModule_AddObject(m, "HeapCTypeSubclassWithFinalizer", HeapCTypeSubclassWithFinalizer);
1084 : :
1085 : 2 : PyObject *HeapCTypeMetaclass = PyType_FromMetaclass(
1086 : : &PyType_Type, m, &HeapCTypeMetaclass_spec, (PyObject *) &PyType_Type);
1087 [ - + ]: 2 : if (HeapCTypeMetaclass == NULL) {
1088 : 0 : return -1;
1089 : : }
1090 : 2 : PyModule_AddObject(m, "HeapCTypeMetaclass", HeapCTypeMetaclass);
1091 : :
1092 : 2 : PyObject *HeapCTypeMetaclassCustomNew = PyType_FromMetaclass(
1093 : : &PyType_Type, m, &HeapCTypeMetaclassCustomNew_spec, (PyObject *) &PyType_Type);
1094 [ - + ]: 2 : if (HeapCTypeMetaclassCustomNew == NULL) {
1095 : 0 : return -1;
1096 : : }
1097 : 2 : PyModule_AddObject(m, "HeapCTypeMetaclassCustomNew", HeapCTypeMetaclassCustomNew);
1098 : :
1099 : 2 : return 0;
1100 : : }
|