[Python-checkins] r84230 - in python/branches/release27-maint: Lib/abc.py Lib/test/test_abc.py Misc/NEWS Modules/Setup.dist

benjamin.peterson python-checkins at python.org
Sat Aug 21 05:03:22 CEST 2010


Author: benjamin.peterson
Date: Sat Aug 21 05:03:22 2010
New Revision: 84230

Log:
Use weakrefs to hold onto classes #2521.

This also causes the _weakref module to be built into the core.


Modified:
   python/branches/release27-maint/Lib/abc.py
   python/branches/release27-maint/Lib/test/test_abc.py
   python/branches/release27-maint/Misc/NEWS
   python/branches/release27-maint/Modules/Setup.dist

Modified: python/branches/release27-maint/Lib/abc.py
==============================================================================
--- python/branches/release27-maint/Lib/abc.py	(original)
+++ python/branches/release27-maint/Lib/abc.py	Sat Aug 21 05:03:22 2010
@@ -5,6 +5,7 @@
 
 import types
 
+from _weakrefset import WeakSet
 
 # Instance of old-style class
 class _C: pass
@@ -95,9 +96,9 @@
                     abstracts.add(name)
         cls.__abstractmethods__ = frozenset(abstracts)
         # Set up inheritance registry
-        cls._abc_registry = set()
-        cls._abc_cache = set()
-        cls._abc_negative_cache = set()
+        cls._abc_registry = WeakSet()
+        cls._abc_cache = WeakSet()
+        cls._abc_negative_cache = WeakSet()
         cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
         return cls
 
@@ -128,7 +129,7 @@
         """Override for isinstance(instance, cls)."""
         # Inline the cache checking when it's simple.
         subclass = getattr(instance, '__class__', None)
-        if subclass in cls._abc_cache:
+        if subclass is not None and subclass in cls._abc_cache:
             return True
         subtype = type(instance)
         # Old-style instances
@@ -152,7 +153,7 @@
         # Check negative cache; may have to invalidate
         if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter:
             # Invalidate the negative cache
-            cls._abc_negative_cache = set()
+            cls._abc_negative_cache = WeakSet()
             cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
         elif subclass in cls._abc_negative_cache:
             return False

Modified: python/branches/release27-maint/Lib/test/test_abc.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_abc.py	(original)
+++ python/branches/release27-maint/Lib/test/test_abc.py	Sat Aug 21 05:03:22 2010
@@ -3,7 +3,7 @@
 
 """Unit tests for abc.py."""
 
-import unittest
+import unittest, weakref
 from test import test_support
 
 import abc
@@ -208,6 +208,22 @@
         C()
         self.assertEqual(B.counter, 1)
 
+    def test_cache_leak(self):
+        # See issue #2521.
+        class A(object):
+            __metaclass__ = abc.ABCMeta
+            @abc.abstractmethod
+            def f(self):
+                pass
+        class C(A):
+            def f(self):
+                A.f(self)
+        r = weakref.ref(C)
+        # Trigger cache.
+        C().f()
+        del C
+        test_support.gc_collect()
+        self.assertEqual(r(), None)
 
 def test_main():
     test_support.run_unittest(TestABC)

Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS	(original)
+++ python/branches/release27-maint/Misc/NEWS	Sat Aug 21 05:03:22 2010
@@ -31,6 +31,9 @@
 Library
 -------
 
+- Issue #2521: Use weakrefs on for caching in the abc module, so that classes
+  are not held onto after they are deleted elsewhere.
+
 - Issue #9626: the view methods for collections.OrderedDict() were returning
   the unordered versions inherited from dict.  Those methods are now
   overridden to provide ordered views.
@@ -188,6 +191,9 @@
 Extension Modules
 -----------------
 
+- As a result of issue #2521, the _weakref module is now compiled into the
+  interpreter by default.
+
 - Issue #9324: Add parameter validation to signal.signal on Windows in order
   to prevent crashes.
 

Modified: python/branches/release27-maint/Modules/Setup.dist
==============================================================================
--- python/branches/release27-maint/Modules/Setup.dist	(original)
+++ python/branches/release27-maint/Modules/Setup.dist	Sat Aug 21 05:03:22 2010
@@ -118,6 +118,7 @@
 				# if $HOME is not set
 _sre _sre.c			# Fredrik Lundh's new regular expressions
 _codecs _codecsmodule.c		# access to the builtin codecs and codec registry
+_weakref _weakref.c             # weak references
 
 # The zipimport module is always imported at startup. Having it as a
 # builtin module avoids some bootstrapping problems and reduces overhead.


More information about the Python-checkins mailing list