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