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