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