diff options
author | Benjamin Peterson <benjamin@python.org> | 2010-08-21 03:03:22 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2010-08-21 03:03:22 (GMT) |
commit | 52c36051bded16cf8616996e271a1aafbe2ec908 (patch) | |
tree | 60a50ec3271030d68c7fe64088cbdc553fd1b9df /Lib | |
parent | b1147f5d0a89a24a978d9db93750ad5cc3829542 (diff) | |
download | cpython-52c36051bded16cf8616996e271a1aafbe2ec908.zip cpython-52c36051bded16cf8616996e271a1aafbe2ec908.tar.gz cpython-52c36051bded16cf8616996e271a1aafbe2ec908.tar.bz2 |
Use weakrefs to hold onto classes #2521.
This also causes the _weakref module to be built into the core.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/abc.py | 11 | ||||
-rw-r--r-- | Lib/test/test_abc.py | 18 |
2 files changed, 23 insertions, 6 deletions
@@ -5,6 +5,7 @@ import types +from _weakrefset import WeakSet # Instance of old-style class class _C: pass @@ -95,9 +96,9 @@ class ABCMeta(type): 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 @@ class ABCMeta(type): """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 @@ class ABCMeta(type): # 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 diff --git a/Lib/test/test_abc.py b/Lib/test/test_abc.py index b5af46b..6a8c3a1 100644 --- a/Lib/test/test_abc.py +++ b/Lib/test/test_abc.py @@ -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 @@ class TestABC(unittest.TestCase): 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) |