Coverage Report

Created: 2025-07-04 06:49

/src/cpython/Modules/_abc.c
Line
Count
Source (jump to first uncovered line)
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
8.10k
{
30
8.10k
    void *state = _PyModule_GetState(module);
31
8.10k
    assert(state != NULL);
32
8.10k
    return (_abcmodule_state *)state;
33
8.10k
}
34
35
static inline uint64_t
36
get_invalidation_counter(_abcmodule_state *state)
37
1.26k
{
38
#ifdef Py_GIL_DISABLED
39
    return _Py_atomic_load_uint64(&state->abc_invalidation_counter);
40
#else
41
1.26k
    return state->abc_invalidation_counter;
42
1.26k
#endif
43
1.26k
}
44
45
static inline void
46
increment_invalidation_counter(_abcmodule_state *state)
47
334
{
48
#ifdef Py_GIL_DISABLED
49
    _Py_atomic_add_uint64(&state->abc_invalidation_counter, 1);
50
#else
51
334
    state->abc_invalidation_counter++;
52
334
#endif
53
334
}
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
324k
#define _abc_data_CAST(op)  ((_abc_data *)(op))
71
72
static inline uint64_t
73
get_cache_version(_abc_data *impl)
74
590
{
75
#ifdef Py_GIL_DISABLED
76
    return _Py_atomic_load_uint64(&impl->_abc_negative_cache_version);
77
#else
78
590
    return impl->_abc_negative_cache_version;
79
590
#endif
80
590
}
81
82
static inline void
83
set_cache_version(_abc_data *impl, uint64_t version)
84
180
{
85
#ifdef Py_GIL_DISABLED
86
    _Py_atomic_store_uint64(&impl->_abc_negative_cache_version, version);
87
#else
88
180
    impl->_abc_negative_cache_version = version;
89
180
#endif
90
180
}
91
92
static int
93
abc_data_traverse(PyObject *op, visitproc visit, void *arg)
94
324k
{
95
324k
    _abc_data *self = _abc_data_CAST(op);
96
324k
    Py_VISIT(Py_TYPE(self));
97
324k
    Py_VISIT(self->_abc_registry);
98
324k
    Py_VISIT(self->_abc_cache);
99
324k
    Py_VISIT(self->_abc_negative_cache);
100
324k
    return 0;
101
324k
}
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
674
{
126
674
    _abc_data *self = (_abc_data *) type->tp_alloc(type, 0);
127
674
    _abcmodule_state *state = NULL;
128
674
    if (self == NULL) {
129
0
        return NULL;
130
0
    }
131
132
674
    state = _PyType_GetModuleState(type);
133
674
    if (state == NULL) {
134
0
        Py_DECREF(self);
135
0
        return NULL;
136
0
    }
137
138
674
    self->_abc_registry = NULL;
139
674
    self->_abc_cache = NULL;
140
674
    self->_abc_negative_cache = NULL;
141
674
    self->_abc_negative_cache_version = get_invalidation_counter(state);
142
674
    return (PyObject *) self;
143
674
}
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
924
{
167
924
    _abcmodule_state *state = get_abc_state(module);
168
924
    PyObject *impl = PyObject_GetAttr(self, &_Py_ID(_abc_impl));
169
924
    if (impl == NULL) {
170
0
        return NULL;
171
0
    }
172
924
    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
924
    return (_abc_data *)impl;
178
924
}
179
180
static int
181
_in_weak_set(_abc_data *impl, PyObject **pset, PyObject *obj)
182
1.33k
{
183
1.33k
    PyObject *set;
184
1.33k
    Py_BEGIN_CRITICAL_SECTION(impl);
185
1.33k
    set = *pset;
186
1.33k
    Py_END_CRITICAL_SECTION();
187
1.33k
    if (set == NULL || PySet_GET_SIZE(set) == 0) {
188
982
        return 0;
189
982
    }
190
352
    PyObject *ref = PyWeakref_NewRef(obj, NULL);
191
352
    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
352
    int res = PySet_Contains(set, ref);
199
352
    Py_DECREF(ref);
200
352
    return res;
201
352
}
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
924
{
225
924
    PyObject *set;
226
924
    Py_BEGIN_CRITICAL_SECTION(impl);
227
924
    set = *pset;
228
924
    if (set == NULL) {
229
412
        set = *pset = PySet_New(NULL);
230
412
    }
231
924
    Py_END_CRITICAL_SECTION();
232
924
    if (set == NULL) {
233
0
        return -1;
234
0
    }
235
236
924
    PyObject *ref, *wr;
237
924
    PyObject *destroy_cb;
238
924
    wr = PyWeakref_NewRef(set, NULL);
239
924
    if (wr == NULL) {
240
0
        return -1;
241
0
    }
242
924
    destroy_cb = PyCFunction_NewEx(&_destroy_def, wr, NULL);
243
924
    if (destroy_cb == NULL) {
244
0
        Py_DECREF(wr);
245
0
        return -1;
246
0
    }
247
924
    ref = PyWeakref_NewRef(obj, destroy_cb);
248
924
    Py_DECREF(destroy_cb);
249
924
    if (ref == NULL) {
250
0
        Py_DECREF(wr);
251
0
        return -1;
252
0
    }
253
924
    int ret = PySet_Add(set, ref);
254
924
    Py_DECREF(wr);
255
924
    Py_DECREF(ref);
256
924
    return ret;
257
924
}
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
674
{
364
674
    int ret = -1;
365
674
    PyObject *abstracts = PyFrozenSet_New(NULL);
366
674
    if (abstracts == NULL) {
367
0
        return -1;
368
0
    }
369
370
674
    PyObject *ns = NULL, *items = NULL, *bases = NULL;  // Py_XDECREF()ed on error.
371
372
    /* Stage 1: direct abstract methods. */
373
674
    ns = PyObject_GetAttr(self, &_Py_ID(__dict__));
374
674
    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
674
    items = PyMapping_Items(ns);
381
674
    if (!items) {
382
0
        goto error;
383
0
    }
384
674
    assert(PyList_Check(items));
385
8.71k
    for (Py_ssize_t pos = 0; pos < PyList_GET_SIZE(items); pos++) {
386
8.03k
        PyObject *it = PySequence_Fast(
387
8.03k
                PyList_GET_ITEM(items, pos),
388
8.03k
                "items() returned non-iterable");
389
8.03k
        if (!it) {
390
0
            goto error;
391
0
        }
392
8.03k
        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
8.03k
        PyObject *key = PySequence_Fast_GET_ITEM(it, 0);
401
8.03k
        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
8.03k
        Py_INCREF(key);
405
8.03k
        int is_abstract = _PyObject_IsAbstract(value);
406
8.03k
        if (is_abstract < 0 ||
407
8.03k
                (is_abstract && PySet_Add(abstracts, key) < 0)) {
408
0
            Py_DECREF(it);
409
0
            Py_DECREF(key);
410
0
            goto error;
411
0
        }
412
8.03k
        Py_DECREF(key);
413
8.03k
        Py_DECREF(it);
414
8.03k
    }
415
416
    /* Stage 2: inherited abstract methods. */
417
674
    bases = PyObject_GetAttr(self, &_Py_ID(__bases__));
418
674
    if (!bases) {
419
0
        goto error;
420
0
    }
421
674
    if (!PyTuple_Check(bases)) {
422
0
        PyErr_SetString(PyExc_TypeError, "__bases__ is not tuple");
423
0
        goto error;
424
0
    }
425
426
1.49k
    for (Py_ssize_t pos = 0; pos < PyTuple_GET_SIZE(bases); pos++) {
427
821
        PyObject *item = PyTuple_GET_ITEM(bases, pos);  // borrowed
428
821
        PyObject *base_abstracts, *iter;
429
430
821
        if (PyObject_GetOptionalAttr(item, &_Py_ID(__abstractmethods__),
431
821
                                 &base_abstracts) < 0) {
432
0
            goto error;
433
0
        }
434
821
        if (base_abstracts == NULL) {
435
228
            continue;
436
228
        }
437
593
        if (!(iter = PyObject_GetIter(base_abstracts))) {
438
0
            Py_DECREF(base_abstracts);
439
0
            goto error;
440
0
        }
441
593
        Py_DECREF(base_abstracts);
442
593
        PyObject *key, *value;
443
1.57k
        while ((key = PyIter_Next(iter))) {
444
985
            if (PyObject_GetOptionalAttr(self, key, &value) < 0) {
445
0
                Py_DECREF(key);
446
0
                Py_DECREF(iter);
447
0
                goto error;
448
0
            }
449
985
            if (value == NULL) {
450
0
                Py_DECREF(key);
451
0
                continue;
452
0
            }
453
454
985
            int is_abstract = _PyObject_IsAbstract(value);
455
985
            Py_DECREF(value);
456
985
            if (is_abstract < 0 ||
457
985
                    (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
985
            Py_DECREF(key);
464
985
        }
465
593
        Py_DECREF(iter);
466
593
        if (PyErr_Occurred()) {
467
0
            goto error;
468
0
        }
469
593
    }
470
471
674
    if (PyObject_SetAttr(self, &_Py_ID(__abstractmethods__), abstracts) < 0) {
472
0
        goto error;
473
0
    }
474
475
674
    ret = 0;
476
674
error:
477
674
    Py_DECREF(abstracts);
478
674
    Py_XDECREF(ns);
479
674
    Py_XDECREF(items);
480
674
    Py_XDECREF(bases);
481
674
    return ret;
482
674
}
483
484
602
#define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING)
485
486
/*[clinic input]
487
_abc._abc_init
488
489
    self: object
490
    /
491
492
Internal ABC helper for class set-up. Should be never used outside abc module.
493
[clinic start generated code]*/
494
495
static PyObject *
496
_abc__abc_init(PyObject *module, PyObject *self)
497
/*[clinic end generated code: output=594757375714cda1 input=8d7fe470ff77f029]*/
498
674
{
499
674
    _abcmodule_state *state = get_abc_state(module);
500
674
    PyObject *data;
501
674
    if (compute_abstract_methods(self) < 0) {
502
0
        return NULL;
503
0
    }
504
505
    /* Set up inheritance registry. */
506
674
    data = abc_data_new(state->_abc_data_type, NULL, NULL);
507
674
    if (data == NULL) {
508
0
        return NULL;
509
0
    }
510
674
    if (PyObject_SetAttr(self, &_Py_ID(_abc_impl), data) < 0) {
511
0
        Py_DECREF(data);
512
0
        return NULL;
513
0
    }
514
674
    Py_DECREF(data);
515
    /* If __abc_tpflags__ & COLLECTION_FLAGS is set, then set the corresponding bit(s)
516
     * in the new class.
517
     * Used by collections.abc.Sequence and collections.abc.Mapping to indicate
518
     * their special status w.r.t. pattern matching. */
519
674
    if (PyType_Check(self)) {
520
674
        PyTypeObject *cls = (PyTypeObject *)self;
521
674
        PyObject *dict = _PyType_GetDict(cls);
522
674
        PyObject *flags = NULL;
523
674
        if (PyDict_Pop(dict, &_Py_ID(__abc_tpflags__), &flags) < 0) {
524
0
            return NULL;
525
0
        }
526
674
        if (flags == NULL || !PyLong_CheckExact(flags)) {
527
642
            Py_XDECREF(flags);
528
642
            Py_RETURN_NONE;
529
642
        }
530
531
32
        long val = PyLong_AsLong(flags);
532
32
        Py_DECREF(flags);
533
32
        if (val == -1 && PyErr_Occurred()) {
534
0
            return NULL;
535
0
        }
536
32
        if ((val & COLLECTION_FLAGS) == COLLECTION_FLAGS) {
537
0
            PyErr_SetString(PyExc_TypeError, "__abc_tpflags__ cannot be both Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING");
538
0
            return NULL;
539
0
        }
540
32
        _PyType_SetFlags((PyTypeObject *)self, 0, val & COLLECTION_FLAGS);
541
32
    }
542
674
    Py_RETURN_NONE;
543
674
}
544
545
/*[clinic input]
546
_abc._abc_register
547
548
    self: object
549
    subclass: object
550
    /
551
552
Internal ABC helper for subclasss registration. Should be never used outside abc module.
553
[clinic start generated code]*/
554
555
static PyObject *
556
_abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass)
557
/*[clinic end generated code: output=7851e7668c963524 input=ca589f8c3080e67f]*/
558
590
{
559
590
    if (!PyType_Check(subclass)) {
560
0
        PyErr_SetString(PyExc_TypeError, "Can only register classes");
561
0
        return NULL;
562
0
    }
563
590
    int result = PyObject_IsSubclass(subclass, self);
564
590
    if (result > 0) {
565
256
        return Py_NewRef(subclass);  /* Already a subclass. */
566
256
    }
567
334
    if (result < 0) {
568
0
        return NULL;
569
0
    }
570
    /* Subtle: test for cycles *after* testing for "already a subclass";
571
       this means we allow X.register(X) and interpret it as a no-op. */
572
334
    result = PyObject_IsSubclass(self, subclass);
573
334
    if (result > 0) {
574
        /* This would create a cycle, which is bad for the algorithm below. */
575
0
        PyErr_SetString(PyExc_RuntimeError, "Refusing to create an inheritance cycle");
576
0
        return NULL;
577
0
    }
578
334
    if (result < 0) {
579
0
        return NULL;
580
0
    }
581
334
    _abc_data *impl = _get_impl(module, self);
582
334
    if (impl == NULL) {
583
0
        return NULL;
584
0
    }
585
334
    if (_add_to_weak_set(impl, &impl->_abc_registry, subclass) < 0) {
586
0
        Py_DECREF(impl);
587
0
        return NULL;
588
0
    }
589
334
    Py_DECREF(impl);
590
591
    /* Invalidate negative cache */
592
334
    increment_invalidation_counter(get_abc_state(module));
593
594
    /* Set Py_TPFLAGS_SEQUENCE or Py_TPFLAGS_MAPPING flag */
595
334
    if (PyType_Check(self)) {
596
334
        unsigned long collection_flag =
597
334
            PyType_GetFlags((PyTypeObject *)self) & COLLECTION_FLAGS;
598
334
        if (collection_flag) {
599
172
            _PyType_SetFlagsRecursive((PyTypeObject *)subclass,
600
172
                                      COLLECTION_FLAGS,
601
172
                                      collection_flag);
602
172
        }
603
334
    }
604
334
    return Py_NewRef(subclass);
605
334
}
606
607
608
/*[clinic input]
609
_abc._abc_instancecheck
610
611
    self: object
612
    instance: object
613
    /
614
615
Internal ABC helper for instance checks. Should be never used outside abc module.
616
[clinic start generated code]*/
617
618
static PyObject *
619
_abc__abc_instancecheck_impl(PyObject *module, PyObject *self,
620
                             PyObject *instance)
621
/*[clinic end generated code: output=b8b5148f63b6b56f input=a4f4525679261084]*/
622
0
{
623
0
    PyObject *subtype, *result = NULL, *subclass = NULL;
624
0
    _abc_data *impl = _get_impl(module, self);
625
0
    if (impl == NULL) {
626
0
        return NULL;
627
0
    }
628
629
0
    subclass = PyObject_GetAttr(instance, &_Py_ID(__class__));
630
0
    if (subclass == NULL) {
631
0
        Py_DECREF(impl);
632
0
        return NULL;
633
0
    }
634
    /* Inline the cache checking. */
635
0
    int incache = _in_weak_set(impl, &impl->_abc_cache, subclass);
636
0
    if (incache < 0) {
637
0
        goto end;
638
0
    }
639
0
    if (incache > 0) {
640
0
        result = Py_NewRef(Py_True);
641
0
        goto end;
642
0
    }
643
0
    subtype = (PyObject *)Py_TYPE(instance);
644
0
    if (subtype == subclass) {
645
0
        if (get_cache_version(impl) == get_invalidation_counter(get_abc_state(module))) {
646
0
            incache = _in_weak_set(impl, &impl->_abc_negative_cache, subclass);
647
0
            if (incache < 0) {
648
0
                goto end;
649
0
            }
650
0
            if (incache > 0) {
651
0
                result = Py_NewRef(Py_False);
652
0
                goto end;
653
0
            }
654
0
        }
655
        /* Fall back to the subclass check. */
656
0
        result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
657
0
                                           subclass);
658
0
        goto end;
659
0
    }
660
0
    result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
661
0
                                       subclass);
662
0
    if (result == NULL) {
663
0
        goto end;
664
0
    }
665
666
0
    switch (PyObject_IsTrue(result)) {
667
0
    case -1:
668
0
        Py_SETREF(result, NULL);
669
0
        break;
670
0
    case 0:
671
0
        Py_DECREF(result);
672
0
        result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
673
0
                                           subtype);
674
0
        break;
675
0
    case 1:  // Nothing to do.
676
0
        break;
677
0
    default:
678
0
        Py_UNREACHABLE();
679
0
    }
680
681
0
end:
682
0
    Py_XDECREF(impl);
683
0
    Py_XDECREF(subclass);
684
0
    return result;
685
0
}
686
687
688
// Return -1 when exception occurred.
689
// Return 1 when result is set.
690
// Return 0 otherwise.
691
static int subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
692
                                        PyObject **result);
693
694
/*[clinic input]
695
_abc._abc_subclasscheck
696
697
    self: object
698
    subclass: object
699
    /
700
701
Internal ABC helper for subclasss checks. Should be never used outside abc module.
702
[clinic start generated code]*/
703
704
static PyObject *
705
_abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
706
                             PyObject *subclass)
707
/*[clinic end generated code: output=b56c9e4a530e3894 input=1d947243409d10b8]*/
708
590
{
709
590
    if (!PyType_Check(subclass)) {
710
0
        PyErr_SetString(PyExc_TypeError, "issubclass() arg 1 must be a class");
711
0
        return NULL;
712
0
    }
713
714
590
    PyObject *ok, *subclasses = NULL, *result = NULL;
715
590
    _abcmodule_state *state = NULL;
716
590
    Py_ssize_t pos;
717
590
    int incache;
718
590
    _abc_data *impl = _get_impl(module, self);
719
590
    if (impl == NULL) {
720
0
        return NULL;
721
0
    }
722
723
    /* 1. Check cache. */
724
590
    incache = _in_weak_set(impl, &impl->_abc_cache, subclass);
725
590
    if (incache < 0) {
726
0
        goto end;
727
0
    }
728
590
    if (incache > 0) {
729
0
        result = Py_True;
730
0
        goto end;
731
0
    }
732
733
590
    state = get_abc_state(module);
734
    /* 2. Check negative cache; may have to invalidate. */
735
590
    uint64_t invalidation_counter = get_invalidation_counter(state);
736
590
    if (get_cache_version(impl) < invalidation_counter) {
737
        /* Invalidate the negative cache. */
738
180
        PyObject *negative_cache;
739
180
        Py_BEGIN_CRITICAL_SECTION(impl);
740
180
        negative_cache = impl->_abc_negative_cache;
741
180
        Py_END_CRITICAL_SECTION();
742
180
        if (negative_cache != NULL && PySet_Clear(negative_cache) < 0) {
743
0
            goto end;
744
0
        }
745
180
        set_cache_version(impl, invalidation_counter);
746
180
    }
747
410
    else {
748
410
        incache = _in_weak_set(impl, &impl->_abc_negative_cache, subclass);
749
410
        if (incache < 0) {
750
0
            goto end;
751
0
        }
752
410
        if (incache > 0) {
753
0
            result = Py_False;
754
0
            goto end;
755
0
        }
756
410
    }
757
758
    /* 3. Check the subclass hook. */
759
590
    ok = PyObject_CallMethodOneArg(
760
590
            (PyObject *)self, &_Py_ID(__subclasshook__), subclass);
761
590
    if (ok == NULL) {
762
0
        goto end;
763
0
    }
764
590
    if (ok == Py_True) {
765
256
        Py_DECREF(ok);
766
256
        if (_add_to_weak_set(impl, &impl->_abc_cache, subclass) < 0) {
767
0
            goto end;
768
0
        }
769
256
        result = Py_True;
770
256
        goto end;
771
256
    }
772
334
    if (ok == Py_False) {
773
0
        Py_DECREF(ok);
774
0
        if (_add_to_weak_set(impl, &impl->_abc_negative_cache, subclass) < 0) {
775
0
            goto end;
776
0
        }
777
0
        result = Py_False;
778
0
        goto end;
779
0
    }
780
334
    if (ok != Py_NotImplemented) {
781
0
        Py_DECREF(ok);
782
0
        PyErr_SetString(PyExc_AssertionError, "__subclasshook__ must return either"
783
0
                                              " False, True, or NotImplemented");
784
0
        goto end;
785
0
    }
786
334
    Py_DECREF(ok);
787
788
    /* 4. Check if it's a direct subclass. */
789
334
    if (PyType_IsSubtype((PyTypeObject *)subclass, (PyTypeObject *)self)) {
790
0
        if (_add_to_weak_set(impl, &impl->_abc_cache, subclass) < 0) {
791
0
            goto end;
792
0
        }
793
0
        result = Py_True;
794
0
        goto end;
795
0
    }
796
797
    /* 5. Check if it's a subclass of a registered class (recursive). */
798
334
    if (subclasscheck_check_registry(impl, subclass, &result)) {
799
        // Exception occurred or result is set.
800
0
        goto end;
801
0
    }
802
803
    /* 6. Check if it's a subclass of a subclass (recursive). */
804
334
    subclasses = PyObject_CallMethod(self, "__subclasses__", NULL);
805
334
    if (subclasses == NULL) {
806
0
        goto end;
807
0
    }
808
334
    if (!PyList_Check(subclasses)) {
809
0
        PyErr_SetString(PyExc_TypeError, "__subclasses__() must return a list");
810
0
        goto end;
811
0
    }
812
334
    for (pos = 0; pos < PyList_GET_SIZE(subclasses); pos++) {
813
0
        PyObject *scls = PyList_GetItemRef(subclasses, pos);
814
0
        if (scls == NULL) {
815
0
            goto end;
816
0
        }
817
0
        int r = PyObject_IsSubclass(subclass, scls);
818
0
        Py_DECREF(scls);
819
0
        if (r > 0) {
820
0
            if (_add_to_weak_set(impl, &impl->_abc_cache, subclass) < 0) {
821
0
                goto end;
822
0
            }
823
0
            result = Py_True;
824
0
            goto end;
825
0
        }
826
0
        if (r < 0) {
827
0
            goto end;
828
0
        }
829
0
    }
830
831
    /* No dice; update negative cache. */
832
334
    if (_add_to_weak_set(impl, &impl->_abc_negative_cache, subclass) < 0) {
833
0
        goto end;
834
0
    }
835
334
    result = Py_False;
836
837
590
end:
838
590
    Py_DECREF(impl);
839
590
    Py_XDECREF(subclasses);
840
590
    return Py_XNewRef(result);
841
334
}
842
843
844
static int
845
subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
846
                             PyObject **result)
847
334
{
848
    // Fast path: check subclass is in weakref directly.
849
334
    int ret = _in_weak_set(impl, &impl->_abc_registry, subclass);
850
334
    if (ret < 0) {
851
0
        *result = NULL;
852
0
        return -1;
853
0
    }
854
334
    if (ret > 0) {
855
0
        *result = Py_True;
856
0
        return 1;
857
0
    }
858
859
334
    PyObject *registry_shared;
860
334
    Py_BEGIN_CRITICAL_SECTION(impl);
861
334
    registry_shared = impl->_abc_registry;
862
334
    Py_END_CRITICAL_SECTION();
863
334
    if (registry_shared == NULL) {
864
174
        return 0;
865
174
    }
866
867
    // Make a local copy of the registry to protect against concurrent
868
    // modifications of _abc_registry.
869
160
    PyObject *registry = PyFrozenSet_New(registry_shared);
870
160
    if (registry == NULL) {
871
0
        return -1;
872
0
    }
873
160
    PyObject *key;
874
160
    Py_ssize_t pos = 0;
875
160
    Py_hash_t hash;
876
877
488
    while (_PySet_NextEntry(registry, &pos, &key, &hash)) {
878
328
        PyObject *rkey;
879
328
        if (PyWeakref_GetRef(key, &rkey) < 0) {
880
            // Someone inject non-weakref type in the registry.
881
0
            ret = -1;
882
0
            break;
883
0
        }
884
885
328
        if (rkey == NULL) {
886
0
            continue;
887
0
        }
888
328
        int r = PyObject_IsSubclass(subclass, rkey);
889
328
        Py_DECREF(rkey);
890
328
        if (r < 0) {
891
0
            ret = -1;
892
0
            break;
893
0
        }
894
328
        if (r > 0) {
895
0
            if (_add_to_weak_set(impl, &impl->_abc_cache, subclass) < 0) {
896
0
                ret = -1;
897
0
                break;
898
0
            }
899
0
            *result = Py_True;
900
0
            ret = 1;
901
0
            break;
902
0
        }
903
328
    }
904
905
160
    Py_DECREF(registry);
906
160
    return ret;
907
160
}
908
909
/*[clinic input]
910
_abc.get_cache_token
911
912
Returns the current ABC cache token.
913
914
The token is an opaque object (supporting equality testing) identifying the
915
current version of the ABC cache for virtual subclasses. The token changes
916
with every call to register() on any ABC.
917
[clinic start generated code]*/
918
919
static PyObject *
920
_abc_get_cache_token_impl(PyObject *module)
921
/*[clinic end generated code: output=c7d87841e033dacc input=70413d1c423ad9f9]*/
922
0
{
923
0
    _abcmodule_state *state = get_abc_state(module);
924
0
    return PyLong_FromUnsignedLongLong(get_invalidation_counter(state));
925
0
}
926
927
static struct PyMethodDef _abcmodule_methods[] = {
928
    _ABC_GET_CACHE_TOKEN_METHODDEF
929
    _ABC__ABC_INIT_METHODDEF
930
    _ABC__RESET_REGISTRY_METHODDEF
931
    _ABC__RESET_CACHES_METHODDEF
932
    _ABC__GET_DUMP_METHODDEF
933
    _ABC__ABC_REGISTER_METHODDEF
934
    _ABC__ABC_INSTANCECHECK_METHODDEF
935
    _ABC__ABC_SUBCLASSCHECK_METHODDEF
936
    {NULL,       NULL}          /* sentinel */
937
};
938
939
static int
940
_abcmodule_exec(PyObject *module)
941
16
{
942
16
    _abcmodule_state *state = get_abc_state(module);
943
16
    state->abc_invalidation_counter = 0;
944
16
    state->_abc_data_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &_abc_data_type_spec, NULL);
945
16
    if (state->_abc_data_type == NULL) {
946
0
        return -1;
947
0
    }
948
949
16
    return 0;
950
16
}
951
952
static int
953
_abcmodule_traverse(PyObject *module, visitproc visit, void *arg)
954
5.56k
{
955
5.56k
    _abcmodule_state *state = get_abc_state(module);
956
5.56k
    Py_VISIT(state->_abc_data_type);
957
5.56k
    return 0;
958
5.56k
}
959
960
static int
961
_abcmodule_clear(PyObject *module)
962
0
{
963
0
    _abcmodule_state *state = get_abc_state(module);
964
0
    Py_CLEAR(state->_abc_data_type);
965
0
    return 0;
966
0
}
967
968
static void
969
_abcmodule_free(void *module)
970
0
{
971
0
    (void)_abcmodule_clear((PyObject *)module);
972
0
}
973
974
static PyModuleDef_Slot _abcmodule_slots[] = {
975
    {Py_mod_exec, _abcmodule_exec},
976
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
977
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
978
    {0, NULL}
979
};
980
981
static struct PyModuleDef _abcmodule = {
982
    PyModuleDef_HEAD_INIT,
983
    .m_name = "_abc",
984
    .m_doc = _abc__doc__,
985
    .m_size = sizeof(_abcmodule_state),
986
    .m_methods = _abcmodule_methods,
987
    .m_slots = _abcmodule_slots,
988
    .m_traverse = _abcmodule_traverse,
989
    .m_clear = _abcmodule_clear,
990
    .m_free = _abcmodule_free,
991
};
992
993
PyMODINIT_FUNC
994
PyInit__abc(void)
995
16
{
996
16
    return PyModuleDef_Init(&_abcmodule);
997
16
}