diff options
| author | Jason Madden <jason+github@nextthought.com> | 2016-08-31 07:41:51 -0500 |
|---|---|---|
| committer | Michael Howitz <mh@gocept.com> | 2016-08-31 14:41:51 +0200 |
| commit | 14c8b2966011bc0dcab7e908cd80cb61dfd413cb (patch) | |
| tree | 45731b513adb6d72bb19642db6b4f45cb569f826 /src | |
| parent | 21b7a985afd3ad0b0ff89b4ae25015daf63324d1 (diff) | |
| download | zope-interface-14c8b2966011bc0dcab7e908cd80cb61dfd413cb.tar.gz | |
Support Components subclasses that are not hashable. (#54)
* Support Components subclasses that are not hashable.
Fixes #53.
Diffstat (limited to 'src')
| -rw-r--r-- | src/zope/interface/registry.py | 20 | ||||
| -rw-r--r-- | src/zope/interface/tests/test_registry.py | 22 |
2 files changed, 31 insertions, 11 deletions
diff --git a/src/zope/interface/registry.py b/src/zope/interface/registry.py index 2e1b085..c2b588c 100644 --- a/src/zope/interface/registry.py +++ b/src/zope/interface/registry.py @@ -14,7 +14,7 @@ """Basic components support """ from collections import defaultdict -from weakref import WeakKeyDictionary +import weakref try: from zope.event import notify @@ -71,15 +71,18 @@ class _UnhashableComponentCounter(object): class _UtilityRegistrations(object): - _regs_for_components = WeakKeyDictionary() + _regs_for_components = {} + _weakrefs_for_components = {} @classmethod def for_components(cls, components): # We manage these utility/subscription registrations as associated # objects with a weakref to avoid making any changes to - # the pickle format + # the pickle format. They are keyed off the id of the component because + # Components subclasses are not guaranteed to be hashable. + key = id(components) try: - regs = cls._regs_for_components[components] + regs = cls._regs_for_components[key] except KeyError: regs = None else: @@ -91,7 +94,14 @@ class _UtilityRegistrations(object): if regs is None: regs = cls(components.utilities, components._utility_registrations) - cls._regs_for_components[components] = regs + cls._regs_for_components[key] = regs + + if key not in cls._weakrefs_for_components: + def _cleanup(r): + cls._weakrefs_for_components.pop(key) + cls._regs_for_components.pop(key) + + cls._weakrefs_for_components[key] = weakref.ref(components, _cleanup) return regs diff --git a/src/zope/interface/tests/test_registry.py b/src/zope/interface/tests/test_registry.py index c2a940a..852034e 100644 --- a/src/zope/interface/tests/test_registry.py +++ b/src/zope/interface/tests/test_registry.py @@ -2133,6 +2133,15 @@ class ComponentsTests(unittest.TestCase): self.assertEqual(_called_2, [bar]) +class UnhashableComponentsTests(ComponentsTests): + + def _getTargetClass(self): + # Mimic what pyramid does to create an unhashable + # registry + class Components(super(UnhashableComponentsTests, self)._getTargetClass(), dict): + pass + return Components + # Test _getUtilityProvided, _getAdapterProvided, _getAdapterRequired via their # callers (Component.registerUtility, Component.registerAdapter). @@ -2646,9 +2655,10 @@ class _Monkey(object): def test_suite(): return unittest.TestSuite(( - unittest.makeSuite(ComponentsTests), - unittest.makeSuite(UtilityRegistrationTests), - unittest.makeSuite(AdapterRegistrationTests), - unittest.makeSuite(SubscriptionRegistrationTests), - unittest.makeSuite(AdapterRegistrationTests), - )) + unittest.makeSuite(ComponentsTests), + unittest.makeSuite(UnhashableComponentsTests), + unittest.makeSuite(UtilityRegistrationTests), + unittest.makeSuite(AdapterRegistrationTests), + unittest.makeSuite(SubscriptionRegistrationTests), + unittest.makeSuite(AdapterRegistrationTests), + )) |
