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