Branch data Line data Source code
1 : : /* ABCMeta implementation */
2 : : #ifndef Py_BUILD_CORE_BUILTIN
3 : : # define Py_BUILD_CORE_MODULE 1
4 : : #endif
5 : :
6 : : #include "Python.h"
7 : : #include "pycore_moduleobject.h" // _PyModule_GetState()
8 : : #include "pycore_object.h" // _PyType_GetSubclasses()
9 : : #include "pycore_runtime.h" // _Py_ID()
10 : : #include "clinic/_abc.c.h"
11 : :
12 : : /*[clinic input]
13 : : module _abc
14 : : [clinic start generated code]*/
15 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=964f5328e1aefcda]*/
16 : :
17 : : PyDoc_STRVAR(_abc__doc__,
18 : : "Module contains faster C implementation of abc.ABCMeta");
19 : :
20 : : typedef struct {
21 : : PyTypeObject *_abc_data_type;
22 : : unsigned long long abc_invalidation_counter;
23 : : } _abcmodule_state;
24 : :
25 : : static inline _abcmodule_state*
26 : 1514147 : get_abc_state(PyObject *module)
27 : : {
28 : 1514147 : void *state = _PyModule_GetState(module);
29 : : assert(state != NULL);
30 : 1514147 : return (_abcmodule_state *)state;
31 : : }
32 : :
33 : : /* This object stores internal state for ABCs.
34 : : Note that we can use normal sets for caches,
35 : : since they are never iterated over. */
36 : : typedef struct {
37 : : PyObject_HEAD
38 : : PyObject *_abc_registry;
39 : : PyObject *_abc_cache; /* Normal set of weak references. */
40 : : PyObject *_abc_negative_cache; /* Normal set of weak references. */
41 : : unsigned long long _abc_negative_cache_version;
42 : : } _abc_data;
43 : :
44 : : static int
45 : 3901400 : abc_data_traverse(_abc_data *self, visitproc visit, void *arg)
46 : : {
47 [ + - - + ]: 3901400 : Py_VISIT(Py_TYPE(self));
48 [ + + - + ]: 3901400 : Py_VISIT(self->_abc_registry);
49 [ + + - + ]: 3901400 : Py_VISIT(self->_abc_cache);
50 [ + + - + ]: 3901400 : Py_VISIT(self->_abc_negative_cache);
51 : 3901400 : return 0;
52 : : }
53 : :
54 : : static int
55 : 173947 : abc_data_clear(_abc_data *self)
56 : : {
57 [ + + ]: 173947 : Py_CLEAR(self->_abc_registry);
58 [ + + ]: 173947 : Py_CLEAR(self->_abc_cache);
59 [ + + ]: 173947 : Py_CLEAR(self->_abc_negative_cache);
60 : 173947 : return 0;
61 : : }
62 : :
63 : : static void
64 : 173893 : abc_data_dealloc(_abc_data *self)
65 : : {
66 : 173893 : PyTypeObject *tp = Py_TYPE(self);
67 : 173893 : (void)abc_data_clear(self);
68 : 173893 : tp->tp_free(self);
69 : 173893 : Py_DECREF(tp);
70 : 173893 : }
71 : :
72 : : static PyObject *
73 : 175543 : abc_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
74 : : {
75 : 175543 : _abc_data *self = (_abc_data *) type->tp_alloc(type, 0);
76 : 175543 : _abcmodule_state *state = NULL;
77 [ - + ]: 175543 : if (self == NULL) {
78 : 0 : return NULL;
79 : : }
80 : :
81 : 175543 : state = PyType_GetModuleState(type);
82 [ - + ]: 175543 : if (state == NULL) {
83 : 0 : Py_DECREF(self);
84 : 0 : return NULL;
85 : : }
86 : :
87 : 175543 : self->_abc_registry = NULL;
88 : 175543 : self->_abc_cache = NULL;
89 : 175543 : self->_abc_negative_cache = NULL;
90 : 175543 : self->_abc_negative_cache_version = state->abc_invalidation_counter;
91 : 175543 : return (PyObject *) self;
92 : : }
93 : :
94 : : PyDoc_STRVAR(abc_data_doc,
95 : : "Internal state held by ABC machinery.");
96 : :
97 : : static PyType_Slot _abc_data_type_spec_slots[] = {
98 : : {Py_tp_doc, (void *)abc_data_doc},
99 : : {Py_tp_new, abc_data_new},
100 : : {Py_tp_dealloc, abc_data_dealloc},
101 : : {Py_tp_traverse, abc_data_traverse},
102 : : {Py_tp_clear, abc_data_clear},
103 : : {0, 0}
104 : : };
105 : :
106 : : static PyType_Spec _abc_data_type_spec = {
107 : : .name = "_abc._abc_data",
108 : : .basicsize = sizeof(_abc_data),
109 : : .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
110 : : .slots = _abc_data_type_spec_slots,
111 : : };
112 : :
113 : : static _abc_data *
114 : 777051 : _get_impl(PyObject *module, PyObject *self)
115 : : {
116 : 777051 : _abcmodule_state *state = get_abc_state(module);
117 : 777051 : PyObject *impl = PyObject_GetAttr(self, &_Py_ID(_abc_impl));
118 [ - + ]: 777051 : if (impl == NULL) {
119 : 0 : return NULL;
120 : : }
121 [ - + ]: 777051 : if (!Py_IS_TYPE(impl, state->_abc_data_type)) {
122 : 0 : PyErr_SetString(PyExc_TypeError, "_abc_impl is set to a wrong type");
123 : 0 : Py_DECREF(impl);
124 : 0 : return NULL;
125 : : }
126 : 777051 : return (_abc_data *)impl;
127 : : }
128 : :
129 : : static int
130 : 1176771 : _in_weak_set(PyObject *set, PyObject *obj)
131 : : {
132 [ + + + + ]: 1176771 : if (set == NULL || PySet_GET_SIZE(set) == 0) {
133 : 284160 : return 0;
134 : : }
135 : 892611 : PyObject *ref = PyWeakref_NewRef(obj, NULL);
136 [ - + ]: 892611 : if (ref == NULL) {
137 [ # # ]: 0 : if (PyErr_ExceptionMatches(PyExc_TypeError)) {
138 : 0 : PyErr_Clear();
139 : 0 : return 0;
140 : : }
141 : 0 : return -1;
142 : : }
143 : 892611 : int res = PySet_Contains(set, ref);
144 : 892611 : Py_DECREF(ref);
145 : 892611 : return res;
146 : : }
147 : :
148 : : static PyObject *
149 : 4971 : _destroy(PyObject *setweakref, PyObject *objweakref)
150 : : {
151 : : PyObject *set;
152 : 4971 : set = PyWeakref_GET_OBJECT(setweakref);
153 [ - + ]: 4971 : if (set == Py_None) {
154 : 0 : Py_RETURN_NONE;
155 : : }
156 : 4971 : Py_INCREF(set);
157 [ - + ]: 4971 : if (PySet_Discard(set, objweakref) < 0) {
158 : 0 : Py_DECREF(set);
159 : 0 : return NULL;
160 : : }
161 : 4971 : Py_DECREF(set);
162 : 4971 : Py_RETURN_NONE;
163 : : }
164 : :
165 : : static PyMethodDef _destroy_def = {
166 : : "_destroy", (PyCFunction) _destroy, METH_O
167 : : };
168 : :
169 : : static int
170 : 226707 : _add_to_weak_set(PyObject **pset, PyObject *obj)
171 : : {
172 [ + + ]: 226707 : if (*pset == NULL) {
173 : 98348 : *pset = PySet_New(NULL);
174 [ - + ]: 98348 : if (*pset == NULL) {
175 : 0 : return -1;
176 : : }
177 : : }
178 : :
179 : 226707 : PyObject *set = *pset;
180 : : PyObject *ref, *wr;
181 : : PyObject *destroy_cb;
182 : 226707 : wr = PyWeakref_NewRef(set, NULL);
183 [ - + ]: 226707 : if (wr == NULL) {
184 : 0 : return -1;
185 : : }
186 : 226707 : destroy_cb = PyCFunction_NewEx(&_destroy_def, wr, NULL);
187 [ - + ]: 226707 : if (destroy_cb == NULL) {
188 : 0 : Py_DECREF(wr);
189 : 0 : return -1;
190 : : }
191 : 226707 : ref = PyWeakref_NewRef(obj, destroy_cb);
192 : 226707 : Py_DECREF(destroy_cb);
193 [ - + ]: 226707 : if (ref == NULL) {
194 : 0 : Py_DECREF(wr);
195 : 0 : return -1;
196 : : }
197 : 226707 : int ret = PySet_Add(set, ref);
198 : 226707 : Py_DECREF(wr);
199 : 226707 : Py_DECREF(ref);
200 : 226707 : return ret;
201 : : }
202 : :
203 : : /*[clinic input]
204 : : _abc._reset_registry
205 : :
206 : : self: object
207 : : /
208 : :
209 : : Internal ABC helper to reset registry of a given class.
210 : :
211 : : Should be only used by refleak.py
212 : : [clinic start generated code]*/
213 : :
214 : : static PyObject *
215 : 1 : _abc__reset_registry(PyObject *module, PyObject *self)
216 : : /*[clinic end generated code: output=92d591a43566cc10 input=12a0b7eb339ac35c]*/
217 : : {
218 : 1 : _abc_data *impl = _get_impl(module, self);
219 [ - + ]: 1 : if (impl == NULL) {
220 : 0 : return NULL;
221 : : }
222 [ + - - + ]: 1 : if (impl->_abc_registry != NULL && PySet_Clear(impl->_abc_registry) < 0) {
223 : 0 : Py_DECREF(impl);
224 : 0 : return NULL;
225 : : }
226 : 1 : Py_DECREF(impl);
227 : 1 : Py_RETURN_NONE;
228 : : }
229 : :
230 : : /*[clinic input]
231 : : _abc._reset_caches
232 : :
233 : : self: object
234 : : /
235 : :
236 : : Internal ABC helper to reset both caches of a given class.
237 : :
238 : : Should be only used by refleak.py
239 : : [clinic start generated code]*/
240 : :
241 : : static PyObject *
242 : 1 : _abc__reset_caches(PyObject *module, PyObject *self)
243 : : /*[clinic end generated code: output=f296f0d5c513f80c input=c0ac616fd8acfb6f]*/
244 : : {
245 : 1 : _abc_data *impl = _get_impl(module, self);
246 [ - + ]: 1 : if (impl == NULL) {
247 : 0 : return NULL;
248 : : }
249 [ - + - - ]: 1 : if (impl->_abc_cache != NULL && PySet_Clear(impl->_abc_cache) < 0) {
250 : 0 : Py_DECREF(impl);
251 : 0 : return NULL;
252 : : }
253 : : /* also the second cache */
254 [ + - - + ]: 2 : if (impl->_abc_negative_cache != NULL &&
255 : 1 : PySet_Clear(impl->_abc_negative_cache) < 0) {
256 : 0 : Py_DECREF(impl);
257 : 0 : return NULL;
258 : : }
259 : 1 : Py_DECREF(impl);
260 : 1 : Py_RETURN_NONE;
261 : : }
262 : :
263 : : /*[clinic input]
264 : : _abc._get_dump
265 : :
266 : : self: object
267 : : /
268 : :
269 : : Internal ABC helper for cache and registry debugging.
270 : :
271 : : Return shallow copies of registry, of both caches, and
272 : : negative cache version. Don't call this function directly,
273 : : instead use ABC._dump_registry() for a nice repr.
274 : : [clinic start generated code]*/
275 : :
276 : : static PyObject *
277 : 0 : _abc__get_dump(PyObject *module, PyObject *self)
278 : : /*[clinic end generated code: output=9d9569a8e2c1c443 input=2c5deb1bfe9e3c79]*/
279 : : {
280 : 0 : _abc_data *impl = _get_impl(module, self);
281 [ # # ]: 0 : if (impl == NULL) {
282 : 0 : return NULL;
283 : : }
284 : 0 : PyObject *res = Py_BuildValue("NNNK",
285 : : PySet_New(impl->_abc_registry),
286 : : PySet_New(impl->_abc_cache),
287 : : PySet_New(impl->_abc_negative_cache),
288 : : impl->_abc_negative_cache_version);
289 : 0 : Py_DECREF(impl);
290 : 0 : return res;
291 : : }
292 : :
293 : : // Compute set of abstract method names.
294 : : static int
295 : 175544 : compute_abstract_methods(PyObject *self)
296 : : {
297 : 175544 : int ret = -1;
298 : 175544 : PyObject *abstracts = PyFrozenSet_New(NULL);
299 [ - + ]: 175544 : if (abstracts == NULL) {
300 : 0 : return -1;
301 : : }
302 : :
303 : 175544 : PyObject *ns = NULL, *items = NULL, *bases = NULL; // Py_XDECREF()ed on error.
304 : :
305 : : /* Stage 1: direct abstract methods. */
306 : 175544 : ns = PyObject_GetAttr(self, &_Py_ID(__dict__));
307 [ - + ]: 175544 : if (!ns) {
308 : 0 : goto error;
309 : : }
310 : :
311 : : // We can't use PyDict_Next(ns) even when ns is dict because
312 : : // _PyObject_IsAbstract() can mutate ns.
313 : 175544 : items = PyMapping_Items(ns);
314 [ - + ]: 175544 : if (!items) {
315 : 0 : goto error;
316 : : }
317 : : assert(PyList_Check(items));
318 [ + + ]: 1800915 : for (Py_ssize_t pos = 0; pos < PyList_GET_SIZE(items); pos++) {
319 : 1625372 : PyObject *it = PySequence_Fast(
320 : 1625372 : PyList_GET_ITEM(items, pos),
321 : : "items() returned non-iterable");
322 [ - + ]: 1625372 : if (!it) {
323 : 0 : goto error;
324 : : }
325 [ - + - + ]: 1625372 : if (PySequence_Fast_GET_SIZE(it) != 2) {
326 : 0 : PyErr_SetString(PyExc_TypeError,
327 : : "items() returned item which size is not 2");
328 : 0 : Py_DECREF(it);
329 : 0 : goto error;
330 : : }
331 : :
332 : : // borrowed
333 [ - + ]: 1625372 : PyObject *key = PySequence_Fast_GET_ITEM(it, 0);
334 [ - + ]: 1625372 : PyObject *value = PySequence_Fast_GET_ITEM(it, 1);
335 : : // items or it may be cleared while accessing __abstractmethod__
336 : : // So we need to keep strong reference for key
337 : 1625372 : Py_INCREF(key);
338 : 1625372 : int is_abstract = _PyObject_IsAbstract(value);
339 [ + + + + ]: 1625372 : if (is_abstract < 0 ||
340 [ - + ]: 99100 : (is_abstract && PySet_Add(abstracts, key) < 0)) {
341 : 1 : Py_DECREF(it);
342 : 1 : Py_DECREF(key);
343 : 1 : goto error;
344 : : }
345 : 1625371 : Py_DECREF(key);
346 : 1625371 : Py_DECREF(it);
347 : : }
348 : :
349 : : /* Stage 2: inherited abstract methods. */
350 : 175543 : bases = PyObject_GetAttr(self, &_Py_ID(__bases__));
351 [ - + ]: 175543 : if (!bases) {
352 : 0 : goto error;
353 : : }
354 [ - + ]: 175543 : if (!PyTuple_Check(bases)) {
355 : 0 : PyErr_SetString(PyExc_TypeError, "__bases__ is not tuple");
356 : 0 : goto error;
357 : : }
358 : :
359 [ + + ]: 391895 : for (Py_ssize_t pos = 0; pos < PyTuple_GET_SIZE(bases); pos++) {
360 : 216352 : PyObject *item = PyTuple_GET_ITEM(bases, pos); // borrowed
361 : : PyObject *base_abstracts, *iter;
362 : :
363 [ - + ]: 216352 : if (_PyObject_LookupAttr(item, &_Py_ID(__abstractmethods__),
364 : : &base_abstracts) < 0) {
365 : 0 : goto error;
366 : : }
367 [ + + ]: 216352 : if (base_abstracts == NULL) {
368 : 52940 : continue;
369 : : }
370 [ - + ]: 163412 : if (!(iter = PyObject_GetIter(base_abstracts))) {
371 : 0 : Py_DECREF(base_abstracts);
372 : 0 : goto error;
373 : : }
374 : 163412 : Py_DECREF(base_abstracts);
375 : : PyObject *key, *value;
376 [ + + ]: 395928 : while ((key = PyIter_Next(iter))) {
377 [ - + ]: 232516 : if (_PyObject_LookupAttr(self, key, &value) < 0) {
378 : 0 : Py_DECREF(key);
379 : 0 : Py_DECREF(iter);
380 : 0 : goto error;
381 : : }
382 [ + + ]: 232516 : if (value == NULL) {
383 : 2 : Py_DECREF(key);
384 : 2 : continue;
385 : : }
386 : :
387 : 232514 : int is_abstract = _PyObject_IsAbstract(value);
388 : 232514 : Py_DECREF(value);
389 [ + - + + ]: 232514 : if (is_abstract < 0 ||
390 [ - + ]: 69945 : (is_abstract && PySet_Add(abstracts, key) < 0))
391 : : {
392 : 0 : Py_DECREF(key);
393 : 0 : Py_DECREF(iter);
394 : 0 : goto error;
395 : : }
396 : 232514 : Py_DECREF(key);
397 : : }
398 : 163412 : Py_DECREF(iter);
399 [ - + ]: 163412 : if (PyErr_Occurred()) {
400 : 0 : goto error;
401 : : }
402 : : }
403 : :
404 [ - + ]: 175543 : if (PyObject_SetAttr(self, &_Py_ID(__abstractmethods__), abstracts) < 0) {
405 : 0 : goto error;
406 : : }
407 : :
408 : 175543 : ret = 0;
409 : 175544 : error:
410 : 175544 : Py_DECREF(abstracts);
411 : 175544 : Py_XDECREF(ns);
412 : 175544 : Py_XDECREF(items);
413 : 175544 : Py_XDECREF(bases);
414 : 175544 : return ret;
415 : : }
416 : :
417 : : #define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING)
418 : :
419 : : /*[clinic input]
420 : : _abc._abc_init
421 : :
422 : : self: object
423 : : /
424 : :
425 : : Internal ABC helper for class set-up. Should be never used outside abc module.
426 : : [clinic start generated code]*/
427 : :
428 : : static PyObject *
429 : 175544 : _abc__abc_init(PyObject *module, PyObject *self)
430 : : /*[clinic end generated code: output=594757375714cda1 input=8d7fe470ff77f029]*/
431 : : {
432 : 175544 : _abcmodule_state *state = get_abc_state(module);
433 : : PyObject *data;
434 [ + + ]: 175544 : if (compute_abstract_methods(self) < 0) {
435 : 1 : return NULL;
436 : : }
437 : :
438 : : /* Set up inheritance registry. */
439 : 175543 : data = abc_data_new(state->_abc_data_type, NULL, NULL);
440 [ - + ]: 175543 : if (data == NULL) {
441 : 0 : return NULL;
442 : : }
443 [ - + ]: 175543 : if (PyObject_SetAttr(self, &_Py_ID(_abc_impl), data) < 0) {
444 : 0 : Py_DECREF(data);
445 : 0 : return NULL;
446 : : }
447 : 175543 : Py_DECREF(data);
448 : : /* If __abc_tpflags__ & COLLECTION_FLAGS is set, then set the corresponding bit(s)
449 : : * in the new class.
450 : : * Used by collections.abc.Sequence and collections.abc.Mapping to indicate
451 : : * their special status w.r.t. pattern matching. */
452 [ + - ]: 175543 : if (PyType_Check(self)) {
453 : 175543 : PyTypeObject *cls = (PyTypeObject *)self;
454 : 175543 : PyObject *flags = PyDict_GetItemWithError(cls->tp_dict,
455 : : &_Py_ID(__abc_tpflags__));
456 [ + + ]: 175543 : if (flags == NULL) {
457 [ - + ]: 169308 : if (PyErr_Occurred()) {
458 : 0 : return NULL;
459 : : }
460 : : }
461 : : else {
462 [ + - ]: 6235 : if (PyLong_CheckExact(flags)) {
463 : 6235 : long val = PyLong_AsLong(flags);
464 [ - + - - ]: 6235 : if (val == -1 && PyErr_Occurred()) {
465 : 0 : return NULL;
466 : : }
467 [ + + ]: 6235 : if ((val & COLLECTION_FLAGS) == COLLECTION_FLAGS) {
468 : 1 : PyErr_SetString(PyExc_TypeError, "__abc_tpflags__ cannot be both Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING");
469 : 1 : return NULL;
470 : : }
471 : 6234 : ((PyTypeObject *)self)->tp_flags |= (val & COLLECTION_FLAGS);
472 : : }
473 [ - + ]: 6234 : if (PyDict_DelItem(cls->tp_dict, &_Py_ID(__abc_tpflags__)) < 0) {
474 : 0 : return NULL;
475 : : }
476 : : }
477 : : }
478 : 175542 : Py_RETURN_NONE;
479 : : }
480 : :
481 : : static void
482 : 33994 : set_collection_flag_recursive(PyTypeObject *child, unsigned long flag)
483 : : {
484 : : assert(flag == Py_TPFLAGS_MAPPING || flag == Py_TPFLAGS_SEQUENCE);
485 [ + + ]: 33994 : if (PyType_HasFeature(child, Py_TPFLAGS_IMMUTABLETYPE) ||
486 [ - + ]: 31 : (child->tp_flags & COLLECTION_FLAGS) == flag)
487 : : {
488 : 33963 : return;
489 : : }
490 : :
491 : 31 : child->tp_flags &= ~COLLECTION_FLAGS;
492 : 31 : child->tp_flags |= flag;
493 : :
494 : 31 : PyObject *grandchildren = _PyType_GetSubclasses(child);
495 [ - + ]: 31 : if (grandchildren == NULL) {
496 : 0 : return;
497 : : }
498 : :
499 [ + + ]: 35 : for (Py_ssize_t i = 0; i < PyList_GET_SIZE(grandchildren); i++) {
500 : 4 : PyObject *grandchild = PyList_GET_ITEM(grandchildren, i);
501 : 4 : set_collection_flag_recursive((PyTypeObject *)grandchild, flag);
502 : : }
503 : 31 : Py_DECREF(grandchildren);
504 : : }
505 : :
506 : : /*[clinic input]
507 : : _abc._abc_register
508 : :
509 : : self: object
510 : : subclass: object
511 : : /
512 : :
513 : : Internal ABC helper for subclasss registration. Should be never used outside abc module.
514 : : [clinic start generated code]*/
515 : :
516 : : static PyObject *
517 : 127210 : _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass)
518 : : /*[clinic end generated code: output=7851e7668c963524 input=ca589f8c3080e67f]*/
519 : : {
520 [ + + ]: 127210 : if (!PyType_Check(subclass)) {
521 : 1 : PyErr_SetString(PyExc_TypeError, "Can only register classes");
522 : 1 : return NULL;
523 : : }
524 : 127209 : int result = PyObject_IsSubclass(subclass, self);
525 [ + + ]: 127209 : if (result > 0) {
526 : 50603 : Py_INCREF(subclass);
527 : 50603 : return subclass; /* Already a subclass. */
528 : : }
529 [ - + ]: 76606 : if (result < 0) {
530 : 0 : return NULL;
531 : : }
532 : : /* Subtle: test for cycles *after* testing for "already a subclass";
533 : : this means we allow X.register(X) and interpret it as a no-op. */
534 : 76606 : result = PyObject_IsSubclass(self, subclass);
535 [ + + ]: 76606 : if (result > 0) {
536 : : /* This would create a cycle, which is bad for the algorithm below. */
537 : 2 : PyErr_SetString(PyExc_RuntimeError, "Refusing to create an inheritance cycle");
538 : 2 : return NULL;
539 : : }
540 [ - + ]: 76604 : if (result < 0) {
541 : 0 : return NULL;
542 : : }
543 : 76604 : _abc_data *impl = _get_impl(module, self);
544 [ - + ]: 76604 : if (impl == NULL) {
545 : 0 : return NULL;
546 : : }
547 [ - + ]: 76604 : if (_add_to_weak_set(&impl->_abc_registry, subclass) < 0) {
548 : 0 : Py_DECREF(impl);
549 : 0 : return NULL;
550 : : }
551 : 76604 : Py_DECREF(impl);
552 : :
553 : : /* Invalidate negative cache */
554 : 76604 : get_abc_state(module)->abc_invalidation_counter++;
555 : :
556 : : /* Set Py_TPFLAGS_SEQUENCE or Py_TPFLAGS_MAPPING flag */
557 [ + - ]: 76604 : if (PyType_Check(self)) {
558 : 76604 : unsigned long collection_flag = ((PyTypeObject *)self)->tp_flags & COLLECTION_FLAGS;
559 [ + + ]: 76604 : if (collection_flag) {
560 : 33990 : set_collection_flag_recursive((PyTypeObject *)subclass, collection_flag);
561 : : }
562 : : }
563 : 76604 : Py_INCREF(subclass);
564 : 76604 : return subclass;
565 : : }
566 : :
567 : :
568 : : /*[clinic input]
569 : : _abc._abc_instancecheck
570 : :
571 : : self: object
572 : : instance: object
573 : : /
574 : :
575 : : Internal ABC helper for instance checks. Should be never used outside abc module.
576 : : [clinic start generated code]*/
577 : :
578 : : static PyObject *
579 : 543927 : _abc__abc_instancecheck_impl(PyObject *module, PyObject *self,
580 : : PyObject *instance)
581 : : /*[clinic end generated code: output=b8b5148f63b6b56f input=a4f4525679261084]*/
582 : : {
583 : 543927 : PyObject *subtype, *result = NULL, *subclass = NULL;
584 : 543927 : _abc_data *impl = _get_impl(module, self);
585 [ - + ]: 543927 : if (impl == NULL) {
586 : 0 : return NULL;
587 : : }
588 : :
589 : 543927 : subclass = PyObject_GetAttr(instance, &_Py_ID(__class__));
590 [ - + ]: 543927 : if (subclass == NULL) {
591 : 0 : Py_DECREF(impl);
592 : 0 : return NULL;
593 : : }
594 : : /* Inline the cache checking. */
595 : 543927 : int incache = _in_weak_set(impl->_abc_cache, subclass);
596 [ - + ]: 543927 : if (incache < 0) {
597 : 0 : goto end;
598 : : }
599 [ + + ]: 543927 : if (incache > 0) {
600 : 280028 : result = Py_True;
601 : 280028 : Py_INCREF(result);
602 : 280028 : goto end;
603 : : }
604 : 263899 : subtype = (PyObject *)Py_TYPE(instance);
605 [ + + ]: 263899 : if (subtype == subclass) {
606 [ + + ]: 263896 : if (impl->_abc_negative_cache_version == get_abc_state(module)->abc_invalidation_counter) {
607 : 263376 : incache = _in_weak_set(impl->_abc_negative_cache, subclass);
608 [ - + ]: 263376 : if (incache < 0) {
609 : 0 : goto end;
610 : : }
611 [ + + ]: 263376 : if (incache > 0) {
612 : 257537 : result = Py_False;
613 : 257537 : Py_INCREF(result);
614 : 257537 : goto end;
615 : : }
616 : : }
617 : : /* Fall back to the subclass check. */
618 : 6359 : result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
619 : : subclass);
620 : 6359 : goto end;
621 : : }
622 : 3 : result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
623 : : subclass);
624 [ - + ]: 3 : if (result == NULL) {
625 : 0 : goto end;
626 : : }
627 : :
628 [ - + + - ]: 3 : switch (PyObject_IsTrue(result)) {
629 : 0 : case -1:
630 : 0 : Py_DECREF(result);
631 : 0 : result = NULL;
632 : 0 : break;
633 : 2 : case 0:
634 : 2 : Py_DECREF(result);
635 : 2 : result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
636 : : subtype);
637 : 2 : break;
638 : 1 : case 1: // Nothing to do.
639 : 1 : break;
640 : 0 : default:
641 : 0 : Py_UNREACHABLE();
642 : : }
643 : :
644 : 543927 : end:
645 : 543927 : Py_XDECREF(impl);
646 : 543927 : Py_XDECREF(subclass);
647 : 543927 : return result;
648 : : }
649 : :
650 : :
651 : : // Return -1 when exception occurred.
652 : : // Return 1 when result is set.
653 : : // Return 0 otherwise.
654 : : static int subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
655 : : PyObject **result);
656 : :
657 : : /*[clinic input]
658 : : _abc._abc_subclasscheck
659 : :
660 : : self: object
661 : : subclass: object
662 : : /
663 : :
664 : : Internal ABC helper for subclasss checks. Should be never used outside abc module.
665 : : [clinic start generated code]*/
666 : :
667 : : static PyObject *
668 : 156524 : _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
669 : : PyObject *subclass)
670 : : /*[clinic end generated code: output=b56c9e4a530e3894 input=1d947243409d10b8]*/
671 : : {
672 [ + + ]: 156524 : if (!PyType_Check(subclass)) {
673 : 6 : PyErr_SetString(PyExc_TypeError, "issubclass() arg 1 must be a class");
674 : 6 : return NULL;
675 : : }
676 : :
677 : 156518 : PyObject *ok, *subclasses = NULL, *result = NULL;
678 : 156518 : _abcmodule_state *state = NULL;
679 : : Py_ssize_t pos;
680 : : int incache;
681 : 156518 : _abc_data *impl = _get_impl(module, self);
682 [ - + ]: 156518 : if (impl == NULL) {
683 : 0 : return NULL;
684 : : }
685 : :
686 : : /* 1. Check cache. */
687 : 156518 : incache = _in_weak_set(impl->_abc_cache, subclass);
688 [ - + ]: 156518 : if (incache < 0) {
689 : 0 : goto end;
690 : : }
691 [ + + ]: 156518 : if (incache > 0) {
692 : 764 : result = Py_True;
693 : 764 : goto end;
694 : : }
695 : :
696 : 155754 : state = get_abc_state(module);
697 : : /* 2. Check negative cache; may have to invalidate. */
698 [ + + ]: 155754 : if (impl->_abc_negative_cache_version < state->abc_invalidation_counter) {
699 : : /* Invalidate the negative cache. */
700 [ + + - + ]: 83629 : if (impl->_abc_negative_cache != NULL &&
701 : 37671 : PySet_Clear(impl->_abc_negative_cache) < 0)
702 : : {
703 : 0 : goto end;
704 : : }
705 : 45958 : impl->_abc_negative_cache_version = state->abc_invalidation_counter;
706 : : }
707 : : else {
708 : 109796 : incache = _in_weak_set(impl->_abc_negative_cache, subclass);
709 [ - + ]: 109796 : if (incache < 0) {
710 : 0 : goto end;
711 : : }
712 [ + + ]: 109796 : if (incache > 0) {
713 : 1450 : result = Py_False;
714 : 1450 : goto end;
715 : : }
716 : : }
717 : :
718 : : /* 3. Check the subclass hook. */
719 : 154304 : ok = PyObject_CallMethodOneArg(
720 : : (PyObject *)self, &_Py_ID(__subclasshook__), subclass);
721 [ + + ]: 154304 : if (ok == NULL) {
722 : 5 : goto end;
723 : : }
724 [ + + ]: 154299 : if (ok == Py_True) {
725 : 50739 : Py_DECREF(ok);
726 [ - + ]: 50739 : if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
727 : 0 : goto end;
728 : : }
729 : 50739 : result = Py_True;
730 : 50739 : goto end;
731 : : }
732 [ + + ]: 103560 : if (ok == Py_False) {
733 : 6 : Py_DECREF(ok);
734 [ - + ]: 6 : if (_add_to_weak_set(&impl->_abc_negative_cache, subclass) < 0) {
735 : 0 : goto end;
736 : : }
737 : 6 : result = Py_False;
738 : 6 : goto end;
739 : : }
740 [ - + ]: 103554 : if (ok != Py_NotImplemented) {
741 : 0 : Py_DECREF(ok);
742 : 0 : PyErr_SetString(PyExc_AssertionError, "__subclasshook__ must return either"
743 : : " False, True, or NotImplemented");
744 : 0 : goto end;
745 : : }
746 : 103554 : Py_DECREF(ok);
747 : :
748 : : /* 4. Check if it's a direct subclass. */
749 : 103554 : PyObject *mro = ((PyTypeObject *)subclass)->tp_mro;
750 : : assert(PyTuple_Check(mro));
751 [ + + ]: 379441 : for (pos = 0; pos < PyTuple_GET_SIZE(mro); pos++) {
752 : 276287 : PyObject *mro_item = PyTuple_GET_ITEM(mro, pos);
753 : : assert(mro_item != NULL);
754 [ + + ]: 276287 : if ((PyObject *)self == mro_item) {
755 [ - + ]: 400 : if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
756 : 0 : goto end;
757 : : }
758 : 400 : result = Py_True;
759 : 400 : goto end;
760 : : }
761 : : }
762 : :
763 : : /* 5. Check if it's a subclass of a registered class (recursive). */
764 [ + + ]: 103154 : if (subclasscheck_check_registry(impl, subclass, &result)) {
765 : : // Exception occurred or result is set.
766 : 4227 : goto end;
767 : : }
768 : :
769 : : /* 6. Check if it's a subclass of a subclass (recursive). */
770 : 98927 : subclasses = PyObject_CallMethod(self, "__subclasses__", NULL);
771 [ + + ]: 98927 : if (subclasses == NULL) {
772 : 3 : goto end;
773 : : }
774 [ + + ]: 98924 : if (!PyList_Check(subclasses)) {
775 : 1 : PyErr_SetString(PyExc_TypeError, "__subclasses__() must return a list");
776 : 1 : goto end;
777 : : }
778 [ + + ]: 118901 : for (pos = 0; pos < PyList_GET_SIZE(subclasses); pos++) {
779 : 20090 : PyObject *scls = PyList_GET_ITEM(subclasses, pos);
780 : 20090 : Py_INCREF(scls);
781 : 20090 : int r = PyObject_IsSubclass(subclass, scls);
782 : 20090 : Py_DECREF(scls);
783 [ + + ]: 20090 : if (r > 0) {
784 [ - + ]: 111 : if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
785 : 0 : goto end;
786 : : }
787 : 111 : result = Py_True;
788 : 111 : goto end;
789 : : }
790 [ + + ]: 19979 : if (r < 0) {
791 : 1 : goto end;
792 : : }
793 : : }
794 : :
795 : : /* No dice; update negative cache. */
796 [ - + ]: 98811 : if (_add_to_weak_set(&impl->_abc_negative_cache, subclass) < 0) {
797 : 0 : goto end;
798 : : }
799 : 98811 : result = Py_False;
800 : :
801 : 156518 : end:
802 : 156518 : Py_DECREF(impl);
803 : 156518 : Py_XDECREF(subclasses);
804 : 156518 : Py_XINCREF(result);
805 : 156518 : return result;
806 : : }
807 : :
808 : :
809 : : static int
810 : 103154 : subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
811 : : PyObject **result)
812 : : {
813 : : // Fast path: check subclass is in weakref directly.
814 : 103154 : int ret = _in_weak_set(impl->_abc_registry, subclass);
815 [ - + ]: 103154 : if (ret < 0) {
816 : 0 : *result = NULL;
817 : 0 : return -1;
818 : : }
819 [ + + ]: 103154 : if (ret > 0) {
820 : 4191 : *result = Py_True;
821 : 4191 : return 1;
822 : : }
823 : :
824 [ + + ]: 98963 : if (impl->_abc_registry == NULL) {
825 : 60989 : return 0;
826 : : }
827 : 37974 : Py_ssize_t registry_size = PySet_Size(impl->_abc_registry);
828 [ + + ]: 37974 : if (registry_size == 0) {
829 : 6 : return 0;
830 : : }
831 : : // Weakref callback may remove entry from set.
832 : : // So we take snapshot of registry first.
833 : 37968 : PyObject **copy = PyMem_Malloc(sizeof(PyObject*) * registry_size);
834 [ - + ]: 37968 : if (copy == NULL) {
835 : : PyErr_NoMemory();
836 : 0 : return -1;
837 : : }
838 : : PyObject *key;
839 : 37968 : Py_ssize_t pos = 0;
840 : : Py_hash_t hash;
841 : 37968 : Py_ssize_t i = 0;
842 : :
843 [ + + ]: 109804 : while (_PySet_NextEntry(impl->_abc_registry, &pos, &key, &hash)) {
844 : 71836 : Py_INCREF(key);
845 : 71836 : copy[i++] = key;
846 : : }
847 : : assert(i == registry_size);
848 : :
849 [ + + ]: 109763 : for (i = 0; i < registry_size; i++) {
850 : 71831 : PyObject *rkey = PyWeakref_GetObject(copy[i]);
851 [ - + ]: 71831 : if (rkey == NULL) {
852 : : // Someone inject non-weakref type in the registry.
853 : 0 : ret = -1;
854 : 0 : break;
855 : : }
856 [ + + ]: 71831 : if (rkey == Py_None) {
857 : 4 : continue;
858 : : }
859 : 71827 : Py_INCREF(rkey);
860 : 71827 : int r = PyObject_IsSubclass(subclass, rkey);
861 : 71827 : Py_DECREF(rkey);
862 [ - + ]: 71827 : if (r < 0) {
863 : 0 : ret = -1;
864 : 0 : break;
865 : : }
866 [ + + ]: 71827 : if (r > 0) {
867 [ - + ]: 36 : if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) {
868 : 0 : ret = -1;
869 : 0 : break;
870 : : }
871 : 36 : *result = Py_True;
872 : 36 : ret = 1;
873 : 36 : break;
874 : : }
875 : : }
876 : :
877 [ + + ]: 109804 : for (i = 0; i < registry_size; i++) {
878 : 71836 : Py_DECREF(copy[i]);
879 : : }
880 : 37968 : PyMem_Free(copy);
881 : 37968 : return ret;
882 : : }
883 : :
884 : : /*[clinic input]
885 : : _abc.get_cache_token
886 : :
887 : : Returns the current ABC cache token.
888 : :
889 : : The token is an opaque object (supporting equality testing) identifying the
890 : : current version of the ABC cache for virtual subclasses. The token changes
891 : : with every call to register() on any ABC.
892 : : [clinic start generated code]*/
893 : :
894 : : static PyObject *
895 : 109 : _abc_get_cache_token_impl(PyObject *module)
896 : : /*[clinic end generated code: output=c7d87841e033dacc input=70413d1c423ad9f9]*/
897 : : {
898 : 109 : _abcmodule_state *state = get_abc_state(module);
899 : 109 : return PyLong_FromUnsignedLongLong(state->abc_invalidation_counter);
900 : : }
901 : :
902 : : static struct PyMethodDef _abcmodule_methods[] = {
903 : : _ABC_GET_CACHE_TOKEN_METHODDEF
904 : : _ABC__ABC_INIT_METHODDEF
905 : : _ABC__RESET_REGISTRY_METHODDEF
906 : : _ABC__RESET_CACHES_METHODDEF
907 : : _ABC__GET_DUMP_METHODDEF
908 : : _ABC__ABC_REGISTER_METHODDEF
909 : : _ABC__ABC_INSTANCECHECK_METHODDEF
910 : : _ABC__ABC_SUBCLASSCHECK_METHODDEF
911 : : {NULL, NULL} /* sentinel */
912 : : };
913 : :
914 : : static int
915 : 3133 : _abcmodule_exec(PyObject *module)
916 : : {
917 : 3133 : _abcmodule_state *state = get_abc_state(module);
918 : 3133 : state->abc_invalidation_counter = 0;
919 : 3133 : state->_abc_data_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &_abc_data_type_spec, NULL);
920 [ - + ]: 3133 : if (state->_abc_data_type == NULL) {
921 : 0 : return -1;
922 : : }
923 : :
924 : 3133 : return 0;
925 : : }
926 : :
927 : : static int
928 : 56916 : _abcmodule_traverse(PyObject *module, visitproc visit, void *arg)
929 : : {
930 : 56916 : _abcmodule_state *state = get_abc_state(module);
931 [ + - - + ]: 56916 : Py_VISIT(state->_abc_data_type);
932 : 56916 : return 0;
933 : : }
934 : :
935 : : static int
936 : 5140 : _abcmodule_clear(PyObject *module)
937 : : {
938 : 5140 : _abcmodule_state *state = get_abc_state(module);
939 [ + + ]: 5140 : Py_CLEAR(state->_abc_data_type);
940 : 5140 : return 0;
941 : : }
942 : :
943 : : static void
944 : 3045 : _abcmodule_free(void *module)
945 : : {
946 : 3045 : _abcmodule_clear((PyObject *)module);
947 : 3045 : }
948 : :
949 : : static PyModuleDef_Slot _abcmodule_slots[] = {
950 : : {Py_mod_exec, _abcmodule_exec},
951 : : {0, NULL}
952 : : };
953 : :
954 : : static struct PyModuleDef _abcmodule = {
955 : : PyModuleDef_HEAD_INIT,
956 : : .m_name = "_abc",
957 : : .m_doc = _abc__doc__,
958 : : .m_size = sizeof(_abcmodule_state),
959 : : .m_methods = _abcmodule_methods,
960 : : .m_slots = _abcmodule_slots,
961 : : .m_traverse = _abcmodule_traverse,
962 : : .m_clear = _abcmodule_clear,
963 : : .m_free = _abcmodule_free,
964 : : };
965 : :
966 : : PyMODINIT_FUNC
967 : 3133 : PyInit__abc(void)
968 : : {
969 : 3133 : return PyModuleDef_Init(&_abcmodule);
970 : : }
|