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