blob: 0ddc2abeee1e0e778b4b6ad487bbeabc1571d88b [file] [log] [blame]
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +00001/* ABCMeta implementation */
2
3#include "Python.h"
Victor Stinnercdad2722021-04-22 00:52:52 +02004#include "pycore_moduleobject.h" // _PyModule_GetState()
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +00005#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;
Dong-hee Na77c61462020-05-09 17:31:40 +090025 unsigned long long abc_invalidation_counter;
Dong-hee Na53e4c912020-03-30 23:35:38 +090026} _abcmodule_state;
27
Dong-hee Na53e4c912020-03-30 23:35:38 +090028static inline _abcmodule_state*
29get_abc_state(PyObject *module)
30{
Victor Stinnercdad2722021-04-22 00:52:52 +020031 void *state = _PyModule_GetState(module);
Dong-hee Na53e4c912020-03-30 23:35:38 +090032 assert(state != NULL);
33 return (_abcmodule_state *)state;
34}
35
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000036/* This object stores internal state for ABCs.
37 Note that we can use normal sets for caches,
38 since they are never iterated over. */
39typedef struct {
40 PyObject_HEAD
41 PyObject *_abc_registry;
42 PyObject *_abc_cache; /* Normal set of weak references. */
43 PyObject *_abc_negative_cache; /* Normal set of weak references. */
44 unsigned long long _abc_negative_cache_version;
45} _abc_data;
46
Victor Stinner9cc3ebd2020-04-07 18:36:04 +020047static int
48abc_data_traverse(_abc_data *self, visitproc visit, void *arg)
49{
Pablo Galindo1cf15af2020-05-27 10:03:38 +010050 Py_VISIT(Py_TYPE(self));
Victor Stinner9cc3ebd2020-04-07 18:36:04 +020051 Py_VISIT(self->_abc_registry);
52 Py_VISIT(self->_abc_cache);
53 Py_VISIT(self->_abc_negative_cache);
54 return 0;
55}
56
57static int
58abc_data_clear(_abc_data *self)
59{
60 Py_CLEAR(self->_abc_registry);
61 Py_CLEAR(self->_abc_cache);
62 Py_CLEAR(self->_abc_negative_cache);
63 return 0;
64}
65
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000066static void
67abc_data_dealloc(_abc_data *self)
68{
Dong-hee Na53e4c912020-03-30 23:35:38 +090069 PyTypeObject *tp = Py_TYPE(self);
Victor Stinner9cc3ebd2020-04-07 18:36:04 +020070 (void)abc_data_clear(self);
Dong-hee Na53e4c912020-03-30 23:35:38 +090071 tp->tp_free(self);
72 Py_DECREF(tp);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000073}
74
75static PyObject *
76abc_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
77{
78 _abc_data *self = (_abc_data *) type->tp_alloc(type, 0);
Dong-hee Na77c61462020-05-09 17:31:40 +090079 _abcmodule_state *state = NULL;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000080 if (self == NULL) {
81 return NULL;
82 }
83
Dong-hee Na77c61462020-05-09 17:31:40 +090084 state = PyType_GetModuleState(type);
85 if (state == NULL) {
86 Py_DECREF(self);
87 return NULL;
88 }
89
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000090 self->_abc_registry = NULL;
91 self->_abc_cache = NULL;
92 self->_abc_negative_cache = NULL;
Dong-hee Na77c61462020-05-09 17:31:40 +090093 self->_abc_negative_cache_version = state->abc_invalidation_counter;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +000094 return (PyObject *) self;
95}
96
97PyDoc_STRVAR(abc_data_doc,
98"Internal state held by ABC machinery.");
99
Dong-hee Na53e4c912020-03-30 23:35:38 +0900100static PyType_Slot _abc_data_type_spec_slots[] = {
101 {Py_tp_doc, (void *)abc_data_doc},
102 {Py_tp_new, abc_data_new},
103 {Py_tp_dealloc, abc_data_dealloc},
Victor Stinner9cc3ebd2020-04-07 18:36:04 +0200104 {Py_tp_traverse, abc_data_traverse},
105 {Py_tp_clear, abc_data_clear},
Dong-hee Na53e4c912020-03-30 23:35:38 +0900106 {0, 0}
107};
108
109static PyType_Spec _abc_data_type_spec = {
110 .name = "_abc._abc_data",
111 .basicsize = sizeof(_abc_data),
Victor Stinner9cc3ebd2020-04-07 18:36:04 +0200112 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
Dong-hee Na53e4c912020-03-30 23:35:38 +0900113 .slots = _abc_data_type_spec_slots,
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000114};
115
116static _abc_data *
Dong-hee Na53e4c912020-03-30 23:35:38 +0900117_get_impl(PyObject *module, PyObject *self)
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000118{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900119 _abcmodule_state *state = get_abc_state(module);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000120 PyObject *impl = _PyObject_GetAttrId(self, &PyId__abc_impl);
121 if (impl == NULL) {
122 return NULL;
123 }
Dong-hee Na53e4c912020-03-30 23:35:38 +0900124 if (!Py_IS_TYPE(impl, state->_abc_data_type)) {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000125 PyErr_SetString(PyExc_TypeError, "_abc_impl is set to a wrong type");
126 Py_DECREF(impl);
127 return NULL;
128 }
129 return (_abc_data *)impl;
130}
131
132static int
133_in_weak_set(PyObject *set, PyObject *obj)
134{
135 if (set == NULL || PySet_GET_SIZE(set) == 0) {
136 return 0;
137 }
138 PyObject *ref = PyWeakref_NewRef(obj, NULL);
139 if (ref == NULL) {
140 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
141 PyErr_Clear();
142 return 0;
143 }
144 return -1;
145 }
146 int res = PySet_Contains(set, ref);
147 Py_DECREF(ref);
148 return res;
149}
150
151static PyObject *
152_destroy(PyObject *setweakref, PyObject *objweakref)
153{
154 PyObject *set;
155 set = PyWeakref_GET_OBJECT(setweakref);
156 if (set == Py_None) {
157 Py_RETURN_NONE;
158 }
159 Py_INCREF(set);
160 if (PySet_Discard(set, objweakref) < 0) {
161 Py_DECREF(set);
162 return NULL;
163 }
164 Py_DECREF(set);
165 Py_RETURN_NONE;
166}
167
168static PyMethodDef _destroy_def = {
169 "_destroy", (PyCFunction) _destroy, METH_O
170};
171
172static int
173_add_to_weak_set(PyObject **pset, PyObject *obj)
174{
175 if (*pset == NULL) {
176 *pset = PySet_New(NULL);
177 if (*pset == NULL) {
178 return -1;
179 }
180 }
181
182 PyObject *set = *pset;
183 PyObject *ref, *wr;
184 PyObject *destroy_cb;
185 wr = PyWeakref_NewRef(set, NULL);
186 if (wr == NULL) {
187 return -1;
188 }
189 destroy_cb = PyCFunction_NewEx(&_destroy_def, wr, NULL);
190 if (destroy_cb == NULL) {
191 Py_DECREF(wr);
192 return -1;
193 }
194 ref = PyWeakref_NewRef(obj, destroy_cb);
195 Py_DECREF(destroy_cb);
196 if (ref == NULL) {
197 Py_DECREF(wr);
198 return -1;
199 }
200 int ret = PySet_Add(set, ref);
201 Py_DECREF(wr);
202 Py_DECREF(ref);
203 return ret;
204}
205
206/*[clinic input]
207_abc._reset_registry
208
209 self: object
210 /
211
212Internal ABC helper to reset registry of a given class.
213
214Should be only used by refleak.py
215[clinic start generated code]*/
216
217static PyObject *
218_abc__reset_registry(PyObject *module, PyObject *self)
219/*[clinic end generated code: output=92d591a43566cc10 input=12a0b7eb339ac35c]*/
220{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900221 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000222 if (impl == NULL) {
223 return NULL;
224 }
225 if (impl->_abc_registry != NULL && PySet_Clear(impl->_abc_registry) < 0) {
226 Py_DECREF(impl);
227 return NULL;
228 }
229 Py_DECREF(impl);
230 Py_RETURN_NONE;
231}
232
233/*[clinic input]
234_abc._reset_caches
235
236 self: object
237 /
238
239Internal ABC helper to reset both caches of a given class.
240
241Should be only used by refleak.py
242[clinic start generated code]*/
243
244static PyObject *
245_abc__reset_caches(PyObject *module, PyObject *self)
246/*[clinic end generated code: output=f296f0d5c513f80c input=c0ac616fd8acfb6f]*/
247{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900248 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000249 if (impl == NULL) {
250 return NULL;
251 }
252 if (impl->_abc_cache != NULL && PySet_Clear(impl->_abc_cache) < 0) {
253 Py_DECREF(impl);
254 return NULL;
255 }
256 /* also the second cache */
257 if (impl->_abc_negative_cache != NULL &&
258 PySet_Clear(impl->_abc_negative_cache) < 0) {
259 Py_DECREF(impl);
260 return NULL;
261 }
262 Py_DECREF(impl);
263 Py_RETURN_NONE;
264}
265
266/*[clinic input]
267_abc._get_dump
268
269 self: object
270 /
271
272Internal ABC helper for cache and registry debugging.
273
274Return shallow copies of registry, of both caches, and
275negative cache version. Don't call this function directly,
276instead use ABC._dump_registry() for a nice repr.
277[clinic start generated code]*/
278
279static PyObject *
280_abc__get_dump(PyObject *module, PyObject *self)
281/*[clinic end generated code: output=9d9569a8e2c1c443 input=2c5deb1bfe9e3c79]*/
282{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900283 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000284 if (impl == NULL) {
285 return NULL;
286 }
287 PyObject *res = Py_BuildValue("NNNK",
288 PySet_New(impl->_abc_registry),
289 PySet_New(impl->_abc_cache),
290 PySet_New(impl->_abc_negative_cache),
291 impl->_abc_negative_cache_version);
292 Py_DECREF(impl);
293 return res;
294}
295
296// Compute set of abstract method names.
297static int
298compute_abstract_methods(PyObject *self)
299{
300 int ret = -1;
301 PyObject *abstracts = PyFrozenSet_New(NULL);
302 if (abstracts == NULL) {
303 return -1;
304 }
305
306 PyObject *ns = NULL, *items = NULL, *bases = NULL; // Py_XDECREF()ed on error.
307
308 /* Stage 1: direct abstract methods. */
309 ns = _PyObject_GetAttrId(self, &PyId___dict__);
310 if (!ns) {
311 goto error;
312 }
313
314 // We can't use PyDict_Next(ns) even when ns is dict because
315 // _PyObject_IsAbstract() can mutate ns.
316 items = PyMapping_Items(ns);
317 if (!items) {
318 goto error;
319 }
320 assert(PyList_Check(items));
321 for (Py_ssize_t pos = 0; pos < PyList_GET_SIZE(items); pos++) {
322 PyObject *it = PySequence_Fast(
323 PyList_GET_ITEM(items, pos),
324 "items() returned non-iterable");
325 if (!it) {
326 goto error;
327 }
328 if (PySequence_Fast_GET_SIZE(it) != 2) {
329 PyErr_SetString(PyExc_TypeError,
330 "items() returned item which size is not 2");
331 Py_DECREF(it);
332 goto error;
333 }
334
335 // borrowed
336 PyObject *key = PySequence_Fast_GET_ITEM(it, 0);
337 PyObject *value = PySequence_Fast_GET_ITEM(it, 1);
338 // items or it may be cleared while accessing __abstractmethod__
339 // So we need to keep strong reference for key
340 Py_INCREF(key);
341 int is_abstract = _PyObject_IsAbstract(value);
342 if (is_abstract < 0 ||
343 (is_abstract && PySet_Add(abstracts, key) < 0)) {
344 Py_DECREF(it);
345 Py_DECREF(key);
346 goto error;
347 }
348 Py_DECREF(key);
349 Py_DECREF(it);
350 }
351
352 /* Stage 2: inherited abstract methods. */
353 bases = _PyObject_GetAttrId(self, &PyId___bases__);
354 if (!bases) {
355 goto error;
356 }
357 if (!PyTuple_Check(bases)) {
358 PyErr_SetString(PyExc_TypeError, "__bases__ is not tuple");
359 goto error;
360 }
361
362 for (Py_ssize_t pos = 0; pos < PyTuple_GET_SIZE(bases); pos++) {
363 PyObject *item = PyTuple_GET_ITEM(bases, pos); // borrowed
364 PyObject *base_abstracts, *iter;
365
366 if (_PyObject_LookupAttrId(item, &PyId___abstractmethods__,
367 &base_abstracts) < 0) {
368 goto error;
369 }
370 if (base_abstracts == NULL) {
371 continue;
372 }
373 if (!(iter = PyObject_GetIter(base_abstracts))) {
374 Py_DECREF(base_abstracts);
375 goto error;
376 }
377 Py_DECREF(base_abstracts);
378 PyObject *key, *value;
379 while ((key = PyIter_Next(iter))) {
380 if (_PyObject_LookupAttr(self, key, &value) < 0) {
381 Py_DECREF(key);
382 Py_DECREF(iter);
383 goto error;
384 }
385 if (value == NULL) {
386 Py_DECREF(key);
387 continue;
388 }
389
390 int is_abstract = _PyObject_IsAbstract(value);
391 Py_DECREF(value);
392 if (is_abstract < 0 ||
393 (is_abstract && PySet_Add(abstracts, key) < 0))
394 {
395 Py_DECREF(key);
396 Py_DECREF(iter);
397 goto error;
398 }
399 Py_DECREF(key);
400 }
401 Py_DECREF(iter);
402 if (PyErr_Occurred()) {
403 goto error;
404 }
405 }
406
407 if (_PyObject_SetAttrId(self, &PyId___abstractmethods__, abstracts) < 0) {
408 goto error;
409 }
410
411 ret = 0;
412error:
413 Py_DECREF(abstracts);
414 Py_XDECREF(ns);
415 Py_XDECREF(items);
416 Py_XDECREF(bases);
417 return ret;
418}
419
420/*[clinic input]
421_abc._abc_init
422
423 self: object
424 /
425
426Internal ABC helper for class set-up. Should be never used outside abc module.
427[clinic start generated code]*/
428
429static PyObject *
430_abc__abc_init(PyObject *module, PyObject *self)
431/*[clinic end generated code: output=594757375714cda1 input=8d7fe470ff77f029]*/
432{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900433 _abcmodule_state *state = get_abc_state(module);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000434 PyObject *data;
435 if (compute_abstract_methods(self) < 0) {
436 return NULL;
437 }
438
439 /* Set up inheritance registry. */
Dong-hee Na53e4c912020-03-30 23:35:38 +0900440 data = abc_data_new(state->_abc_data_type, NULL, NULL);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000441 if (data == NULL) {
442 return NULL;
443 }
444 if (_PyObject_SetAttrId(self, &PyId__abc_impl, data) < 0) {
445 Py_DECREF(data);
446 return NULL;
447 }
448 Py_DECREF(data);
449 Py_RETURN_NONE;
450}
451
452/*[clinic input]
453_abc._abc_register
454
455 self: object
456 subclass: object
457 /
458
459Internal ABC helper for subclasss registration. Should be never used outside abc module.
460[clinic start generated code]*/
461
462static PyObject *
463_abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass)
464/*[clinic end generated code: output=7851e7668c963524 input=ca589f8c3080e67f]*/
465{
466 if (!PyType_Check(subclass)) {
467 PyErr_SetString(PyExc_TypeError, "Can only register classes");
468 return NULL;
469 }
470 int result = PyObject_IsSubclass(subclass, self);
471 if (result > 0) {
472 Py_INCREF(subclass);
473 return subclass; /* Already a subclass. */
474 }
475 if (result < 0) {
476 return NULL;
477 }
478 /* Subtle: test for cycles *after* testing for "already a subclass";
479 this means we allow X.register(X) and interpret it as a no-op. */
480 result = PyObject_IsSubclass(self, subclass);
481 if (result > 0) {
482 /* This would create a cycle, which is bad for the algorithm below. */
483 PyErr_SetString(PyExc_RuntimeError, "Refusing to create an inheritance cycle");
484 return NULL;
485 }
486 if (result < 0) {
487 return NULL;
488 }
Dong-hee Na53e4c912020-03-30 23:35:38 +0900489 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000490 if (impl == NULL) {
491 return NULL;
492 }
493 if (_add_to_weak_set(&impl->_abc_registry, subclass) < 0) {
494 Py_DECREF(impl);
495 return NULL;
496 }
497 Py_DECREF(impl);
498
499 /* Invalidate negative cache */
Dong-hee Na77c61462020-05-09 17:31:40 +0900500 get_abc_state(module)->abc_invalidation_counter++;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000501
502 Py_INCREF(subclass);
503 return subclass;
504}
505
506
507/*[clinic input]
508_abc._abc_instancecheck
509
510 self: object
511 instance: object
512 /
513
514Internal ABC helper for instance checks. Should be never used outside abc module.
515[clinic start generated code]*/
516
517static PyObject *
518_abc__abc_instancecheck_impl(PyObject *module, PyObject *self,
519 PyObject *instance)
520/*[clinic end generated code: output=b8b5148f63b6b56f input=a4f4525679261084]*/
521{
522 PyObject *subtype, *result = NULL, *subclass = NULL;
Dong-hee Na53e4c912020-03-30 23:35:38 +0900523 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000524 if (impl == NULL) {
525 return NULL;
526 }
527
528 subclass = _PyObject_GetAttrId(instance, &PyId___class__);
529 if (subclass == NULL) {
530 Py_DECREF(impl);
531 return NULL;
532 }
533 /* Inline the cache checking. */
534 int incache = _in_weak_set(impl->_abc_cache, subclass);
535 if (incache < 0) {
536 goto end;
537 }
538 if (incache > 0) {
539 result = Py_True;
540 Py_INCREF(result);
541 goto end;
542 }
543 subtype = (PyObject *)Py_TYPE(instance);
544 if (subtype == subclass) {
Dong-hee Na77c61462020-05-09 17:31:40 +0900545 if (impl->_abc_negative_cache_version == get_abc_state(module)->abc_invalidation_counter) {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000546 incache = _in_weak_set(impl->_abc_negative_cache, subclass);
547 if (incache < 0) {
548 goto end;
549 }
550 if (incache > 0) {
551 result = Py_False;
552 Py_INCREF(result);
553 goto end;
554 }
555 }
556 /* Fall back to the subclass check. */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200557 result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__,
558 subclass);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000559 goto end;
560 }
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200561 result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__,
562 subclass);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000563 if (result == NULL) {
564 goto end;
565 }
566
567 switch (PyObject_IsTrue(result)) {
568 case -1:
569 Py_DECREF(result);
570 result = NULL;
571 break;
572 case 0:
573 Py_DECREF(result);
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200574 result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__,
575 subtype);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000576 break;
577 case 1: // Nothing to do.
578 break;
579 default:
580 Py_UNREACHABLE();
581 }
582
583end:
584 Py_XDECREF(impl);
585 Py_XDECREF(subclass);
586 return result;
587}
588
589
Min ho Kimf7d72e42019-07-06 07:39:32 +1000590// Return -1 when exception occurred.
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000591// Return 1 when result is set.
592// Return 0 otherwise.
593static int subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
594 PyObject **result);
595
596/*[clinic input]
597_abc._abc_subclasscheck
598
599 self: object
600 subclass: object
601 /
602
603Internal ABC helper for subclasss checks. Should be never used outside abc module.
604[clinic start generated code]*/
605
606static PyObject *
607_abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
608 PyObject *subclass)
609/*[clinic end generated code: output=b56c9e4a530e3894 input=1d947243409d10b8]*/
610{
jab40472dd2018-03-23 00:26:06 +1300611 if (!PyType_Check(subclass)) {
612 PyErr_SetString(PyExc_TypeError, "issubclass() arg 1 must be a class");
613 return NULL;
614 }
615
INADA Naokif757b722018-03-22 21:52:42 +0900616 PyObject *ok, *subclasses = NULL, *result = NULL;
Dong-hee Na77c61462020-05-09 17:31:40 +0900617 _abcmodule_state *state = NULL;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000618 Py_ssize_t pos;
619 int incache;
Dong-hee Na53e4c912020-03-30 23:35:38 +0900620 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000621 if (impl == NULL) {
622 return NULL;
623 }
624
625 /* 1. Check cache. */
626 incache = _in_weak_set(impl->_abc_cache, subclass);
627 if (incache < 0) {
628 goto end;
629 }
630 if (incache > 0) {
631 result = Py_True;
632 goto end;
633 }
634
Dong-hee Na77c61462020-05-09 17:31:40 +0900635 state = get_abc_state(module);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000636 /* 2. Check negative cache; may have to invalidate. */
Dong-hee Na77c61462020-05-09 17:31:40 +0900637 if (impl->_abc_negative_cache_version < state->abc_invalidation_counter) {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000638 /* Invalidate the negative cache. */
639 if (impl->_abc_negative_cache != NULL &&
640 PySet_Clear(impl->_abc_negative_cache) < 0)
641 {
642 goto end;
643 }
Dong-hee Na77c61462020-05-09 17:31:40 +0900644 impl->_abc_negative_cache_version = state->abc_invalidation_counter;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000645 }
646 else {
647 incache = _in_weak_set(impl->_abc_negative_cache, subclass);
648 if (incache < 0) {
649 goto end;
650 }
651 if (incache > 0) {
652 result = Py_False;
653 goto end;
654 }
655 }
656
657 /* 3. Check the subclass hook. */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200658 ok = _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId___subclasshook__,
659 subclass);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000660 if (ok == NULL) {
661 goto end;
662 }
663 if (ok == Py_True) {
664 Py_DECREF(ok);
665 if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
666 goto end;
667 }
668 result = Py_True;
669 goto end;
670 }
671 if (ok == Py_False) {
672 Py_DECREF(ok);
673 if (_add_to_weak_set(&impl->_abc_negative_cache, subclass) < 0) {
674 goto end;
675 }
676 result = Py_False;
677 goto end;
678 }
679 if (ok != Py_NotImplemented) {
680 Py_DECREF(ok);
681 PyErr_SetString(PyExc_AssertionError, "__subclasshook__ must return either"
682 " False, True, or NotImplemented");
683 goto end;
684 }
685 Py_DECREF(ok);
686
INADA Naokif757b722018-03-22 21:52:42 +0900687 /* 4. Check if it's a direct subclass. */
688 PyObject *mro = ((PyTypeObject *)subclass)->tp_mro;
689 assert(PyTuple_Check(mro));
690 for (pos = 0; pos < PyTuple_GET_SIZE(mro); pos++) {
691 PyObject *mro_item = PyTuple_GET_ITEM(mro, pos);
INADA Naokic65bf3f2018-03-23 18:19:34 +0900692 assert(mro_item != NULL);
INADA Naokif757b722018-03-22 21:52:42 +0900693 if ((PyObject *)self == mro_item) {
694 if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000695 goto end;
696 }
INADA Naokif757b722018-03-22 21:52:42 +0900697 result = Py_True;
698 goto end;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000699 }
700 }
701
702 /* 5. Check if it's a subclass of a registered class (recursive). */
703 if (subclasscheck_check_registry(impl, subclass, &result)) {
Min ho Kimf7d72e42019-07-06 07:39:32 +1000704 // Exception occurred or result is set.
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000705 goto end;
706 }
707
708 /* 6. Check if it's a subclass of a subclass (recursive). */
709 subclasses = PyObject_CallMethod(self, "__subclasses__", NULL);
Alexey Izbyshevcdbf50c2018-08-20 23:04:19 +0300710 if (subclasses == NULL) {
711 goto end;
712 }
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000713 if (!PyList_Check(subclasses)) {
714 PyErr_SetString(PyExc_TypeError, "__subclasses__() must return a list");
715 goto end;
716 }
717 for (pos = 0; pos < PyList_GET_SIZE(subclasses); pos++) {
718 PyObject *scls = PyList_GET_ITEM(subclasses, pos);
719 Py_INCREF(scls);
720 int r = PyObject_IsSubclass(subclass, scls);
721 Py_DECREF(scls);
722 if (r > 0) {
723 if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
724 goto end;
725 }
726 result = Py_True;
727 goto end;
728 }
729 if (r < 0) {
730 goto end;
731 }
732 }
733
734 /* No dice; update negative cache. */
735 if (_add_to_weak_set(&impl->_abc_negative_cache, subclass) < 0) {
736 goto end;
737 }
738 result = Py_False;
739
740end:
INADA Naokifc7df0e2018-03-07 16:27:01 +0900741 Py_DECREF(impl);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000742 Py_XDECREF(subclasses);
743 Py_XINCREF(result);
744 return result;
745}
746
747
748static int
749subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
750 PyObject **result)
751{
752 // Fast path: check subclass is in weakref directly.
753 int ret = _in_weak_set(impl->_abc_registry, subclass);
754 if (ret < 0) {
755 *result = NULL;
756 return -1;
757 }
758 if (ret > 0) {
759 *result = Py_True;
760 return 1;
761 }
762
763 if (impl->_abc_registry == NULL) {
764 return 0;
765 }
766 Py_ssize_t registry_size = PySet_Size(impl->_abc_registry);
767 if (registry_size == 0) {
768 return 0;
769 }
770 // Weakref callback may remove entry from set.
771 // So we take snapshot of registry first.
772 PyObject **copy = PyMem_Malloc(sizeof(PyObject*) * registry_size);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700773 if (copy == NULL) {
774 PyErr_NoMemory();
775 return -1;
776 }
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000777 PyObject *key;
778 Py_ssize_t pos = 0;
779 Py_hash_t hash;
780 Py_ssize_t i = 0;
781
782 while (_PySet_NextEntry(impl->_abc_registry, &pos, &key, &hash)) {
783 Py_INCREF(key);
784 copy[i++] = key;
785 }
786 assert(i == registry_size);
787
788 for (i = 0; i < registry_size; i++) {
789 PyObject *rkey = PyWeakref_GetObject(copy[i]);
790 if (rkey == NULL) {
791 // Someone inject non-weakref type in the registry.
792 ret = -1;
793 break;
794 }
795 if (rkey == Py_None) {
796 continue;
797 }
798 Py_INCREF(rkey);
799 int r = PyObject_IsSubclass(subclass, rkey);
800 Py_DECREF(rkey);
801 if (r < 0) {
802 ret = -1;
803 break;
804 }
805 if (r > 0) {
806 if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
807 ret = -1;
808 break;
809 }
810 *result = Py_True;
811 ret = 1;
812 break;
813 }
814 }
815
816 for (i = 0; i < registry_size; i++) {
817 Py_DECREF(copy[i]);
818 }
819 PyMem_Free(copy);
820 return ret;
821}
822
823/*[clinic input]
824_abc.get_cache_token
825
826Returns the current ABC cache token.
827
828The token is an opaque object (supporting equality testing) identifying the
829current version of the ABC cache for virtual subclasses. The token changes
830with every call to register() on any ABC.
831[clinic start generated code]*/
832
833static PyObject *
834_abc_get_cache_token_impl(PyObject *module)
835/*[clinic end generated code: output=c7d87841e033dacc input=70413d1c423ad9f9]*/
836{
Dong-hee Na77c61462020-05-09 17:31:40 +0900837 _abcmodule_state *state = get_abc_state(module);
838 return PyLong_FromUnsignedLongLong(state->abc_invalidation_counter);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000839}
840
Dong-hee Na53e4c912020-03-30 23:35:38 +0900841static struct PyMethodDef _abcmodule_methods[] = {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000842 _ABC_GET_CACHE_TOKEN_METHODDEF
843 _ABC__ABC_INIT_METHODDEF
844 _ABC__RESET_REGISTRY_METHODDEF
845 _ABC__RESET_CACHES_METHODDEF
846 _ABC__GET_DUMP_METHODDEF
847 _ABC__ABC_REGISTER_METHODDEF
848 _ABC__ABC_INSTANCECHECK_METHODDEF
849 _ABC__ABC_SUBCLASSCHECK_METHODDEF
850 {NULL, NULL} /* sentinel */
851};
852
Hai Shi4c1b6a62020-02-17 21:50:35 +0800853static int
Dong-hee Na53e4c912020-03-30 23:35:38 +0900854_abcmodule_exec(PyObject *module)
Hai Shi4c1b6a62020-02-17 21:50:35 +0800855{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900856 _abcmodule_state *state = get_abc_state(module);
Dong-hee Na77c61462020-05-09 17:31:40 +0900857 state->abc_invalidation_counter = 0;
858 state->_abc_data_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &_abc_data_type_spec, NULL);
Dong-hee Na53e4c912020-03-30 23:35:38 +0900859 if (state->_abc_data_type == NULL) {
Hai Shi4c1b6a62020-02-17 21:50:35 +0800860 return -1;
861 }
Dong-hee Na53e4c912020-03-30 23:35:38 +0900862
Hai Shi4c1b6a62020-02-17 21:50:35 +0800863 return 0;
864}
865
Dong-hee Na53e4c912020-03-30 23:35:38 +0900866static int
867_abcmodule_traverse(PyObject *module, visitproc visit, void *arg)
868{
869 _abcmodule_state *state = get_abc_state(module);
870 Py_VISIT(state->_abc_data_type);
871 return 0;
872}
873
874static int
875_abcmodule_clear(PyObject *module)
876{
877 _abcmodule_state *state = get_abc_state(module);
878 Py_CLEAR(state->_abc_data_type);
879 return 0;
880}
881
882static void
883_abcmodule_free(void *module)
884{
885 _abcmodule_clear((PyObject *)module);
886}
887
888static PyModuleDef_Slot _abcmodule_slots[] = {
889 {Py_mod_exec, _abcmodule_exec},
Hai Shi4c1b6a62020-02-17 21:50:35 +0800890 {0, NULL}
891};
892
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000893static struct PyModuleDef _abcmodule = {
894 PyModuleDef_HEAD_INIT,
Victor Stinnerc8c42002020-10-26 23:19:22 +0100895 .m_name = "_abc",
896 .m_doc = _abc__doc__,
897 .m_size = sizeof(_abcmodule_state),
898 .m_methods = _abcmodule_methods,
899 .m_slots = _abcmodule_slots,
900 .m_traverse = _abcmodule_traverse,
901 .m_clear = _abcmodule_clear,
902 .m_free = _abcmodule_free,
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000903};
904
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000905PyMODINIT_FUNC
906PyInit__abc(void)
907{
Hai Shi4c1b6a62020-02-17 21:50:35 +0800908 return PyModuleDef_Init(&_abcmodule);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000909}