Coverage Report

Created: 2026-04-12 06:54

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