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