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