Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-40566: Apply PEP 573 to abc module #20005

Merged
merged 3 commits into from
May 9, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Apply :pep:`573` to :mod:`abc`.
30 changes: 14 additions & 16 deletions Modules/_abc.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,9 @@ _Py_IDENTIFIER(__subclasshook__);

typedef struct {
PyTypeObject *_abc_data_type;
unsigned long long abc_invalidation_counter;
} _abcmodule_state;

/* A global counter that is incremented each time a class is
registered as a virtual subclass of anything. It forces the
negative cache to be cleared before its next use.
Note: this counter is private. Use `abc.get_cache_token()` for
external code. */
// FIXME: PEP 573: Move abc_invalidation_counter into _abcmodule_state.
static unsigned long long abc_invalidation_counter = 0;

static inline _abcmodule_state*
get_abc_state(PyObject *module)
{
Expand Down Expand Up @@ -81,14 +74,15 @@ static PyObject *
abc_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
_abc_data *self = (_abc_data *) type->tp_alloc(type, 0);
if (self == NULL) {
_abcmodule_state *state = PyType_GetModuleState(type);
if (self == NULL || state == NULL) {
return NULL;
corona10 marked this conversation as resolved.
Show resolved Hide resolved
}

self->_abc_registry = NULL;
self->_abc_cache = NULL;
self->_abc_negative_cache = NULL;
self->_abc_negative_cache_version = abc_invalidation_counter;
self->_abc_negative_cache_version = state->abc_invalidation_counter;
return (PyObject *) self;
}

Expand Down Expand Up @@ -495,7 +489,7 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass)
Py_DECREF(impl);

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

Py_INCREF(subclass);
return subclass;
Expand Down Expand Up @@ -540,7 +534,7 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self,
}
subtype = (PyObject *)Py_TYPE(instance);
if (subtype == subclass) {
if (impl->_abc_negative_cache_version == abc_invalidation_counter) {
if (impl->_abc_negative_cache_version == get_abc_state(module)->abc_invalidation_counter) {
incache = _in_weak_set(impl->_abc_negative_cache, subclass);
if (incache < 0) {
goto end;
Expand Down Expand Up @@ -612,6 +606,7 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
}

PyObject *ok, *subclasses = NULL, *result = NULL;
_abcmodule_state *state = NULL;
Py_ssize_t pos;
int incache;
_abc_data *impl = _get_impl(module, self);
Expand All @@ -629,15 +624,16 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
goto end;
}

state = get_abc_state(module);
/* 2. Check negative cache; may have to invalidate. */
if (impl->_abc_negative_cache_version < abc_invalidation_counter) {
if (impl->_abc_negative_cache_version < state->abc_invalidation_counter) {
/* Invalidate the negative cache. */
if (impl->_abc_negative_cache != NULL &&
PySet_Clear(impl->_abc_negative_cache) < 0)
{
goto end;
}
impl->_abc_negative_cache_version = abc_invalidation_counter;
impl->_abc_negative_cache_version = state->abc_invalidation_counter;
}
else {
incache = _in_weak_set(impl->_abc_negative_cache, subclass);
Expand Down Expand Up @@ -830,7 +826,8 @@ static PyObject *
_abc_get_cache_token_impl(PyObject *module)
/*[clinic end generated code: output=c7d87841e033dacc input=70413d1c423ad9f9]*/
{
return PyLong_FromUnsignedLongLong(abc_invalidation_counter);
_abcmodule_state *state = get_abc_state(module);
return PyLong_FromUnsignedLongLong(state->abc_invalidation_counter);
}

static struct PyMethodDef _abcmodule_methods[] = {
Expand All @@ -849,7 +846,8 @@ static int
_abcmodule_exec(PyObject *module)
{
_abcmodule_state *state = get_abc_state(module);
state->_abc_data_type = (PyTypeObject *)PyType_FromSpec(&_abc_data_type_spec);
state->abc_invalidation_counter = 0;
state->_abc_data_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &_abc_data_type_spec, NULL);
if (state->_abc_data_type == NULL) {
return -1;
}
Expand Down