blob: 1fbf3a831007bd677212f2f64c1ef063d5c8b11c [file] [log] [blame]
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +00001/* ABCMeta implementation */
2
3#include "Python.h"
4#include "structmember.h"
5#include "clinic/_abc.c.h"
6
7/*[clinic input]
8module _abc
9[clinic start generated code]*/
10/*[clinic end generated code: output=da39a3ee5e6b4b0d input=964f5328e1aefcda]*/
11
12PyDoc_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. */
28static 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. */
33typedef 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
41static void
42abc_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
50static PyObject *
51abc_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
65PyDoc_STRVAR(abc_data_doc,
66"Internal state held by ABC machinery.");
67
68static PyTypeObject _abc_data_type = {
E. M. Brayabe59222019-02-24 02:30:14 +010069 PyVarObject_HEAD_INIT(NULL, 0)
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000070 "_abc_data", /*tp_name*/
Peter Eisentraut0e0bc4e2018-09-10 18:46:08 +020071 sizeof(_abc_data), /*tp_basicsize*/
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000072 .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
78static _abc_data *
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
93static int
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
112static PyObject *
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
129static PyMethodDef _destroy_def = {
130 "_destroy", (PyCFunction) _destroy, METH_O
131};
132
133static int
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
173Internal ABC helper to reset registry of a given class.
174
175Should be only used by refleak.py
176[clinic start generated code]*/
177
178static PyObject *
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
200Internal ABC helper to reset both caches of a given class.
201
202Should be only used by refleak.py
203[clinic start generated code]*/
204
205static PyObject *
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
233Internal ABC helper for cache and registry debugging.
234
235Return shallow copies of registry, of both caches, and
236negative cache version. Don't call this function directly,
237instead use ABC._dump_registry() for a nice repr.
238[clinic start generated code]*/
239
240static PyObject *
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.
258static int
259compute_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;
373error:
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
387Internal ABC helper for class set-up. Should be never used outside abc module.
388[clinic start generated code]*/
389
390static PyObject *
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
419Internal ABC helper for subclasss registration. Should be never used outside abc module.
420[clinic start generated code]*/
421
422static PyObject *
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
474Internal ABC helper for instance checks. Should be never used outside abc module.
475[clinic start generated code]*/
476
477static PyObject *
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
543end:
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.
553static 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
563Internal ABC helper for subclasss checks. Should be never used outside abc module.
564[clinic start generated code]*/
565
566static PyObject *
567_abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
568 PyObject *subclass)
569/*[clinic end generated code: output=b56c9e4a530e3894 input=1d947243409d10b8]*/
570{
jab40472dd2018-03-23 00:26:06 +1300571 if (!PyType_Check(subclass)) {
572 PyErr_SetString(PyExc_TypeError, "issubclass() arg 1 must be a class");
573 return NULL;
574 }
575
INADA Naokif757b722018-03-22 21:52:42 +0900576 PyObject *ok, *subclasses = NULL, *result = NULL;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000577 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
INADA Naokif757b722018-03-22 21:52:42 +0900645 /* 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);
INADA Naokic65bf3f2018-03-23 18:19:34 +0900650 assert(mro_item != NULL);
INADA Naokif757b722018-03-22 21:52:42 +0900651 if ((PyObject *)self == mro_item) {
652 if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000653 goto end;
654 }
INADA Naokif757b722018-03-22 21:52:42 +0900655 result = Py_True;
656 goto end;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000657 }
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);
Alexey Izbyshevcdbf50c2018-08-20 23:04:19 +0300668 if (subclasses == NULL) {
669 goto end;
670 }
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000671 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
698end:
INADA Naokifc7df0e2018-03-07 16:27:01 +0900699 Py_DECREF(impl);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000700 Py_XDECREF(subclasses);
701 Py_XINCREF(result);
702 return result;
703}
704
705
706static int
707subclasscheck_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);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700731 if (copy == NULL) {
732 PyErr_NoMemory();
733 return -1;
734 }
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000735 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
784Returns the current ABC cache token.
785
786The token is an opaque object (supporting equality testing) identifying the
787current version of the ABC cache for virtual subclasses. The token changes
788with every call to register() on any ABC.
789[clinic start generated code]*/
790
791static PyObject *
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
798static 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
810static 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
823PyMODINIT_FUNC
824PyInit__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}