Fix #16832 - expose cache validity checking support in ABCMeta
This commit is contained in:
parent
b961955e95
commit
eadd8cf507
|
@ -58,6 +58,10 @@ This module provides the following classes:
|
|||
.. versionchanged:: 3.3
|
||||
Returns the registered subclass, to allow usage as a class decorator.
|
||||
|
||||
.. versionchanged:: 3.4
|
||||
To detect calls to :meth:`register`, you can use the
|
||||
:func:`get_cache_token` function.
|
||||
|
||||
You can also override this method in an abstract base class:
|
||||
|
||||
.. method:: __subclasshook__(subclass)
|
||||
|
@ -308,6 +312,19 @@ The :mod:`abc` module also provides the following decorators:
|
|||
:func:`abstractmethod`, making this decorator redundant.
|
||||
|
||||
|
||||
The :mod:`abc` module also provides the following functions:
|
||||
|
||||
.. function:: get_cache_token()
|
||||
|
||||
Returns the current abstract base class cache token.
|
||||
|
||||
The token is an opaque integer identifying the current version of the
|
||||
abstract base class cache for virtual subclasses. This number changes
|
||||
with every call to :meth:`ABCMeta.register` on any ABC.
|
||||
|
||||
.. versionadded:: 3.4
|
||||
|
||||
|
||||
.. rubric:: Footnotes
|
||||
|
||||
.. [#] C++ programmers should note that Python's virtual base class
|
||||
|
|
14
Lib/abc.py
14
Lib/abc.py
|
@ -5,6 +5,7 @@
|
|||
|
||||
from _weakrefset import WeakSet
|
||||
|
||||
|
||||
def abstractmethod(funcobj):
|
||||
"""A decorator indicating abstract methods.
|
||||
|
||||
|
@ -124,6 +125,8 @@ class ABCMeta(type):
|
|||
# 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.
|
||||
_abc_invalidation_counter = 0
|
||||
|
||||
def __new__(mcls, name, bases, namespace):
|
||||
|
@ -227,8 +230,19 @@ class ABCMeta(type):
|
|||
cls._abc_negative_cache.add(subclass)
|
||||
return False
|
||||
|
||||
|
||||
class ABC(metaclass=ABCMeta):
|
||||
"""Helper class that provides a standard way to create an ABC using
|
||||
inheritance.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def get_cache_token():
|
||||
"""Returns the current ABC cache token.
|
||||
|
||||
The token is an opaque integer identifying the current version of
|
||||
the ABC cache for virtual subclasses. This number changes with
|
||||
every call to ``register()`` on any ABC.
|
||||
"""
|
||||
return ABCMeta._abc_invalidation_counter
|
||||
|
|
|
@ -329,7 +329,10 @@ class TestABC(unittest.TestCase):
|
|||
b = B()
|
||||
self.assertFalse(isinstance(b, A))
|
||||
self.assertFalse(isinstance(b, (A,)))
|
||||
token_old = abc.get_cache_token()
|
||||
A.register(B)
|
||||
token_new = abc.get_cache_token()
|
||||
self.assertNotEqual(token_old, token_new)
|
||||
self.assertTrue(isinstance(b, A))
|
||||
self.assertTrue(isinstance(b, (A,)))
|
||||
|
||||
|
|
Loading…
Reference in New Issue