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