blob: 7afaa759b2bfec943679f6f5306fc6037360b9f3 [file] [log] [blame]
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +00001/* ABCMeta implementation */
2
3#include "Python.h"
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +00004#include "clinic/_abc.c.h"
5
6/*[clinic input]
7module _abc
8[clinic start generated code]*/
9/*[clinic end generated code: output=da39a3ee5e6b4b0d input=964f5328e1aefcda]*/
10
11PyDoc_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
Dong-hee Na53e4c912020-03-30 23:35:38 +090022typedef struct {
23 PyTypeObject *_abc_data_type;
Dong-hee Na77c61462020-05-09 17:31:40 +090024 unsigned long long abc_invalidation_counter;
Dong-hee Na53e4c912020-03-30 23:35:38 +090025} _abcmodule_state;
26
Dong-hee Na53e4c912020-03-30 23:35:38 +090027static inline _abcmodule_state*
28get_abc_state(PyObject *module)
29{
30 void *state = PyModule_GetState(module);
31 assert(state != NULL);
32 return (_abcmodule_state *)state;
33}
34
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000035/* This object stores internal state for ABCs.
36 Note that we can use normal sets for caches,
37 since they are never iterated over. */
38typedef 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
Victor Stinner9cc3ebd2020-04-07 18:36:04 +020046static int
47abc_data_traverse(_abc_data *self, visitproc visit, void *arg)
48{
Pablo Galindo1cf15af2020-05-27 10:03:38 +010049 Py_VISIT(Py_TYPE(self));
Victor Stinner9cc3ebd2020-04-07 18:36:04 +020050 Py_VISIT(self->_abc_registry);
51 Py_VISIT(self->_abc_cache);
52 Py_VISIT(self->_abc_negative_cache);
53 return 0;
54}
55
56static int
57abc_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
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000065static void
66abc_data_dealloc(_abc_data *self)
67{
Dong-hee Na53e4c912020-03-30 23:35:38 +090068 PyTypeObject *tp = Py_TYPE(self);
Victor Stinner9cc3ebd2020-04-07 18:36:04 +020069 (void)abc_data_clear(self);
Dong-hee Na53e4c912020-03-30 23:35:38 +090070 tp->tp_free(self);
71 Py_DECREF(tp);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000072}
73
74static PyObject *
75abc_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
76{
77 _abc_data *self = (_abc_data *) type->tp_alloc(type, 0);
Dong-hee Na77c61462020-05-09 17:31:40 +090078 _abcmodule_state *state = NULL;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000079 if (self == NULL) {
80 return NULL;
81 }
82
Dong-hee Na77c61462020-05-09 17:31:40 +090083 state = PyType_GetModuleState(type);
84 if (state == NULL) {
85 Py_DECREF(self);
86 return NULL;
87 }
88
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000089 self->_abc_registry = NULL;
90 self->_abc_cache = NULL;
91 self->_abc_negative_cache = NULL;
Dong-hee Na77c61462020-05-09 17:31:40 +090092 self->_abc_negative_cache_version = state->abc_invalidation_counter;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000093 return (PyObject *) self;
94}
95
96PyDoc_STRVAR(abc_data_doc,
97"Internal state held by ABC machinery.");
98
Dong-hee Na53e4c912020-03-30 23:35:38 +090099static 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},
Victor Stinner9cc3ebd2020-04-07 18:36:04 +0200103 {Py_tp_traverse, abc_data_traverse},
104 {Py_tp_clear, abc_data_clear},
Dong-hee Na53e4c912020-03-30 23:35:38 +0900105 {0, 0}
106};
107
108static PyType_Spec _abc_data_type_spec = {
109 .name = "_abc._abc_data",
110 .basicsize = sizeof(_abc_data),
Victor Stinner9cc3ebd2020-04-07 18:36:04 +0200111 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
Dong-hee Na53e4c912020-03-30 23:35:38 +0900112 .slots = _abc_data_type_spec_slots,
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000113};
114
115static _abc_data *
Dong-hee Na53e4c912020-03-30 23:35:38 +0900116_get_impl(PyObject *module, PyObject *self)
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000117{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900118 _abcmodule_state *state = get_abc_state(module);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000119 PyObject *impl = _PyObject_GetAttrId(self, &PyId__abc_impl);
120 if (impl == NULL) {
121 return NULL;
122 }
Dong-hee Na53e4c912020-03-30 23:35:38 +0900123 if (!Py_IS_TYPE(impl, state->_abc_data_type)) {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000124 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
131static int
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
150static PyObject *
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
167static PyMethodDef _destroy_def = {
168 "_destroy", (PyCFunction) _destroy, METH_O
169};
170
171static int
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
211Internal ABC helper to reset registry of a given class.
212
213Should be only used by refleak.py
214[clinic start generated code]*/
215
216static PyObject *
217_abc__reset_registry(PyObject *module, PyObject *self)
218/*[clinic end generated code: output=92d591a43566cc10 input=12a0b7eb339ac35c]*/
219{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900220 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000221 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
238Internal ABC helper to reset both caches of a given class.
239
240Should be only used by refleak.py
241[clinic start generated code]*/
242
243static PyObject *
244_abc__reset_caches(PyObject *module, PyObject *self)
245/*[clinic end generated code: output=f296f0d5c513f80c input=c0ac616fd8acfb6f]*/
246{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900247 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000248 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
271Internal ABC helper for cache and registry debugging.
272
273Return shallow copies of registry, of both caches, and
274negative cache version. Don't call this function directly,
275instead use ABC._dump_registry() for a nice repr.
276[clinic start generated code]*/
277
278static PyObject *
279_abc__get_dump(PyObject *module, PyObject *self)
280/*[clinic end generated code: output=9d9569a8e2c1c443 input=2c5deb1bfe9e3c79]*/
281{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900282 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000283 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.
296static int
297compute_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;
411error:
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
425Internal ABC helper for class set-up. Should be never used outside abc module.
426[clinic start generated code]*/
427
428static PyObject *
429_abc__abc_init(PyObject *module, PyObject *self)
430/*[clinic end generated code: output=594757375714cda1 input=8d7fe470ff77f029]*/
431{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900432 _abcmodule_state *state = get_abc_state(module);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000433 PyObject *data;
434 if (compute_abstract_methods(self) < 0) {
435 return NULL;
436 }
437
438 /* Set up inheritance registry. */
Dong-hee Na53e4c912020-03-30 23:35:38 +0900439 data = abc_data_new(state->_abc_data_type, NULL, NULL);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000440 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
458Internal ABC helper for subclasss registration. Should be never used outside abc module.
459[clinic start generated code]*/
460
461static PyObject *
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 }
Dong-hee Na53e4c912020-03-30 23:35:38 +0900488 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000489 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 */
Dong-hee Na77c61462020-05-09 17:31:40 +0900499 get_abc_state(module)->abc_invalidation_counter++;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000500
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
513Internal ABC helper for instance checks. Should be never used outside abc module.
514[clinic start generated code]*/
515
516static PyObject *
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;
Dong-hee Na53e4c912020-03-30 23:35:38 +0900522 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000523 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) {
Dong-hee Na77c61462020-05-09 17:31:40 +0900544 if (impl->_abc_negative_cache_version == get_abc_state(module)->abc_invalidation_counter) {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000545 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. */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200556 result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__,
557 subclass);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000558 goto end;
559 }
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200560 result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__,
561 subclass);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000562 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);
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200573 result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__,
574 subtype);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000575 break;
576 case 1: // Nothing to do.
577 break;
578 default:
579 Py_UNREACHABLE();
580 }
581
582end:
583 Py_XDECREF(impl);
584 Py_XDECREF(subclass);
585 return result;
586}
587
588
Min ho Kimf7d72e42019-07-06 07:39:32 +1000589// Return -1 when exception occurred.
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000590// Return 1 when result is set.
591// Return 0 otherwise.
592static 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
602Internal ABC helper for subclasss checks. Should be never used outside abc module.
603[clinic start generated code]*/
604
605static PyObject *
606_abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
607 PyObject *subclass)
608/*[clinic end generated code: output=b56c9e4a530e3894 input=1d947243409d10b8]*/
609{
jab40472dd2018-03-23 00:26:06 +1300610 if (!PyType_Check(subclass)) {
611 PyErr_SetString(PyExc_TypeError, "issubclass() arg 1 must be a class");
612 return NULL;
613 }
614
INADA Naokif757b722018-03-22 21:52:42 +0900615 PyObject *ok, *subclasses = NULL, *result = NULL;
Dong-hee Na77c61462020-05-09 17:31:40 +0900616 _abcmodule_state *state = NULL;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000617 Py_ssize_t pos;
618 int incache;
Dong-hee Na53e4c912020-03-30 23:35:38 +0900619 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000620 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
Dong-hee Na77c61462020-05-09 17:31:40 +0900634 state = get_abc_state(module);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000635 /* 2. Check negative cache; may have to invalidate. */
Dong-hee Na77c61462020-05-09 17:31:40 +0900636 if (impl->_abc_negative_cache_version < state->abc_invalidation_counter) {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000637 /* Invalidate the negative cache. */
638 if (impl->_abc_negative_cache != NULL &&
639 PySet_Clear(impl->_abc_negative_cache) < 0)
640 {
641 goto end;
642 }
Dong-hee Na77c61462020-05-09 17:31:40 +0900643 impl->_abc_negative_cache_version = state->abc_invalidation_counter;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000644 }
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. */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200657 ok = _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId___subclasshook__,
658 subclass);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000659 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
INADA Naokif757b722018-03-22 21:52:42 +0900686 /* 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);
INADA Naokic65bf3f2018-03-23 18:19:34 +0900691 assert(mro_item != NULL);
INADA Naokif757b722018-03-22 21:52:42 +0900692 if ((PyObject *)self == mro_item) {
693 if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000694 goto end;
695 }
INADA Naokif757b722018-03-22 21:52:42 +0900696 result = Py_True;
697 goto end;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000698 }
699 }
700
701 /* 5. Check if it's a subclass of a registered class (recursive). */
702 if (subclasscheck_check_registry(impl, subclass, &result)) {
Min ho Kimf7d72e42019-07-06 07:39:32 +1000703 // Exception occurred or result is set.
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000704 goto end;
705 }
706
707 /* 6. Check if it's a subclass of a subclass (recursive). */
708 subclasses = PyObject_CallMethod(self, "__subclasses__", NULL);
Alexey Izbyshevcdbf50c2018-08-20 23:04:19 +0300709 if (subclasses == NULL) {
710 goto end;
711 }
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000712 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
739end:
INADA Naokifc7df0e2018-03-07 16:27:01 +0900740 Py_DECREF(impl);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000741 Py_XDECREF(subclasses);
742 Py_XINCREF(result);
743 return result;
744}
745
746
747static int
748subclasscheck_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);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700772 if (copy == NULL) {
773 PyErr_NoMemory();
774 return -1;
775 }
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000776 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
825Returns the current ABC cache token.
826
827The token is an opaque object (supporting equality testing) identifying the
828current version of the ABC cache for virtual subclasses. The token changes
829with every call to register() on any ABC.
830[clinic start generated code]*/
831
832static PyObject *
833_abc_get_cache_token_impl(PyObject *module)
834/*[clinic end generated code: output=c7d87841e033dacc input=70413d1c423ad9f9]*/
835{
Dong-hee Na77c61462020-05-09 17:31:40 +0900836 _abcmodule_state *state = get_abc_state(module);
837 return PyLong_FromUnsignedLongLong(state->abc_invalidation_counter);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000838}
839
Dong-hee Na53e4c912020-03-30 23:35:38 +0900840static struct PyMethodDef _abcmodule_methods[] = {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000841 _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
Hai Shi4c1b6a62020-02-17 21:50:35 +0800852static int
Dong-hee Na53e4c912020-03-30 23:35:38 +0900853_abcmodule_exec(PyObject *module)
Hai Shi4c1b6a62020-02-17 21:50:35 +0800854{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900855 _abcmodule_state *state = get_abc_state(module);
Dong-hee Na77c61462020-05-09 17:31:40 +0900856 state->abc_invalidation_counter = 0;
857 state->_abc_data_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &_abc_data_type_spec, NULL);
Dong-hee Na53e4c912020-03-30 23:35:38 +0900858 if (state->_abc_data_type == NULL) {
Hai Shi4c1b6a62020-02-17 21:50:35 +0800859 return -1;
860 }
Dong-hee Na53e4c912020-03-30 23:35:38 +0900861
Hai Shi4c1b6a62020-02-17 21:50:35 +0800862 return 0;
863}
864
Dong-hee Na53e4c912020-03-30 23:35:38 +0900865static int
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
873static int
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
881static void
882_abcmodule_free(void *module)
883{
884 _abcmodule_clear((PyObject *)module);
885}
886
887static PyModuleDef_Slot _abcmodule_slots[] = {
888 {Py_mod_exec, _abcmodule_exec},
Hai Shi4c1b6a62020-02-17 21:50:35 +0800889 {0, NULL}
890};
891
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000892static struct PyModuleDef _abcmodule = {
893 PyModuleDef_HEAD_INIT,
Victor Stinnerc8c42002020-10-26 23:19:22 +0100894 .m_name = "_abc",
895 .m_doc = _abc__doc__,
896 .m_size = sizeof(_abcmodule_state),
897 .m_methods = _abcmodule_methods,
898 .m_slots = _abcmodule_slots,
899 .m_traverse = _abcmodule_traverse,
900 .m_clear = _abcmodule_clear,
901 .m_free = _abcmodule_free,
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000902};
903
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000904PyMODINIT_FUNC
905PyInit__abc(void)
906{
Hai Shi4c1b6a62020-02-17 21:50:35 +0800907 return PyModuleDef_Init(&_abcmodule);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000908}