LCOV - code coverage report
Current view: | top level - Modules - _abc.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 288 | 458 | 62.9 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 21 | 25 | 84.0 %
|  |  | Branches: | 155 | 278 | 55.8 %

               Branch data     Line data    Source code
           1                 :            : /* ABCMeta implementation */
           2                 :            : #ifndef Py_BUILD_CORE_BUILTIN
           3                 :            : #  define Py_BUILD_CORE_MODULE 1
           4                 :            : #endif
           5                 :            :
           6                 :            : #include "Python.h"
           7                 :            : #include "pycore_moduleobject.h"  // _PyModule_GetState()
           8                 :            : #include "pycore_object.h"        // _PyType_GetSubclasses()
           9                 :            : #include "pycore_runtime.h"       // _Py_ID()
          10                 :            : #include "clinic/_abc.c.h"
          11                 :            :
          12                 :            : /*[clinic input]
          13                 :            : module _abc
          14                 :            : [clinic start generated code]*/
          15                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=964f5328e1aefcda]*/
          16                 :            :
          17                 :            : PyDoc_STRVAR(_abc__doc__,
          18                 :            : "Module contains faster C implementation of abc.ABCMeta");
          19                 :            :
          20                 :            : typedef struct {
          21                 :            :     PyTypeObject *_abc_data_type;
          22                 :            :     unsigned long long abc_invalidation_counter;
          23                 :            : } _abcmodule_state;
          24                 :            :
          25                 :            : static inline _abcmodule_state*
          26                 :     125267 : get_abc_state(PyObject *module)
          27                 :            : {
          28                 :     125267 :     void *state = _PyModule_GetState(module);
          29                 :            :     assert(state != NULL);
          30                 :     125267 :     return (_abcmodule_state *)state;
          31                 :            : }
          32                 :            :
          33                 :            : /* This object stores internal state for ABCs.
          34                 :            :    Note that we can use normal sets for caches,
          35                 :            :    since they are never iterated over. */
          36                 :            : typedef struct {
          37                 :            :     PyObject_HEAD
          38                 :            :     PyObject *_abc_registry;
          39                 :            :     PyObject *_abc_cache; /* Normal set of weak references. */
          40                 :            :     PyObject *_abc_negative_cache; /* Normal set of weak references. */
          41                 :            :     unsigned long long _abc_negative_cache_version;
          42                 :            : } _abc_data;
          43                 :            :
          44                 :            : static int
          45                 :       8744 : abc_data_traverse(_abc_data *self, visitproc visit, void *arg)
          46                 :            : {
          47   [ +  -  -  + ]:       8744 :     Py_VISIT(Py_TYPE(self));
          48   [ +  +  -  + ]:       8744 :     Py_VISIT(self->_abc_registry);
          49   [ +  +  -  + ]:       8744 :     Py_VISIT(self->_abc_cache);
          50   [ +  +  -  + ]:       8744 :     Py_VISIT(self->_abc_negative_cache);
          51                 :       8744 :     return 0;
          52                 :            : }
          53                 :            :
          54                 :            : static int
          55                 :        918 : abc_data_clear(_abc_data *self)
          56                 :            : {
          57         [ +  + ]:        918 :     Py_CLEAR(self->_abc_registry);
          58         [ +  + ]:        918 :     Py_CLEAR(self->_abc_cache);
          59         [ +  + ]:        918 :     Py_CLEAR(self->_abc_negative_cache);
          60                 :        918 :     return 0;
          61                 :            : }
          62                 :            :
          63                 :            : static void
          64                 :        918 : abc_data_dealloc(_abc_data *self)
          65                 :            : {
          66                 :        918 :     PyObject_GC_UnTrack(self);
          67                 :        918 :     PyTypeObject *tp = Py_TYPE(self);
          68                 :        918 :     (void)abc_data_clear(self);
          69                 :        918 :     tp->tp_free(self);
          70                 :        918 :     Py_DECREF(tp);
          71                 :        918 : }
          72                 :            :
          73                 :            : static PyObject *
          74                 :        962 : abc_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
          75                 :            : {
          76                 :        962 :     _abc_data *self = (_abc_data *) type->tp_alloc(type, 0);
          77                 :        962 :     _abcmodule_state *state = NULL;
          78         [ -  + ]:        962 :     if (self == NULL) {
          79                 :          0 :         return NULL;
          80                 :            :     }
          81                 :            :
          82                 :        962 :     state = _PyType_GetModuleState(type);
          83         [ -  + ]:        962 :     if (state == NULL) {
          84                 :          0 :         Py_DECREF(self);
          85                 :          0 :         return NULL;
          86                 :            :     }
          87                 :            :
          88                 :        962 :     self->_abc_registry = NULL;
          89                 :        962 :     self->_abc_cache = NULL;
          90                 :        962 :     self->_abc_negative_cache = NULL;
          91                 :        962 :     self->_abc_negative_cache_version = state->abc_invalidation_counter;
          92                 :        962 :     return (PyObject *) self;
          93                 :            : }
          94                 :            :
          95                 :            : PyDoc_STRVAR(abc_data_doc,
          96                 :            : "Internal state held by ABC machinery.");
          97                 :            :
          98                 :            : static PyType_Slot _abc_data_type_spec_slots[] = {
          99                 :            :     {Py_tp_doc, (void *)abc_data_doc},
         100                 :            :     {Py_tp_new, abc_data_new},
         101                 :            :     {Py_tp_dealloc, abc_data_dealloc},
         102                 :            :     {Py_tp_traverse, abc_data_traverse},
         103                 :            :     {Py_tp_clear, abc_data_clear},
         104                 :            :     {0, 0}
         105                 :            : };
         106                 :            :
         107                 :            : static PyType_Spec _abc_data_type_spec = {
         108                 :            :     .name = "_abc._abc_data",
         109                 :            :     .basicsize = sizeof(_abc_data),
         110                 :            :     .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
         111                 :            :     .slots = _abc_data_type_spec_slots,
         112                 :            : };
         113                 :            :
         114                 :            : static _abc_data *
         115                 :      71868 : _get_impl(PyObject *module, PyObject *self)
         116                 :            : {
         117                 :      71868 :     _abcmodule_state *state = get_abc_state(module);
         118                 :      71868 :     PyObject *impl = PyObject_GetAttr(self, &_Py_ID(_abc_impl));
         119         [ -  + ]:      71868 :     if (impl == NULL) {
         120                 :          0 :         return NULL;
         121                 :            :     }
         122         [ -  + ]:      71868 :     if (!Py_IS_TYPE(impl, state->_abc_data_type)) {
         123                 :          0 :         PyErr_SetString(PyExc_TypeError, "_abc_impl is set to a wrong type");
         124                 :          0 :         Py_DECREF(impl);
         125                 :          0 :         return NULL;
         126                 :            :     }
         127                 :      71868 :     return (_abc_data *)impl;
         128                 :            : }
         129                 :            :
         130                 :            : static int
         131                 :     123124 : _in_weak_set(PyObject *set, PyObject *obj)
         132                 :            : {
         133   [ +  +  +  + ]:     123124 :     if (set == NULL || PySet_GET_SIZE(set) == 0) {
         134                 :      22747 :         return 0;
         135                 :            :     }
         136                 :     100377 :     PyObject *ref = PyWeakref_NewRef(obj, NULL);
         137         [ -  + ]:     100377 :     if (ref == NULL) {
         138         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_TypeError)) {
         139                 :          0 :             PyErr_Clear();
         140                 :          0 :             return 0;
         141                 :            :         }
         142                 :          0 :         return -1;
         143                 :            :     }
         144                 :     100377 :     int res = PySet_Contains(set, ref);
         145                 :     100377 :     Py_DECREF(ref);
         146                 :     100377 :     return res;
         147                 :            : }
         148                 :            :
         149                 :            : static PyObject *
         150                 :          7 : _destroy(PyObject *setweakref, PyObject *objweakref)
         151                 :            : {
         152                 :            :     PyObject *set;
         153                 :          7 :     set = PyWeakref_GET_OBJECT(setweakref);
         154         [ -  + ]:          7 :     if (set == Py_None) {
         155                 :          0 :         Py_RETURN_NONE;
         156                 :            :     }
         157                 :          7 :     Py_INCREF(set);
         158         [ -  + ]:          7 :     if (PySet_Discard(set, objweakref) < 0) {
         159                 :          0 :         Py_DECREF(set);
         160                 :          0 :         return NULL;
         161                 :            :     }
         162                 :          7 :     Py_DECREF(set);
         163                 :          7 :     Py_RETURN_NONE;
         164                 :            : }
         165                 :            :
         166                 :            : static PyMethodDef _destroy_def = {
         167                 :            :     "_destroy", (PyCFunction) _destroy, METH_O
         168                 :            : };
         169                 :            :
         170                 :            : static int
         171                 :       1609 : _add_to_weak_set(PyObject **pset, PyObject *obj)
         172                 :            : {
         173         [ +  + ]:       1609 :     if (*pset == NULL) {
         174                 :        775 :         *pset = PySet_New(NULL);
         175         [ -  + ]:        775 :         if (*pset == NULL) {
         176                 :          0 :             return -1;
         177                 :            :         }
         178                 :            :     }
         179                 :            :
         180                 :       1609 :     PyObject *set = *pset;
         181                 :            :     PyObject *ref, *wr;
         182                 :            :     PyObject *destroy_cb;
         183                 :       1609 :     wr = PyWeakref_NewRef(set, NULL);
         184         [ -  + ]:       1609 :     if (wr == NULL) {
         185                 :          0 :         return -1;
         186                 :            :     }
         187                 :       1609 :     destroy_cb = PyCFunction_NewEx(&_destroy_def, wr, NULL);
         188         [ -  + ]:       1609 :     if (destroy_cb == NULL) {
         189                 :          0 :         Py_DECREF(wr);
         190                 :          0 :         return -1;
         191                 :            :     }
         192                 :       1609 :     ref = PyWeakref_NewRef(obj, destroy_cb);
         193                 :       1609 :     Py_DECREF(destroy_cb);
         194         [ -  + ]:       1609 :     if (ref == NULL) {
         195                 :          0 :         Py_DECREF(wr);
         196                 :          0 :         return -1;
         197                 :            :     }
         198                 :       1609 :     int ret = PySet_Add(set, ref);
         199                 :       1609 :     Py_DECREF(wr);
         200                 :       1609 :     Py_DECREF(ref);
         201                 :       1609 :     return ret;
         202                 :            : }
         203                 :            :
         204                 :            : /*[clinic input]
         205                 :            : _abc._reset_registry
         206                 :            :
         207                 :            :     self: object
         208                 :            :     /
         209                 :            :
         210                 :            : Internal ABC helper to reset registry of a given class.
         211                 :            :
         212                 :            : Should be only used by refleak.py
         213                 :            : [clinic start generated code]*/
         214                 :            :
         215                 :            : static PyObject *
         216                 :          0 : _abc__reset_registry(PyObject *module, PyObject *self)
         217                 :            : /*[clinic end generated code: output=92d591a43566cc10 input=12a0b7eb339ac35c]*/
         218                 :            : {
         219                 :          0 :     _abc_data *impl = _get_impl(module, self);
         220         [ #  # ]:          0 :     if (impl == NULL) {
         221                 :          0 :         return NULL;
         222                 :            :     }
         223   [ #  #  #  # ]:          0 :     if (impl->_abc_registry != NULL && PySet_Clear(impl->_abc_registry) < 0) {
         224                 :          0 :         Py_DECREF(impl);
         225                 :          0 :         return NULL;
         226                 :            :     }
         227                 :          0 :     Py_DECREF(impl);
         228                 :          0 :     Py_RETURN_NONE;
         229                 :            : }
         230                 :            :
         231                 :            : /*[clinic input]
         232                 :            : _abc._reset_caches
         233                 :            :
         234                 :            :     self: object
         235                 :            :     /
         236                 :            :
         237                 :            : Internal ABC helper to reset both caches of a given class.
         238                 :            :
         239                 :            : Should be only used by refleak.py
         240                 :            : [clinic start generated code]*/
         241                 :            :
         242                 :            : static PyObject *
         243                 :          0 : _abc__reset_caches(PyObject *module, PyObject *self)
         244                 :            : /*[clinic end generated code: output=f296f0d5c513f80c input=c0ac616fd8acfb6f]*/
         245                 :            : {
         246                 :          0 :     _abc_data *impl = _get_impl(module, self);
         247         [ #  # ]:          0 :     if (impl == NULL) {
         248                 :          0 :         return NULL;
         249                 :            :     }
         250   [ #  #  #  # ]:          0 :     if (impl->_abc_cache != NULL && PySet_Clear(impl->_abc_cache) < 0) {
         251                 :          0 :         Py_DECREF(impl);
         252                 :          0 :         return NULL;
         253                 :            :     }
         254                 :            :     /* also the second cache */
         255   [ #  #  #  # ]:          0 :     if (impl->_abc_negative_cache != NULL &&
         256                 :          0 :             PySet_Clear(impl->_abc_negative_cache) < 0) {
         257                 :          0 :         Py_DECREF(impl);
         258                 :          0 :         return NULL;
         259                 :            :     }
         260                 :          0 :     Py_DECREF(impl);
         261                 :          0 :     Py_RETURN_NONE;
         262                 :            : }
         263                 :            :
         264                 :            : /*[clinic input]
         265                 :            : _abc._get_dump
         266                 :            :
         267                 :            :     self: object
         268                 :            :     /
         269                 :            :
         270                 :            : Internal ABC helper for cache and registry debugging.
         271                 :            :
         272                 :            : Return shallow copies of registry, of both caches, and
         273                 :            : negative cache version. Don't call this function directly,
         274                 :            : instead use ABC._dump_registry() for a nice repr.
         275                 :            : [clinic start generated code]*/
         276                 :            :
         277                 :            : static PyObject *
         278                 :          0 : _abc__get_dump(PyObject *module, PyObject *self)
         279                 :            : /*[clinic end generated code: output=9d9569a8e2c1c443 input=2c5deb1bfe9e3c79]*/
         280                 :            : {
         281                 :          0 :     _abc_data *impl = _get_impl(module, self);
         282         [ #  # ]:          0 :     if (impl == NULL) {
         283                 :          0 :         return NULL;
         284                 :            :     }
         285                 :          0 :     PyObject *res = Py_BuildValue("NNNK",
         286                 :            :                                   PySet_New(impl->_abc_registry),
         287                 :            :                                   PySet_New(impl->_abc_cache),
         288                 :            :                                   PySet_New(impl->_abc_negative_cache),
         289                 :            :                                   impl->_abc_negative_cache_version);
         290                 :          0 :     Py_DECREF(impl);
         291                 :          0 :     return res;
         292                 :            : }
         293                 :            :
         294                 :            : // Compute set of abstract method names.
         295                 :            : static int
         296                 :        962 : compute_abstract_methods(PyObject *self)
         297                 :            : {
         298                 :        962 :     int ret = -1;
         299                 :        962 :     PyObject *abstracts = PyFrozenSet_New(NULL);
         300         [ -  + ]:        962 :     if (abstracts == NULL) {
         301                 :          0 :         return -1;
         302                 :            :     }
         303                 :            :
         304                 :        962 :     PyObject *ns = NULL, *items = NULL, *bases = NULL;  // Py_XDECREF()ed on error.
         305                 :            :
         306                 :            :     /* Stage 1: direct abstract methods. */
         307                 :        962 :     ns = PyObject_GetAttr(self, &_Py_ID(__dict__));
         308         [ -  + ]:        962 :     if (!ns) {
         309                 :          0 :         goto error;
         310                 :            :     }
         311                 :            :
         312                 :            :     // We can't use PyDict_Next(ns) even when ns is dict because
         313                 :            :     // _PyObject_IsAbstract() can mutate ns.
         314                 :        962 :     items = PyMapping_Items(ns);
         315         [ -  + ]:        962 :     if (!items) {
         316                 :          0 :         goto error;
         317                 :            :     }
         318                 :            :     assert(PyList_Check(items));
         319         [ +  + ]:       8633 :     for (Py_ssize_t pos = 0; pos < PyList_GET_SIZE(items); pos++) {
         320                 :       7671 :         PyObject *it = PySequence_Fast(
         321                 :       7671 :                 PyList_GET_ITEM(items, pos),
         322                 :            :                 "items() returned non-iterable");
         323         [ -  + ]:       7671 :         if (!it) {
         324                 :          0 :             goto error;
         325                 :            :         }
         326   [ -  +  -  + ]:       7671 :         if (PySequence_Fast_GET_SIZE(it) != 2) {
         327                 :          0 :             PyErr_SetString(PyExc_TypeError,
         328                 :            :                             "items() returned item which size is not 2");
         329                 :          0 :             Py_DECREF(it);
         330                 :          0 :             goto error;
         331                 :            :         }
         332                 :            :
         333                 :            :         // borrowed
         334         [ -  + ]:       7671 :         PyObject *key = PySequence_Fast_GET_ITEM(it, 0);
         335         [ -  + ]:       7671 :         PyObject *value = PySequence_Fast_GET_ITEM(it, 1);
         336                 :            :         // items or it may be cleared while accessing __abstractmethod__
         337                 :            :         // So we need to keep strong reference for key
         338                 :       7671 :         Py_INCREF(key);
         339                 :       7671 :         int is_abstract = _PyObject_IsAbstract(value);
         340   [ +  -  +  + ]:       7671 :         if (is_abstract < 0 ||
         341         [ -  + ]:        767 :                 (is_abstract && PySet_Add(abstracts, key) < 0)) {
         342                 :          0 :             Py_DECREF(it);
         343                 :          0 :             Py_DECREF(key);
         344                 :          0 :             goto error;
         345                 :            :         }
         346                 :       7671 :         Py_DECREF(key);
         347                 :       7671 :         Py_DECREF(it);
         348                 :            :     }
         349                 :            :
         350                 :            :     /* Stage 2: inherited abstract methods. */
         351                 :        962 :     bases = PyObject_GetAttr(self, &_Py_ID(__bases__));
         352         [ -  + ]:        962 :     if (!bases) {
         353                 :          0 :         goto error;
         354                 :            :     }
         355         [ -  + ]:        962 :     if (!PyTuple_Check(bases)) {
         356                 :          0 :         PyErr_SetString(PyExc_TypeError, "__bases__ is not tuple");
         357                 :          0 :         goto error;
         358                 :            :     }
         359                 :            :
         360         [ +  + ]:       2179 :     for (Py_ssize_t pos = 0; pos < PyTuple_GET_SIZE(bases); pos++) {
         361                 :       1217 :         PyObject *item = PyTuple_GET_ITEM(bases, pos);  // borrowed
         362                 :            :         PyObject *base_abstracts, *iter;
         363                 :            :
         364         [ -  + ]:       1217 :         if (_PyObject_LookupAttr(item, &_Py_ID(__abstractmethods__),
         365                 :            :                                  &base_abstracts) < 0) {
         366                 :          0 :             goto error;
         367                 :            :         }
         368         [ +  + ]:       1217 :         if (base_abstracts == NULL) {
         369                 :        335 :             continue;
         370                 :            :         }
         371         [ -  + ]:        882 :         if (!(iter = PyObject_GetIter(base_abstracts))) {
         372                 :          0 :             Py_DECREF(base_abstracts);
         373                 :          0 :             goto error;
         374                 :            :         }
         375                 :        882 :         Py_DECREF(base_abstracts);
         376                 :            :         PyObject *key, *value;
         377         [ +  + ]:       2342 :         while ((key = PyIter_Next(iter))) {
         378         [ -  + ]:       1460 :             if (_PyObject_LookupAttr(self, key, &value) < 0) {
         379                 :          0 :                 Py_DECREF(key);
         380                 :          0 :                 Py_DECREF(iter);
         381                 :          0 :                 goto error;
         382                 :            :             }
         383         [ -  + ]:       1460 :             if (value == NULL) {
         384                 :          0 :                 Py_DECREF(key);
         385                 :          0 :                 continue;
         386                 :            :             }
         387                 :            :
         388                 :       1460 :             int is_abstract = _PyObject_IsAbstract(value);
         389                 :       1460 :             Py_DECREF(value);
         390   [ +  -  +  + ]:       1460 :             if (is_abstract < 0 ||
         391         [ -  + ]:        638 :                     (is_abstract && PySet_Add(abstracts, key) < 0))
         392                 :            :             {
         393                 :          0 :                 Py_DECREF(key);
         394                 :          0 :                 Py_DECREF(iter);
         395                 :          0 :                 goto error;
         396                 :            :             }
         397                 :       1460 :             Py_DECREF(key);
         398                 :            :         }
         399                 :        882 :         Py_DECREF(iter);
         400         [ -  + ]:        882 :         if (PyErr_Occurred()) {
         401                 :          0 :             goto error;
         402                 :            :         }
         403                 :            :     }
         404                 :            :
         405         [ -  + ]:        962 :     if (PyObject_SetAttr(self, &_Py_ID(__abstractmethods__), abstracts) < 0) {
         406                 :          0 :         goto error;
         407                 :            :     }
         408                 :            :
         409                 :        962 :     ret = 0;
         410                 :        962 : error:
         411                 :        962 :     Py_DECREF(abstracts);
         412                 :        962 :     Py_XDECREF(ns);
         413                 :        962 :     Py_XDECREF(items);
         414                 :        962 :     Py_XDECREF(bases);
         415                 :        962 :     return ret;
         416                 :            : }
         417                 :            :
         418                 :            : #define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING)
         419                 :            :
         420                 :            : /*[clinic input]
         421                 :            : _abc._abc_init
         422                 :            :
         423                 :            :     self: object
         424                 :            :     /
         425                 :            :
         426                 :            : Internal ABC helper for class set-up. Should be never used outside abc module.
         427                 :            : [clinic start generated code]*/
         428                 :            :
         429                 :            : static PyObject *
         430                 :        962 : _abc__abc_init(PyObject *module, PyObject *self)
         431                 :            : /*[clinic end generated code: output=594757375714cda1 input=8d7fe470ff77f029]*/
         432                 :            : {
         433                 :        962 :     _abcmodule_state *state = get_abc_state(module);
         434                 :            :     PyObject *data;
         435         [ -  + ]:        962 :     if (compute_abstract_methods(self) < 0) {
         436                 :          0 :         return NULL;
         437                 :            :     }
         438                 :            :
         439                 :            :     /* Set up inheritance registry. */
         440                 :        962 :     data = abc_data_new(state->_abc_data_type, NULL, NULL);
         441         [ -  + ]:        962 :     if (data == NULL) {
         442                 :          0 :         return NULL;
         443                 :            :     }
         444         [ -  + ]:        962 :     if (PyObject_SetAttr(self, &_Py_ID(_abc_impl), data) < 0) {
         445                 :          0 :         Py_DECREF(data);
         446                 :          0 :         return NULL;
         447                 :            :     }
         448                 :        962 :     Py_DECREF(data);
         449                 :            :     /* If __abc_tpflags__ & COLLECTION_FLAGS is set, then set the corresponding bit(s)
         450                 :            :      * in the new class.
         451                 :            :      * Used by collections.abc.Sequence and collections.abc.Mapping to indicate
         452                 :            :      * their special status w.r.t. pattern matching. */
         453         [ +  - ]:        962 :     if (PyType_Check(self)) {
         454                 :        962 :         PyTypeObject *cls = (PyTypeObject *)self;
         455                 :        962 :         PyObject *flags = PyDict_GetItemWithError(cls->tp_dict,
         456                 :            :                                                   &_Py_ID(__abc_tpflags__));
         457         [ +  + ]:        962 :         if (flags == NULL) {
         458         [ -  + ]:        912 :             if (PyErr_Occurred()) {
         459                 :          0 :                 return NULL;
         460                 :            :             }
         461                 :            :         }
         462                 :            :         else {
         463         [ +  - ]:         50 :             if (PyLong_CheckExact(flags)) {
         464                 :         50 :                 long val = PyLong_AsLong(flags);
         465   [ -  +  -  - ]:         50 :                 if (val == -1 && PyErr_Occurred()) {
         466                 :          0 :                     return NULL;
         467                 :            :                 }
         468         [ -  + ]:         50 :                 if ((val & COLLECTION_FLAGS) == COLLECTION_FLAGS) {
         469                 :          0 :                     PyErr_SetString(PyExc_TypeError, "__abc_tpflags__ cannot be both Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING");
         470                 :          0 :                     return NULL;
         471                 :            :                 }
         472                 :         50 :                 ((PyTypeObject *)self)->tp_flags |= (val & COLLECTION_FLAGS);
         473                 :            :             }
         474         [ -  + ]:         50 :             if (PyDict_DelItem(cls->tp_dict, &_Py_ID(__abc_tpflags__)) < 0) {
         475                 :          0 :                 return NULL;
         476                 :            :             }
         477                 :            :         }
         478                 :            :     }
         479                 :        962 :     Py_RETURN_NONE;
         480                 :            : }
         481                 :            :
         482                 :            : static void
         483                 :        257 : set_collection_flag_recursive(PyTypeObject *child, unsigned long flag)
         484                 :            : {
         485                 :            :     assert(flag == Py_TPFLAGS_MAPPING || flag == Py_TPFLAGS_SEQUENCE);
         486         [ -  + ]:        257 :     if (PyType_HasFeature(child, Py_TPFLAGS_IMMUTABLETYPE) ||
         487         [ #  # ]:          0 :         (child->tp_flags & COLLECTION_FLAGS) == flag)
         488                 :            :     {
         489                 :        257 :         return;
         490                 :            :     }
         491                 :            :
         492                 :          0 :     child->tp_flags &= ~COLLECTION_FLAGS;
         493                 :          0 :     child->tp_flags |= flag;
         494                 :            :
         495                 :          0 :     PyObject *grandchildren = _PyType_GetSubclasses(child);
         496         [ #  # ]:          0 :     if (grandchildren == NULL) {
         497                 :          0 :         return;
         498                 :            :     }
         499                 :            :
         500         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < PyList_GET_SIZE(grandchildren); i++) {
         501                 :          0 :         PyObject *grandchild = PyList_GET_ITEM(grandchildren, i);
         502                 :          0 :         set_collection_flag_recursive((PyTypeObject *)grandchild, flag);
         503                 :            :     }
         504                 :          0 :     Py_DECREF(grandchildren);
         505                 :            : }
         506                 :            :
         507                 :            : /*[clinic input]
         508                 :            : _abc._abc_register
         509                 :            :
         510                 :            :     self: object
         511                 :            :     subclass: object
         512                 :            :     /
         513                 :            :
         514                 :            : Internal ABC helper for subclasss registration. Should be never used outside abc module.
         515                 :            : [clinic start generated code]*/
         516                 :            :
         517                 :            : static PyObject *
         518                 :        994 : _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass)
         519                 :            : /*[clinic end generated code: output=7851e7668c963524 input=ca589f8c3080e67f]*/
         520                 :            : {
         521         [ -  + ]:        994 :     if (!PyType_Check(subclass)) {
         522                 :          0 :         PyErr_SetString(PyExc_TypeError, "Can only register classes");
         523                 :          0 :         return NULL;
         524                 :            :     }
         525                 :        994 :     int result = PyObject_IsSubclass(subclass, self);
         526         [ +  + ]:        994 :     if (result > 0) {
         527                 :        401 :         return Py_NewRef(subclass);  /* Already a subclass. */
         528                 :            :     }
         529         [ -  + ]:        593 :     if (result < 0) {
         530                 :          0 :         return NULL;
         531                 :            :     }
         532                 :            :     /* Subtle: test for cycles *after* testing for "already a subclass";
         533                 :            :        this means we allow X.register(X) and interpret it as a no-op. */
         534                 :        593 :     result = PyObject_IsSubclass(self, subclass);
         535         [ -  + ]:        593 :     if (result > 0) {
         536                 :            :         /* This would create a cycle, which is bad for the algorithm below. */
         537                 :          0 :         PyErr_SetString(PyExc_RuntimeError, "Refusing to create an inheritance cycle");
         538                 :          0 :         return NULL;
         539                 :            :     }
         540         [ -  + ]:        593 :     if (result < 0) {
         541                 :          0 :         return NULL;
         542                 :            :     }
         543                 :        593 :     _abc_data *impl = _get_impl(module, self);
         544         [ -  + ]:        593 :     if (impl == NULL) {
         545                 :          0 :         return NULL;
         546                 :            :     }
         547         [ -  + ]:        593 :     if (_add_to_weak_set(&impl->_abc_registry, subclass) < 0) {
         548                 :          0 :         Py_DECREF(impl);
         549                 :          0 :         return NULL;
         550                 :            :     }
         551                 :        593 :     Py_DECREF(impl);
         552                 :            :
         553                 :            :     /* Invalidate negative cache */
         554                 :        593 :     get_abc_state(module)->abc_invalidation_counter++;
         555                 :            :
         556                 :            :     /* Set Py_TPFLAGS_SEQUENCE  or Py_TPFLAGS_MAPPING flag */
         557         [ +  - ]:        593 :     if (PyType_Check(self)) {
         558                 :        593 :         unsigned long collection_flag = ((PyTypeObject *)self)->tp_flags & COLLECTION_FLAGS;
         559         [ +  + ]:        593 :         if (collection_flag) {
         560                 :        257 :             set_collection_flag_recursive((PyTypeObject *)subclass, collection_flag);
         561                 :            :         }
         562                 :            :     }
         563                 :        593 :     return Py_NewRef(subclass);
         564                 :            : }
         565                 :            :
         566                 :            :
         567                 :            : /*[clinic input]
         568                 :            : _abc._abc_instancecheck
         569                 :            :
         570                 :            :     self: object
         571                 :            :     instance: object
         572                 :            :     /
         573                 :            :
         574                 :            : Internal ABC helper for instance checks. Should be never used outside abc module.
         575                 :            : [clinic start generated code]*/
         576                 :            :
         577                 :            : static PyObject *
         578                 :      70253 : _abc__abc_instancecheck_impl(PyObject *module, PyObject *self,
         579                 :            :                              PyObject *instance)
         580                 :            : /*[clinic end generated code: output=b8b5148f63b6b56f input=a4f4525679261084]*/
         581                 :            : {
         582                 :      70253 :     PyObject *subtype, *result = NULL, *subclass = NULL;
         583                 :      70253 :     _abc_data *impl = _get_impl(module, self);
         584         [ -  + ]:      70253 :     if (impl == NULL) {
         585                 :          0 :         return NULL;
         586                 :            :     }
         587                 :            :
         588                 :      70253 :     subclass = PyObject_GetAttr(instance, &_Py_ID(__class__));
         589         [ -  + ]:      70253 :     if (subclass == NULL) {
         590                 :          0 :         Py_DECREF(impl);
         591                 :          0 :         return NULL;
         592                 :            :     }
         593                 :            :     /* Inline the cache checking. */
         594                 :      70253 :     int incache = _in_weak_set(impl->_abc_cache, subclass);
         595         [ -  + ]:      70253 :     if (incache < 0) {
         596                 :          0 :         goto end;
         597                 :            :     }
         598         [ +  + ]:      70253 :     if (incache > 0) {
         599                 :      19711 :         result = Py_NewRef(Py_True);
         600                 :      19711 :         goto end;
         601                 :            :     }
         602                 :      50542 :     subtype = (PyObject *)Py_TYPE(instance);
         603         [ +  - ]:      50542 :     if (subtype == subclass) {
         604         [ +  + ]:      50542 :         if (impl->_abc_negative_cache_version == get_abc_state(module)->abc_invalidation_counter) {
         605                 :      50539 :             incache = _in_weak_set(impl->_abc_negative_cache, subclass);
         606         [ -  + ]:      50539 :             if (incache < 0) {
         607                 :          0 :                 goto end;
         608                 :            :             }
         609         [ +  + ]:      50539 :             if (incache > 0) {
         610                 :      50532 :                 result = Py_NewRef(Py_False);
         611                 :      50532 :                 goto end;
         612                 :            :             }
         613                 :            :         }
         614                 :            :         /* Fall back to the subclass check. */
         615                 :         10 :         result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
         616                 :            :                                            subclass);
         617                 :         10 :         goto end;
         618                 :            :     }
         619                 :          0 :     result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
         620                 :            :                                        subclass);
         621         [ #  # ]:          0 :     if (result == NULL) {
         622                 :          0 :         goto end;
         623                 :            :     }
         624                 :            :
         625   [ #  #  #  # ]:          0 :     switch (PyObject_IsTrue(result)) {
         626                 :          0 :     case -1:
         627                 :          0 :         Py_SETREF(result, NULL);
         628                 :          0 :         break;
         629                 :          0 :     case 0:
         630                 :          0 :         Py_DECREF(result);
         631                 :          0 :         result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
         632                 :            :                                            subtype);
         633                 :          0 :         break;
         634                 :          0 :     case 1:  // Nothing to do.
         635                 :          0 :         break;
         636                 :          0 :     default:
         637                 :          0 :         Py_UNREACHABLE();
         638                 :            :     }
         639                 :            :
         640                 :      70253 : end:
         641                 :      70253 :     Py_XDECREF(impl);
         642                 :      70253 :     Py_XDECREF(subclass);
         643                 :      70253 :     return result;
         644                 :            : }
         645                 :            :
         646                 :            :
         647                 :            : // Return -1 when exception occurred.
         648                 :            : // Return 1 when result is set.
         649                 :            : // Return 0 otherwise.
         650                 :            : static int subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
         651                 :            :                                         PyObject **result);
         652                 :            :
         653                 :            : /*[clinic input]
         654                 :            : _abc._abc_subclasscheck
         655                 :            :
         656                 :            :     self: object
         657                 :            :     subclass: object
         658                 :            :     /
         659                 :            :
         660                 :            : Internal ABC helper for subclasss checks. Should be never used outside abc module.
         661                 :            : [clinic start generated code]*/
         662                 :            :
         663                 :            : static PyObject *
         664                 :       1022 : _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
         665                 :            :                              PyObject *subclass)
         666                 :            : /*[clinic end generated code: output=b56c9e4a530e3894 input=1d947243409d10b8]*/
         667                 :            : {
         668         [ -  + ]:       1022 :     if (!PyType_Check(subclass)) {
         669                 :          0 :         PyErr_SetString(PyExc_TypeError, "issubclass() arg 1 must be a class");
         670                 :          0 :         return NULL;
         671                 :            :     }
         672                 :            :
         673                 :       1022 :     PyObject *ok, *subclasses = NULL, *result = NULL;
         674                 :       1022 :     _abcmodule_state *state = NULL;
         675                 :            :     Py_ssize_t pos;
         676                 :            :     int incache;
         677                 :       1022 :     _abc_data *impl = _get_impl(module, self);
         678         [ -  + ]:       1022 :     if (impl == NULL) {
         679                 :          0 :         return NULL;
         680                 :            :     }
         681                 :            :
         682                 :            :     /* 1. Check cache. */
         683                 :       1022 :     incache = _in_weak_set(impl->_abc_cache, subclass);
         684         [ -  + ]:       1022 :     if (incache < 0) {
         685                 :          0 :         goto end;
         686                 :            :     }
         687         [ -  + ]:       1022 :     if (incache > 0) {
         688                 :          0 :         result = Py_True;
         689                 :          0 :         goto end;
         690                 :            :     }
         691                 :            :
         692                 :       1022 :     state = get_abc_state(module);
         693                 :            :     /* 2. Check negative cache; may have to invalidate. */
         694         [ +  + ]:       1022 :     if (impl->_abc_negative_cache_version < state->abc_invalidation_counter) {
         695                 :            :         /* Invalidate the negative cache. */
         696   [ +  +  -  + ]:        606 :         if (impl->_abc_negative_cache != NULL &&
         697                 :        274 :                 PySet_Clear(impl->_abc_negative_cache) < 0)
         698                 :            :         {
         699                 :          0 :             goto end;
         700                 :            :         }
         701                 :        332 :         impl->_abc_negative_cache_version = state->abc_invalidation_counter;
         702                 :            :     }
         703                 :            :     else {
         704                 :        690 :         incache = _in_weak_set(impl->_abc_negative_cache, subclass);
         705         [ -  + ]:        690 :         if (incache < 0) {
         706                 :          0 :             goto end;
         707                 :            :         }
         708         [ -  + ]:        690 :         if (incache > 0) {
         709                 :          0 :             result = Py_False;
         710                 :          0 :             goto end;
         711                 :            :         }
         712                 :            :     }
         713                 :            :
         714                 :            :     /* 3. Check the subclass hook. */
         715                 :       1022 :     ok = PyObject_CallMethodOneArg(
         716                 :            :             (PyObject *)self, &_Py_ID(__subclasshook__), subclass);
         717         [ -  + ]:       1022 :     if (ok == NULL) {
         718                 :          0 :         goto end;
         719                 :            :     }
         720         [ +  + ]:       1022 :     if (ok == Py_True) {
         721                 :        401 :         Py_DECREF(ok);
         722         [ -  + ]:        401 :         if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
         723                 :          0 :             goto end;
         724                 :            :         }
         725                 :        401 :         result = Py_True;
         726                 :        401 :         goto end;
         727                 :            :     }
         728         [ -  + ]:        621 :     if (ok == Py_False) {
         729                 :          0 :         Py_DECREF(ok);
         730         [ #  # ]:          0 :         if (_add_to_weak_set(&impl->_abc_negative_cache, subclass) < 0) {
         731                 :          0 :             goto end;
         732                 :            :         }
         733                 :          0 :         result = Py_False;
         734                 :          0 :         goto end;
         735                 :            :     }
         736         [ -  + ]:        621 :     if (ok != Py_NotImplemented) {
         737                 :          0 :         Py_DECREF(ok);
         738                 :          0 :         PyErr_SetString(PyExc_AssertionError, "__subclasshook__ must return either"
         739                 :            :                                               " False, True, or NotImplemented");
         740                 :          0 :         goto end;
         741                 :            :     }
         742                 :        621 :     Py_DECREF(ok);
         743                 :            :
         744                 :            :     /* 4. Check if it's a direct subclass. */
         745                 :        621 :     PyObject *mro = ((PyTypeObject *)subclass)->tp_mro;
         746                 :            :     assert(PyTuple_Check(mro));
         747         [ +  + ]:       2262 :     for (pos = 0; pos < PyTuple_GET_SIZE(mro); pos++) {
         748                 :       1642 :         PyObject *mro_item = PyTuple_GET_ITEM(mro, pos);
         749                 :            :         assert(mro_item != NULL);
         750         [ +  + ]:       1642 :         if ((PyObject *)self == mro_item) {
         751         [ -  + ]:          1 :             if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
         752                 :          0 :                 goto end;
         753                 :            :             }
         754                 :          1 :             result = Py_True;
         755                 :          1 :             goto end;
         756                 :            :         }
         757                 :            :     }
         758                 :            :
         759                 :            :     /* 5. Check if it's a subclass of a registered class (recursive). */
         760         [ +  + ]:        620 :     if (subclasscheck_check_registry(impl, subclass, &result)) {
         761                 :            :         // Exception occurred or result is set.
         762                 :          6 :         goto end;
         763                 :            :     }
         764                 :            :
         765                 :            :     /* 6. Check if it's a subclass of a subclass (recursive). */
         766                 :        614 :     subclasses = PyObject_CallMethod(self, "__subclasses__", NULL);
         767         [ -  + ]:        614 :     if (subclasses == NULL) {
         768                 :          0 :         goto end;
         769                 :            :     }
         770         [ -  + ]:        614 :     if (!PyList_Check(subclasses)) {
         771                 :          0 :         PyErr_SetString(PyExc_TypeError, "__subclasses__() must return a list");
         772                 :          0 :         goto end;
         773                 :            :     }
         774         [ +  + ]:        630 :     for (pos = 0; pos < PyList_GET_SIZE(subclasses); pos++) {
         775                 :         18 :         PyObject *scls = PyList_GET_ITEM(subclasses, pos);
         776                 :         18 :         Py_INCREF(scls);
         777                 :         18 :         int r = PyObject_IsSubclass(subclass, scls);
         778                 :         18 :         Py_DECREF(scls);
         779         [ +  + ]:         18 :         if (r > 0) {
         780         [ -  + ]:          2 :             if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
         781                 :          0 :                 goto end;
         782                 :            :             }
         783                 :          2 :             result = Py_True;
         784                 :          2 :             goto end;
         785                 :            :         }
         786         [ -  + ]:         16 :         if (r < 0) {
         787                 :          0 :             goto end;
         788                 :            :         }
         789                 :            :     }
         790                 :            :
         791                 :            :     /* No dice; update negative cache. */
         792         [ -  + ]:        612 :     if (_add_to_weak_set(&impl->_abc_negative_cache, subclass) < 0) {
         793                 :          0 :         goto end;
         794                 :            :     }
         795                 :        612 :     result = Py_False;
         796                 :            :
         797                 :       1022 : end:
         798                 :       1022 :     Py_DECREF(impl);
         799                 :       1022 :     Py_XDECREF(subclasses);
         800                 :       1022 :     return Py_XNewRef(result);
         801                 :            : }
         802                 :            :
         803                 :            :
         804                 :            : static int
         805                 :        620 : subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
         806                 :            :                              PyObject **result)
         807                 :            : {
         808                 :            :     // Fast path: check subclass is in weakref directly.
         809                 :        620 :     int ret = _in_weak_set(impl->_abc_registry, subclass);
         810         [ -  + ]:        620 :     if (ret < 0) {
         811                 :          0 :         *result = NULL;
         812                 :          0 :         return -1;
         813                 :            :     }
         814         [ +  + ]:        620 :     if (ret > 0) {
         815                 :          6 :         *result = Py_True;
         816                 :          6 :         return 1;
         817                 :            :     }
         818                 :            :
         819         [ +  + ]:        614 :     if (impl->_abc_registry == NULL) {
         820                 :        343 :         return 0;
         821                 :            :     }
         822                 :        271 :     Py_ssize_t registry_size = PySet_Size(impl->_abc_registry);
         823         [ -  + ]:        271 :     if (registry_size == 0) {
         824                 :          0 :         return 0;
         825                 :            :     }
         826                 :            :     // Weakref callback may remove entry from set.
         827                 :            :     // So we take snapshot of registry first.
         828                 :        271 :     PyObject **copy = PyMem_Malloc(sizeof(PyObject*) * registry_size);
         829         [ -  + ]:        271 :     if (copy == NULL) {
         830                 :          0 :         PyErr_NoMemory();
         831                 :          0 :         return -1;
         832                 :            :     }
         833                 :            :     PyObject *key;
         834                 :        271 :     Py_ssize_t pos = 0;
         835                 :            :     Py_hash_t hash;
         836                 :        271 :     Py_ssize_t i = 0;
         837                 :            :
         838         [ +  + ]:        783 :     while (_PySet_NextEntry(impl->_abc_registry, &pos, &key, &hash)) {
         839                 :        512 :         copy[i++] = Py_NewRef(key);
         840                 :            :     }
         841                 :            :     assert(i == registry_size);
         842                 :            :
         843         [ +  + ]:        783 :     for (i = 0; i < registry_size; i++) {
         844                 :        512 :         PyObject *rkey = PyWeakref_GetObject(copy[i]);
         845         [ -  + ]:        512 :         if (rkey == NULL) {
         846                 :            :             // Someone inject non-weakref type in the registry.
         847                 :          0 :             ret = -1;
         848                 :          0 :             break;
         849                 :            :         }
         850         [ -  + ]:        512 :         if (rkey == Py_None) {
         851                 :          0 :             continue;
         852                 :            :         }
         853                 :        512 :         Py_INCREF(rkey);
         854                 :        512 :         int r = PyObject_IsSubclass(subclass, rkey);
         855                 :        512 :         Py_DECREF(rkey);
         856         [ -  + ]:        512 :         if (r < 0) {
         857                 :          0 :             ret = -1;
         858                 :          0 :             break;
         859                 :            :         }
         860         [ -  + ]:        512 :         if (r > 0) {
         861         [ #  # ]:          0 :             if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
         862                 :          0 :                 ret = -1;
         863                 :          0 :                 break;
         864                 :            :             }
         865                 :          0 :             *result = Py_True;
         866                 :          0 :             ret = 1;
         867                 :          0 :             break;
         868                 :            :         }
         869                 :            :     }
         870                 :            :
         871         [ +  + ]:        783 :     for (i = 0; i < registry_size; i++) {
         872                 :        512 :         Py_DECREF(copy[i]);
         873                 :            :     }
         874                 :        271 :     PyMem_Free(copy);
         875                 :        271 :     return ret;
         876                 :            : }
         877                 :            :
         878                 :            : /*[clinic input]
         879                 :            : _abc.get_cache_token
         880                 :            :
         881                 :            : Returns the current ABC cache token.
         882                 :            :
         883                 :            : The token is an opaque object (supporting equality testing) identifying the
         884                 :            : current version of the ABC cache for virtual subclasses. The token changes
         885                 :            : with every call to register() on any ABC.
         886                 :            : [clinic start generated code]*/
         887                 :            :
         888                 :            : static PyObject *
         889                 :          0 : _abc_get_cache_token_impl(PyObject *module)
         890                 :            : /*[clinic end generated code: output=c7d87841e033dacc input=70413d1c423ad9f9]*/
         891                 :            : {
         892                 :          0 :     _abcmodule_state *state = get_abc_state(module);
         893                 :          0 :     return PyLong_FromUnsignedLongLong(state->abc_invalidation_counter);
         894                 :            : }
         895                 :            :
         896                 :            : static struct PyMethodDef _abcmodule_methods[] = {
         897                 :            :     _ABC_GET_CACHE_TOKEN_METHODDEF
         898                 :            :     _ABC__ABC_INIT_METHODDEF
         899                 :            :     _ABC__RESET_REGISTRY_METHODDEF
         900                 :            :     _ABC__RESET_CACHES_METHODDEF
         901                 :            :     _ABC__GET_DUMP_METHODDEF
         902                 :            :     _ABC__ABC_REGISTER_METHODDEF
         903                 :            :     _ABC__ABC_INSTANCECHECK_METHODDEF
         904                 :            :     _ABC__ABC_SUBCLASSCHECK_METHODDEF
         905                 :            :     {NULL,       NULL}          /* sentinel */
         906                 :            : };
         907                 :            :
         908                 :            : static int
         909                 :         26 : _abcmodule_exec(PyObject *module)
         910                 :            : {
         911                 :         26 :     _abcmodule_state *state = get_abc_state(module);
         912                 :         26 :     state->abc_invalidation_counter = 0;
         913                 :         26 :     state->_abc_data_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &_abc_data_type_spec, NULL);
         914         [ -  + ]:         26 :     if (state->_abc_data_type == NULL) {
         915                 :          0 :         return -1;
         916                 :            :     }
         917                 :            :
         918                 :         26 :     return 0;
         919                 :            : }
         920                 :            :
         921                 :            : static int
         922                 :        208 : _abcmodule_traverse(PyObject *module, visitproc visit, void *arg)
         923                 :            : {
         924                 :        208 :     _abcmodule_state *state = get_abc_state(module);
         925   [ +  -  -  + ]:        208 :     Py_VISIT(state->_abc_data_type);
         926                 :        208 :     return 0;
         927                 :            : }
         928                 :            :
         929                 :            : static int
         930                 :         46 : _abcmodule_clear(PyObject *module)
         931                 :            : {
         932                 :         46 :     _abcmodule_state *state = get_abc_state(module);
         933         [ +  + ]:         46 :     Py_CLEAR(state->_abc_data_type);
         934                 :         46 :     return 0;
         935                 :            : }
         936                 :            :
         937                 :            : static void
         938                 :         24 : _abcmodule_free(void *module)
         939                 :            : {
         940                 :         24 :     _abcmodule_clear((PyObject *)module);
         941                 :         24 : }
         942                 :            :
         943                 :            : static PyModuleDef_Slot _abcmodule_slots[] = {
         944                 :            :     {Py_mod_exec, _abcmodule_exec},
         945                 :            :     {0, NULL}
         946                 :            : };
         947                 :            :
         948                 :            : static struct PyModuleDef _abcmodule = {
         949                 :            :     PyModuleDef_HEAD_INIT,
         950                 :            :     .m_name = "_abc",
         951                 :            :     .m_doc = _abc__doc__,
         952                 :            :     .m_size = sizeof(_abcmodule_state),
         953                 :            :     .m_methods = _abcmodule_methods,
         954                 :            :     .m_slots = _abcmodule_slots,
         955                 :            :     .m_traverse = _abcmodule_traverse,
         956                 :            :     .m_clear = _abcmodule_clear,
         957                 :            :     .m_free = _abcmodule_free,
         958                 :            : };
         959                 :            :
         960                 :            : PyMODINIT_FUNC
         961                 :         26 : PyInit__abc(void)
         962                 :            : {
         963                 :         26 :     return PyModuleDef_Init(&_abcmodule);
         964                 :            : }

Generated by: LCOV version 1.14