blob: 39261dd3cd579cd491c5009f1afb4ba8b49bf8bf [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 }
470 ((PyTypeObject *)self)->tp_flags |= (val & COLLECTION_FLAGS);
471 }
472 if (_PyDict_DelItemId(cls->tp_dict, &PyId___abc_tpflags__) < 0) {
473 return NULL;
474 }
475 }
476 }
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000477 Py_RETURN_NONE;
478}
479
480/*[clinic input]
481_abc._abc_register
482
483 self: object
484 subclass: object
485 /
486
487Internal ABC helper for subclasss registration. Should be never used outside abc module.
488[clinic start generated code]*/
489
490static PyObject *
491_abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass)
492/*[clinic end generated code: output=7851e7668c963524 input=ca589f8c3080e67f]*/
493{
494 if (!PyType_Check(subclass)) {
495 PyErr_SetString(PyExc_TypeError, "Can only register classes");
496 return NULL;
497 }
498 int result = PyObject_IsSubclass(subclass, self);
499 if (result > 0) {
500 Py_INCREF(subclass);
501 return subclass; /* Already a subclass. */
502 }
503 if (result < 0) {
504 return NULL;
505 }
506 /* Subtle: test for cycles *after* testing for "already a subclass";
507 this means we allow X.register(X) and interpret it as a no-op. */
508 result = PyObject_IsSubclass(self, subclass);
509 if (result > 0) {
510 /* This would create a cycle, which is bad for the algorithm below. */
511 PyErr_SetString(PyExc_RuntimeError, "Refusing to create an inheritance cycle");
512 return NULL;
513 }
514 if (result < 0) {
515 return NULL;
516 }
Dong-hee Na53e4c912020-03-30 23:35:38 +0900517 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000518 if (impl == NULL) {
519 return NULL;
520 }
521 if (_add_to_weak_set(&impl->_abc_registry, subclass) < 0) {
522 Py_DECREF(impl);
523 return NULL;
524 }
525 Py_DECREF(impl);
526
527 /* Invalidate negative cache */
Dong-hee Na77c61462020-05-09 17:31:40 +0900528 get_abc_state(module)->abc_invalidation_counter++;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000529
Mark Shannon069e81a2021-04-30 09:50:28 +0100530 if (PyType_Check(subclass) && PyType_Check(self) &&
531 !PyType_HasFeature((PyTypeObject *)subclass, Py_TPFLAGS_IMMUTABLETYPE))
532 {
533 ((PyTypeObject *)subclass)->tp_flags |= (((PyTypeObject *)self)->tp_flags & COLLECTION_FLAGS);
534 }
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000535 Py_INCREF(subclass);
536 return subclass;
537}
538
539
540/*[clinic input]
541_abc._abc_instancecheck
542
543 self: object
544 instance: object
545 /
546
547Internal ABC helper for instance checks. Should be never used outside abc module.
548[clinic start generated code]*/
549
550static PyObject *
551_abc__abc_instancecheck_impl(PyObject *module, PyObject *self,
552 PyObject *instance)
553/*[clinic end generated code: output=b8b5148f63b6b56f input=a4f4525679261084]*/
554{
555 PyObject *subtype, *result = NULL, *subclass = NULL;
Dong-hee Na53e4c912020-03-30 23:35:38 +0900556 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000557 if (impl == NULL) {
558 return NULL;
559 }
560
561 subclass = _PyObject_GetAttrId(instance, &PyId___class__);
562 if (subclass == NULL) {
563 Py_DECREF(impl);
564 return NULL;
565 }
566 /* Inline the cache checking. */
567 int incache = _in_weak_set(impl->_abc_cache, subclass);
568 if (incache < 0) {
569 goto end;
570 }
571 if (incache > 0) {
572 result = Py_True;
573 Py_INCREF(result);
574 goto end;
575 }
576 subtype = (PyObject *)Py_TYPE(instance);
577 if (subtype == subclass) {
Dong-hee Na77c61462020-05-09 17:31:40 +0900578 if (impl->_abc_negative_cache_version == get_abc_state(module)->abc_invalidation_counter) {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000579 incache = _in_weak_set(impl->_abc_negative_cache, subclass);
580 if (incache < 0) {
581 goto end;
582 }
583 if (incache > 0) {
584 result = Py_False;
585 Py_INCREF(result);
586 goto end;
587 }
588 }
589 /* Fall back to the subclass check. */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200590 result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__,
591 subclass);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000592 goto end;
593 }
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200594 result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__,
595 subclass);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000596 if (result == NULL) {
597 goto end;
598 }
599
600 switch (PyObject_IsTrue(result)) {
601 case -1:
602 Py_DECREF(result);
603 result = NULL;
604 break;
605 case 0:
606 Py_DECREF(result);
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200607 result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__,
608 subtype);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000609 break;
610 case 1: // Nothing to do.
611 break;
612 default:
613 Py_UNREACHABLE();
614 }
615
616end:
617 Py_XDECREF(impl);
618 Py_XDECREF(subclass);
619 return result;
620}
621
622
Min ho Kimf7d72e42019-07-06 07:39:32 +1000623// Return -1 when exception occurred.
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000624// Return 1 when result is set.
625// Return 0 otherwise.
626static int subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
627 PyObject **result);
628
629/*[clinic input]
630_abc._abc_subclasscheck
631
632 self: object
633 subclass: object
634 /
635
636Internal ABC helper for subclasss checks. Should be never used outside abc module.
637[clinic start generated code]*/
638
639static PyObject *
640_abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
641 PyObject *subclass)
642/*[clinic end generated code: output=b56c9e4a530e3894 input=1d947243409d10b8]*/
643{
jab40472dd2018-03-23 00:26:06 +1300644 if (!PyType_Check(subclass)) {
645 PyErr_SetString(PyExc_TypeError, "issubclass() arg 1 must be a class");
646 return NULL;
647 }
648
INADA Naokif757b722018-03-22 21:52:42 +0900649 PyObject *ok, *subclasses = NULL, *result = NULL;
Dong-hee Na77c61462020-05-09 17:31:40 +0900650 _abcmodule_state *state = NULL;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000651 Py_ssize_t pos;
652 int incache;
Dong-hee Na53e4c912020-03-30 23:35:38 +0900653 _abc_data *impl = _get_impl(module, self);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000654 if (impl == NULL) {
655 return NULL;
656 }
657
658 /* 1. Check cache. */
659 incache = _in_weak_set(impl->_abc_cache, subclass);
660 if (incache < 0) {
661 goto end;
662 }
663 if (incache > 0) {
664 result = Py_True;
665 goto end;
666 }
667
Dong-hee Na77c61462020-05-09 17:31:40 +0900668 state = get_abc_state(module);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000669 /* 2. Check negative cache; may have to invalidate. */
Dong-hee Na77c61462020-05-09 17:31:40 +0900670 if (impl->_abc_negative_cache_version < state->abc_invalidation_counter) {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000671 /* Invalidate the negative cache. */
672 if (impl->_abc_negative_cache != NULL &&
673 PySet_Clear(impl->_abc_negative_cache) < 0)
674 {
675 goto end;
676 }
Dong-hee Na77c61462020-05-09 17:31:40 +0900677 impl->_abc_negative_cache_version = state->abc_invalidation_counter;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000678 }
679 else {
680 incache = _in_weak_set(impl->_abc_negative_cache, subclass);
681 if (incache < 0) {
682 goto end;
683 }
684 if (incache > 0) {
685 result = Py_False;
686 goto end;
687 }
688 }
689
690 /* 3. Check the subclass hook. */
Jeroen Demeyer59ad1102019-07-11 10:59:05 +0200691 ok = _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId___subclasshook__,
692 subclass);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000693 if (ok == NULL) {
694 goto end;
695 }
696 if (ok == Py_True) {
697 Py_DECREF(ok);
698 if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
699 goto end;
700 }
701 result = Py_True;
702 goto end;
703 }
704 if (ok == Py_False) {
705 Py_DECREF(ok);
706 if (_add_to_weak_set(&impl->_abc_negative_cache, subclass) < 0) {
707 goto end;
708 }
709 result = Py_False;
710 goto end;
711 }
712 if (ok != Py_NotImplemented) {
713 Py_DECREF(ok);
714 PyErr_SetString(PyExc_AssertionError, "__subclasshook__ must return either"
715 " False, True, or NotImplemented");
716 goto end;
717 }
718 Py_DECREF(ok);
719
INADA Naokif757b722018-03-22 21:52:42 +0900720 /* 4. Check if it's a direct subclass. */
721 PyObject *mro = ((PyTypeObject *)subclass)->tp_mro;
722 assert(PyTuple_Check(mro));
723 for (pos = 0; pos < PyTuple_GET_SIZE(mro); pos++) {
724 PyObject *mro_item = PyTuple_GET_ITEM(mro, pos);
INADA Naokic65bf3f2018-03-23 18:19:34 +0900725 assert(mro_item != NULL);
INADA Naokif757b722018-03-22 21:52:42 +0900726 if ((PyObject *)self == mro_item) {
727 if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000728 goto end;
729 }
INADA Naokif757b722018-03-22 21:52:42 +0900730 result = Py_True;
731 goto end;
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000732 }
733 }
734
735 /* 5. Check if it's a subclass of a registered class (recursive). */
736 if (subclasscheck_check_registry(impl, subclass, &result)) {
Min ho Kimf7d72e42019-07-06 07:39:32 +1000737 // Exception occurred or result is set.
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000738 goto end;
739 }
740
741 /* 6. Check if it's a subclass of a subclass (recursive). */
742 subclasses = PyObject_CallMethod(self, "__subclasses__", NULL);
Alexey Izbyshevcdbf50c2018-08-20 23:04:19 +0300743 if (subclasses == NULL) {
744 goto end;
745 }
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000746 if (!PyList_Check(subclasses)) {
747 PyErr_SetString(PyExc_TypeError, "__subclasses__() must return a list");
748 goto end;
749 }
750 for (pos = 0; pos < PyList_GET_SIZE(subclasses); pos++) {
751 PyObject *scls = PyList_GET_ITEM(subclasses, pos);
752 Py_INCREF(scls);
753 int r = PyObject_IsSubclass(subclass, scls);
754 Py_DECREF(scls);
755 if (r > 0) {
756 if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
757 goto end;
758 }
759 result = Py_True;
760 goto end;
761 }
762 if (r < 0) {
763 goto end;
764 }
765 }
766
767 /* No dice; update negative cache. */
768 if (_add_to_weak_set(&impl->_abc_negative_cache, subclass) < 0) {
769 goto end;
770 }
771 result = Py_False;
772
773end:
INADA Naokifc7df0e2018-03-07 16:27:01 +0900774 Py_DECREF(impl);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000775 Py_XDECREF(subclasses);
776 Py_XINCREF(result);
777 return result;
778}
779
780
781static int
782subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
783 PyObject **result)
784{
785 // Fast path: check subclass is in weakref directly.
786 int ret = _in_weak_set(impl->_abc_registry, subclass);
787 if (ret < 0) {
788 *result = NULL;
789 return -1;
790 }
791 if (ret > 0) {
792 *result = Py_True;
793 return 1;
794 }
795
796 if (impl->_abc_registry == NULL) {
797 return 0;
798 }
799 Py_ssize_t registry_size = PySet_Size(impl->_abc_registry);
800 if (registry_size == 0) {
801 return 0;
802 }
803 // Weakref callback may remove entry from set.
804 // So we take snapshot of registry first.
805 PyObject **copy = PyMem_Malloc(sizeof(PyObject*) * registry_size);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700806 if (copy == NULL) {
807 PyErr_NoMemory();
808 return -1;
809 }
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000810 PyObject *key;
811 Py_ssize_t pos = 0;
812 Py_hash_t hash;
813 Py_ssize_t i = 0;
814
815 while (_PySet_NextEntry(impl->_abc_registry, &pos, &key, &hash)) {
816 Py_INCREF(key);
817 copy[i++] = key;
818 }
819 assert(i == registry_size);
820
821 for (i = 0; i < registry_size; i++) {
822 PyObject *rkey = PyWeakref_GetObject(copy[i]);
823 if (rkey == NULL) {
824 // Someone inject non-weakref type in the registry.
825 ret = -1;
826 break;
827 }
828 if (rkey == Py_None) {
829 continue;
830 }
831 Py_INCREF(rkey);
832 int r = PyObject_IsSubclass(subclass, rkey);
833 Py_DECREF(rkey);
834 if (r < 0) {
835 ret = -1;
836 break;
837 }
838 if (r > 0) {
839 if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
840 ret = -1;
841 break;
842 }
843 *result = Py_True;
844 ret = 1;
845 break;
846 }
847 }
848
849 for (i = 0; i < registry_size; i++) {
850 Py_DECREF(copy[i]);
851 }
852 PyMem_Free(copy);
853 return ret;
854}
855
856/*[clinic input]
857_abc.get_cache_token
858
859Returns the current ABC cache token.
860
861The token is an opaque object (supporting equality testing) identifying the
862current version of the ABC cache for virtual subclasses. The token changes
863with every call to register() on any ABC.
864[clinic start generated code]*/
865
866static PyObject *
867_abc_get_cache_token_impl(PyObject *module)
868/*[clinic end generated code: output=c7d87841e033dacc input=70413d1c423ad9f9]*/
869{
Dong-hee Na77c61462020-05-09 17:31:40 +0900870 _abcmodule_state *state = get_abc_state(module);
871 return PyLong_FromUnsignedLongLong(state->abc_invalidation_counter);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000872}
873
Dong-hee Na53e4c912020-03-30 23:35:38 +0900874static struct PyMethodDef _abcmodule_methods[] = {
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000875 _ABC_GET_CACHE_TOKEN_METHODDEF
876 _ABC__ABC_INIT_METHODDEF
877 _ABC__RESET_REGISTRY_METHODDEF
878 _ABC__RESET_CACHES_METHODDEF
879 _ABC__GET_DUMP_METHODDEF
880 _ABC__ABC_REGISTER_METHODDEF
881 _ABC__ABC_INSTANCECHECK_METHODDEF
882 _ABC__ABC_SUBCLASSCHECK_METHODDEF
883 {NULL, NULL} /* sentinel */
884};
885
Hai Shi4c1b6a62020-02-17 21:50:35 +0800886static int
Dong-hee Na53e4c912020-03-30 23:35:38 +0900887_abcmodule_exec(PyObject *module)
Hai Shi4c1b6a62020-02-17 21:50:35 +0800888{
Dong-hee Na53e4c912020-03-30 23:35:38 +0900889 _abcmodule_state *state = get_abc_state(module);
Dong-hee Na77c61462020-05-09 17:31:40 +0900890 state->abc_invalidation_counter = 0;
891 state->_abc_data_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &_abc_data_type_spec, NULL);
Dong-hee Na53e4c912020-03-30 23:35:38 +0900892 if (state->_abc_data_type == NULL) {
Hai Shi4c1b6a62020-02-17 21:50:35 +0800893 return -1;
894 }
Dong-hee Na53e4c912020-03-30 23:35:38 +0900895
Hai Shi4c1b6a62020-02-17 21:50:35 +0800896 return 0;
897}
898
Dong-hee Na53e4c912020-03-30 23:35:38 +0900899static int
900_abcmodule_traverse(PyObject *module, visitproc visit, void *arg)
901{
902 _abcmodule_state *state = get_abc_state(module);
903 Py_VISIT(state->_abc_data_type);
904 return 0;
905}
906
907static int
908_abcmodule_clear(PyObject *module)
909{
910 _abcmodule_state *state = get_abc_state(module);
911 Py_CLEAR(state->_abc_data_type);
912 return 0;
913}
914
915static void
916_abcmodule_free(void *module)
917{
918 _abcmodule_clear((PyObject *)module);
919}
920
921static PyModuleDef_Slot _abcmodule_slots[] = {
922 {Py_mod_exec, _abcmodule_exec},
Hai Shi4c1b6a62020-02-17 21:50:35 +0800923 {0, NULL}
924};
925
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000926static struct PyModuleDef _abcmodule = {
927 PyModuleDef_HEAD_INIT,
Victor Stinnerc8c42002020-10-26 23:19:22 +0100928 .m_name = "_abc",
929 .m_doc = _abc__doc__,
930 .m_size = sizeof(_abcmodule_state),
931 .m_methods = _abcmodule_methods,
932 .m_slots = _abcmodule_slots,
933 .m_traverse = _abcmodule_traverse,
934 .m_clear = _abcmodule_clear,
935 .m_free = _abcmodule_free,
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000936};
937
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000938PyMODINIT_FUNC
939PyInit__abc(void)
940{
Hai Shi4c1b6a62020-02-17 21:50:35 +0800941 return PyModuleDef_Init(&_abcmodule);
Ivan Levkivskyi03e3c342018-02-18 12:41:58 +0000942}