@@ -21,16 +21,9 @@ _Py_IDENTIFIER(__subclasshook__);
2121
2222typedef 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-
3427static inline _abcmodule_state *
3528get_abc_state (PyObject * module )
3629{
@@ -81,14 +74,21 @@ static PyObject *
8174abc_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
836839static 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