[Python-checkins] bpo-40566: Apply PEP 573 to abc module (GH-20005)

Dong-hee Na webhook-mailer at python.org
Sat May 9 04:32:04 EDT 2020


https://github.com/python/cpython/commit/77c614624b6bf2145bef69830d0f499d8b55ec0c
commit: 77c614624b6bf2145bef69830d0f499d8b55ec0c
branch: master
author: Dong-hee Na <donghee.na92 at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-05-09T01:31:40-07:00
summary:

bpo-40566: Apply PEP 573 to abc module (GH-20005)

files:
A Misc/NEWS.d/next/Core and Builtins/2020-05-09-01-39-16.bpo-40566.wlcjW_.rst
M Modules/_abc.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-09-01-39-16.bpo-40566.wlcjW_.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-09-01-39-16.bpo-40566.wlcjW_.rst
new file mode 100644
index 0000000000000..92a5e3ce63217
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-09-01-39-16.bpo-40566.wlcjW_.rst	
@@ -0,0 +1 @@
+Apply :pep:`573` to :mod:`abc`.
diff --git a/Modules/_abc.c b/Modules/_abc.c
index 7c040ef80ba3d..434bc454175b5 100644
--- a/Modules/_abc.c
+++ b/Modules/_abc.c
@@ -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)
 {
@@ -81,14 +74,21 @@ static PyObject *
 abc_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
     _abc_data *self = (_abc_data *) type->tp_alloc(type, 0);
+    _abcmodule_state *state = NULL;
     if (self == NULL) {
         return NULL;
     }
 
+    state = PyType_GetModuleState(type);
+    if (state == NULL) {
+        Py_DECREF(self);
+        return NULL;
+    }
+
     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;
 }
 
@@ -495,7 +495,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;
@@ -540,7 +540,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;
@@ -612,6 +612,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);
@@ -629,15 +630,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);
@@ -830,7 +832,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[] = {
@@ -849,7 +852,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;
     }



More information about the Python-checkins mailing list