]> granicus.if.org Git - python/commitdiff
Fix #16832 - expose cache validity checking support in ABCMeta
authorŁukasz Langa <lukasz@langa.pl>
Sat, 25 May 2013 16:41:50 +0000 (18:41 +0200)
committerŁukasz Langa <lukasz@langa.pl>
Sat, 25 May 2013 16:41:50 +0000 (18:41 +0200)
Doc/library/abc.rst
Lib/abc.py
Lib/test/test_abc.py

index 27abb605fd716ba6cb2369d7314904cce18981e8..1f21b5750d4c9f3377ef5a600a5c18d4bce487a0 100644 (file)
@@ -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
index e807895da3e3f3f96277db185c9220010e18ff69..264c60c428b4d14ff95170a44917a81801aeba73 100644 (file)
@@ -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
index 349852450189ae8b906215117ae80cd8a446ecef..4b151575ba48e521596b3c00f3f96ba2268d108b 100644 (file)
@@ -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,)))