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