LCOV - code coverage report
Current view: | top level - Modules/_testcapi - heaptype.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 60 | 418 | 14.4 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 1 | 27 | 3.7 %
|  |  | Branches: | 20 | 161 | 12.4 %

               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                 :            : }

Generated by: LCOV version 1.14