Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eadd8cf

Browse files
committed
Fix #16832 - expose cache validity checking support in ABCMeta
1 parent b961955 commit eadd8cf

3 files changed

Lines changed: 34 additions & 0 deletions

File tree

Doc/library/abc.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ This module provides the following classes:
5858
.. versionchanged:: 3.3
5959
Returns the registered subclass, to allow usage as a class decorator.
6060

61+
.. versionchanged:: 3.4
62+
To detect calls to :meth:`register`, you can use the
63+
:func:`get_cache_token` function.
64+
6165
You can also override this method in an abstract base class:
6266

6367
.. method:: __subclasshook__(subclass)
@@ -308,6 +312,19 @@ The :mod:`abc` module also provides the following decorators:
308312
:func:`abstractmethod`, making this decorator redundant.
309313

310314

315+
The :mod:`abc` module also provides the following functions:
316+
317+
.. function:: get_cache_token()
318+
319+
Returns the current abstract base class cache token.
320+
321+
The token is an opaque integer identifying the current version of the
322+
abstract base class cache for virtual subclasses. This number changes
323+
with every call to :meth:`ABCMeta.register` on any ABC.
324+
325+
.. versionadded:: 3.4
326+
327+
311328
.. rubric:: Footnotes
312329

313330
.. [#] C++ programmers should note that Python's virtual base class

Lib/abc.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from _weakrefset import WeakSet
77

8+
89
def abstractmethod(funcobj):
910
"""A decorator indicating abstract methods.
1011
@@ -124,6 +125,8 @@ class ABCMeta(type):
124125
# A global counter that is incremented each time a class is
125126
# registered as a virtual subclass of anything. It forces the
126127
# negative cache to be cleared before its next use.
128+
# Note: this counter is private. Use `abc.get_cache_token()` for
129+
# external code.
127130
_abc_invalidation_counter = 0
128131

129132
def __new__(mcls, name, bases, namespace):
@@ -227,8 +230,19 @@ def __subclasscheck__(cls, subclass):
227230
cls._abc_negative_cache.add(subclass)
228231
return False
229232

233+
230234
class ABC(metaclass=ABCMeta):
231235
"""Helper class that provides a standard way to create an ABC using
232236
inheritance.
233237
"""
234238
pass
239+
240+
241+
def get_cache_token():
242+
"""Returns the current ABC cache token.
243+
244+
The token is an opaque integer identifying the current version of
245+
the ABC cache for virtual subclasses. This number changes with
246+
every call to ``register()`` on any ABC.
247+
"""
248+
return ABCMeta._abc_invalidation_counter

Lib/test/test_abc.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,10 @@ class B:
329329
b = B()
330330
self.assertFalse(isinstance(b, A))
331331
self.assertFalse(isinstance(b, (A,)))
332+
token_old = abc.get_cache_token()
332333
A.register(B)
334+
token_new = abc.get_cache_token()
335+
self.assertNotEqual(token_old, token_new)
333336
self.assertTrue(isinstance(b, A))
334337
self.assertTrue(isinstance(b, (A,)))
335338

0 commit comments

Comments
 (0)