[Python-checkins] cpython: Fix #16832 - expose cache validity checking support in ABCMeta

lukasz.langa python-checkins at python.org
Sat May 25 18:42:15 CEST 2013


http://hg.python.org/cpython/rev/5b17d5ca2ff1
changeset:   83929:5b17d5ca2ff1
user:        Łukasz Langa <lukasz at langa.pl>
date:        Sat May 25 18:41:50 2013 +0200
summary:
  Fix #16832 - expose cache validity checking support in ABCMeta

files:
  Doc/library/abc.rst  |  17 +++++++++++++++++
  Lib/abc.py           |  14 ++++++++++++++
  Lib/test/test_abc.py |   3 +++
  3 files changed, 34 insertions(+), 0 deletions(-)


diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst
--- a/Doc/library/abc.rst
+++ b/Doc/library/abc.rst
@@ -58,6 +58,10 @@
       .. 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 @@
        :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
diff --git a/Lib/abc.py b/Lib/abc.py
--- a/Lib/abc.py
+++ b/Lib/abc.py
@@ -5,6 +5,7 @@
 
 from _weakrefset import WeakSet
 
+
 def abstractmethod(funcobj):
     """A decorator indicating abstract methods.
 
@@ -124,6 +125,8 @@
     # 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 @@
         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
diff --git a/Lib/test/test_abc.py b/Lib/test/test_abc.py
--- a/Lib/test/test_abc.py
+++ b/Lib/test/test_abc.py
@@ -329,7 +329,10 @@
         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,)))
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list