Skip to content

Commit 77c6146

Browse files
authored
bpo-40566: Apply PEP 573 to abc module (GH-20005)
1 parent 7f7e706 commit 77c6146

File tree

2 files changed

+20
-15
lines changed

2 files changed

+20
-15
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Apply :pep:`573` to :mod:`abc`.

Modules/_abc.c

+19-15
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,9 @@ _Py_IDENTIFIER(__subclasshook__);
2121

2222
typedef struct {
2323
PyTypeObject *_abc_data_type;
24+
unsigned long long abc_invalidation_counter;
2425
} _abcmodule_state;
2526

26-
/* A global counter that is incremented each time a class is
27-
registered as a virtual subclass of anything. It forces the
28-
negative cache to be cleared before its next use.
29-
Note: this counter is private. Use `abc.get_cache_token()` for
30-
external code. */
31-
// FIXME: PEP 573: Move abc_invalidation_counter into _abcmodule_state.
32-
static unsigned long long abc_invalidation_counter = 0;
33-
3427
static inline _abcmodule_state*
3528
get_abc_state(PyObject *module)
3629
{
@@ -81,14 +74,21 @@ static PyObject *
8174
abc_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
8275
{
8376
_abc_data *self = (_abc_data *) type->tp_alloc(type, 0);
77+
_abcmodule_state *state = NULL;
8478
if (self == NULL) {
8579
return NULL;
8680
}
8781

82+
state = PyType_GetModuleState(type);
83+
if (state == NULL) {
84+
Py_DECREF(self);
85+
return NULL;
86+
}
87+
8888
self->_abc_registry = NULL;
8989
self->_abc_cache = NULL;
9090
self->_abc_negative_cache = NULL;
91-
self->_abc_negative_cache_version = abc_invalidation_counter;
91+
self->_abc_negative_cache_version = state->abc_invalidation_counter;
9292
return (PyObject *) self;
9393
}
9494

@@ -495,7 +495,7 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass)
495495
Py_DECREF(impl);
496496

497497
/* Invalidate negative cache */
498-
abc_invalidation_counter++;
498+
get_abc_state(module)->abc_invalidation_counter++;
499499

500500
Py_INCREF(subclass);
501501
return subclass;
@@ -540,7 +540,7 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self,
540540
}
541541
subtype = (PyObject *)Py_TYPE(instance);
542542
if (subtype == subclass) {
543-
if (impl->_abc_negative_cache_version == abc_invalidation_counter) {
543+
if (impl->_abc_negative_cache_version == get_abc_state(module)->abc_invalidation_counter) {
544544
incache = _in_weak_set(impl->_abc_negative_cache, subclass);
545545
if (incache < 0) {
546546
goto end;
@@ -612,6 +612,7 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
612612
}
613613

614614
PyObject *ok, *subclasses = NULL, *result = NULL;
615+
_abcmodule_state *state = NULL;
615616
Py_ssize_t pos;
616617
int incache;
617618
_abc_data *impl = _get_impl(module, self);
@@ -629,15 +630,16 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
629630
goto end;
630631
}
631632

633+
state = get_abc_state(module);
632634
/* 2. Check negative cache; may have to invalidate. */
633-
if (impl->_abc_negative_cache_version < abc_invalidation_counter) {
635+
if (impl->_abc_negative_cache_version < state->abc_invalidation_counter) {
634636
/* Invalidate the negative cache. */
635637
if (impl->_abc_negative_cache != NULL &&
636638
PySet_Clear(impl->_abc_negative_cache) < 0)
637639
{
638640
goto end;
639641
}
640-
impl->_abc_negative_cache_version = abc_invalidation_counter;
642+
impl->_abc_negative_cache_version = state->abc_invalidation_counter;
641643
}
642644
else {
643645
incache = _in_weak_set(impl->_abc_negative_cache, subclass);
@@ -830,7 +832,8 @@ static PyObject *
830832
_abc_get_cache_token_impl(PyObject *module)
831833
/*[clinic end generated code: output=c7d87841e033dacc input=70413d1c423ad9f9]*/
832834
{
833-
return PyLong_FromUnsignedLongLong(abc_invalidation_counter);
835+
_abcmodule_state *state = get_abc_state(module);
836+
return PyLong_FromUnsignedLongLong(state->abc_invalidation_counter);
834837
}
835838

836839
static struct PyMethodDef _abcmodule_methods[] = {
@@ -849,7 +852,8 @@ static int
849852
_abcmodule_exec(PyObject *module)
850853
{
851854
_abcmodule_state *state = get_abc_state(module);
852-
state->_abc_data_type = (PyTypeObject *)PyType_FromSpec(&_abc_data_type_spec);
855+
state->abc_invalidation_counter = 0;
856+
state->_abc_data_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &_abc_data_type_spec, NULL);
853857
if (state->_abc_data_type == NULL) {
854858
return -1;
855859
}

0 commit comments

Comments
 (0)