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