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