LCOV - code coverage report
Current view: top level - Modules - _abc.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 361 463 78.0 %
Date: 2022-07-20 13:12:14 Functions: 24 25 96.0 %
Branches: 190 278 68.3 %

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

Generated by: LCOV version 1.14