summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Madden <jamadden@gmail.com>2016-08-19 08:18:39 -0500
committerJason Madden <jamadden@gmail.com>2016-08-19 08:18:39 -0500
commit58ef4872922803fac3429d88fb3c58ae509b17c5 (patch)
tree2781bb0f904b30e2c81f62de0957a4cbc5cc03a6 /src
parentb0244a9140b5f3feb968326dfff5d99d303b61a3 (diff)
downloadzope-interface-58ef4872922803fac3429d88fb3c58ae509b17c5.tar.gz
Use dictionary lookups for testing subscribed status.
Fixes #46. Benchmarks show a dramatic improvement; not quite as good as the demonstration in #46 because the implementation had to be a bit more complex to properly handle unregistration, but still very good. Here it is with 20,000 items already registered: ``` %time add_to_reg(reg, 1000) CPU times: user 190 ms, sys: 19.3 ms, total: 209 ms Wall time: 203 ms ``` Here's a profile with about 100,000 utilities registered: ``` %prun add_to_reg(reg, 1000) 80005 function calls (79005 primitive calls) in 0.713 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 1000 0.596 0.001 0.621 0.001 adapter.py:202(subscribe) 12000 0.016 0.000 0.019 0.000 interface.py:518(__hash__) 1000 0.010 0.000 0.709 0.001 registry.py:206(registerUtility) 3000/2000 0.009 0.000 0.014 0.000 interface.py:255(interfaces) 2000 0.008 0.000 0.022 0.000 adapter.py:637(changed) 1000 0.008 0.000 0.025 0.000 registry.py:498(_getUtilityProvided) 9000 0.008 0.000 0.017 0.000 {method 'get' of 'dict' objects} 1000 0.008 0.000 0.027 0.000 adapter.py:102(register) 2000 0.006 0.000 0.008 0.000 adapter.py:450(changed) 1000 0.005 0.000 0.663 0.001 registry.py:145(registerUtility) ``` I was very careful not to change the pickle at all. zope.interface and zope.component tests have been run and both pass. (It was necessary to account for the underlying objects changing because of the way zope.component cleans up after tests.)
Diffstat (limited to 'src')
-rw-r--r--src/zope/interface/registry.py152
-rw-r--r--src/zope/interface/tests/test_registry.py190
2 files changed, 268 insertions, 74 deletions
diff --git a/src/zope/interface/registry.py b/src/zope/interface/registry.py
index 83fcea2..5f945f7 100644
--- a/src/zope/interface/registry.py
+++ b/src/zope/interface/registry.py
@@ -13,9 +13,12 @@
##############################################################################
"""Basic components support
"""
+from collections import defaultdict
+from weakref import WeakKeyDictionary
+
try:
from zope.event import notify
-except ImportError: #pragma NO COVER
+except ImportError: # pragma: no cover
def notify(*arg, **kw): pass
from zope.interface.interfaces import ISpecification
@@ -38,6 +41,128 @@ from zope.interface._compat import CLASS_TYPES
from zope.interface._compat import STRING_TYPES
+class _CacheList(object):
+ # defaultdict(int)-like object for unhashable components
+
+ def __init__(self, otherdict):
+ self._data = []
+ for comp, count in otherdict.items():
+ self._data.append((comp, count))
+
+ def __getitem__(self, key):
+ for comp, count in self._data:
+ if comp == key:
+ return count
+ return 0
+
+ def __setitem__(self, component, count):
+ for i, data in enumerate(self._data):
+ if data[0] == component:
+ self._data[i] = component, count
+ return
+ self._data.append((component, count))
+
+ def __delitem__(self, component):
+ for i, data in enumerate(self._data):
+ if data[0] == component:
+ del self._data[i]
+ return
+ raise KeyError(component) # pragma: no cover
+
+
+class _UtilityRegistrations(object):
+
+ _regs_for_components = WeakKeyDictionary()
+
+ @classmethod
+ def for_components(cls, comps):
+ # We manage these utility/subscription registrations as associated
+ # objects with a weakref to avoid making any changes to
+ # the pickle format
+ try:
+ regs = cls._regs_for_components[comps]
+ except KeyError:
+ regs = None
+ else:
+ # In case the components have been re-initted, clear the cache
+ # (zope.component.testing does this between tests)
+ if (regs._utilities is not comps.utilities
+ or regs._utility_registrations is not comps._utility_registrations):
+ regs = None
+
+ if regs is None:
+ regs = cls(comps.utilities, comps._utility_registrations)
+ cls._regs_for_components[comps] = regs
+
+ return regs
+
+ @classmethod
+ def clear_cache(cls):
+ cls._regs_for_components.clear()
+
+ def __init__(self, utilities, utility_registrations):
+ # {provided -> {component: count}}
+ self._cache = defaultdict(lambda: defaultdict(int))
+ self._utilities = utilities
+ self._utility_registrations = utility_registrations
+
+ self.__populate_cache()
+
+ def __populate_cache(self):
+ for ((p, _), data) in iter(self._utility_registrations.items()):
+ component = data[0]
+ self.__cache_utility(p, component)
+
+ def __cache_utility(self, provided, component):
+ try:
+ self._cache[provided][component] += 1
+ except TypeError:
+ # Not hashable, and we have a dict. Switch to a list.
+ self._cache[provided] = _CacheList(self._cache[provided])
+ self._cache[provided][component] += 1
+
+ def __uncache_utility(self, provided, component):
+ # It seems like this line could raise a TypeError if component isn't
+ # hashable and we haven't yet switched to _CacheList. However,
+ # we can't actually get in that situation. In order to get here, we would
+ # have had to cache the utility already which would have switched
+ # the datastructure if needed.
+ count = self._cache[provided][component]
+ count -= 1
+ if count == 0:
+ del self._cache[provided][component]
+ else:
+ self._cache[provided][component] = count
+ return count > 0
+
+ def _is_utility_subscribed(self, provided, component):
+ try:
+ return self._cache[provided][component] > 0
+ except TypeError:
+ # Not hashable and we're still using a dict
+ return False
+
+ def registerUtility(self, provided, name, component, info, factory):
+ subscribed = self._is_utility_subscribed(provided, component)
+
+ self._utility_registrations[(provided, name)] = component, info, factory
+ self._utilities.register((), provided, name, component)
+
+ if not subscribed:
+ self._utilities.subscribe((), provided, component)
+
+ self.__cache_utility(provided, component)
+
+ def unregisterUtility(self, provided, name, component):
+ del self._utility_registrations[(provided, name)]
+ self._utilities.unregister((), provided, name)
+
+ subscribed = self.__uncache_utility(provided, component)
+
+ if not subscribed:
+ self._utilities.unsubscribe((), provided, component)
+
+
@implementer(IComponents)
class Components(object):
@@ -98,17 +223,7 @@ class Components(object):
return
self.unregisterUtility(reg[0], provided, name)
- subscribed = False
- for ((p, _), data) in iter(self._utility_registrations.items()):
- if p == provided and data[0] == component:
- subscribed = True
- break
-
- self._utility_registrations[(provided, name)] = component, info, factory
- self.utilities.register((), provided, name, component)
-
- if not subscribed:
- self.utilities.subscribe((), provided, component)
+ _UtilityRegistrations.for_components(self).registerUtility(provided, name, component, info, factory)
if event:
notify(Registered(
@@ -138,18 +253,7 @@ class Components(object):
component = old[0]
# Note that component is now the old thing registered
-
- del self._utility_registrations[(provided, name)]
- self.utilities.unregister((), provided, name)
-
- subscribed = False
- for ((p, _), data) in iter(self._utility_registrations.items()):
- if p == provided and data[0] == component:
- subscribed = True
- break
-
- if not subscribed:
- self.utilities.unsubscribe((), provided, component)
+ _UtilityRegistrations.for_components(self).unregisterUtility(provided, name, component)
notify(Unregistered(
UtilityRegistration(self, provided, name, component, *old[1:])
diff --git a/src/zope/interface/tests/test_registry.py b/src/zope/interface/tests/test_registry.py
index 571bab3..c2a940a 100644
--- a/src/zope/interface/tests/test_registry.py
+++ b/src/zope/interface/tests/test_registry.py
@@ -73,7 +73,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerUtility_with_component_name(self):
from zope.interface.declarations import named, InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
@@ -103,7 +103,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Registered
from zope.interface.registry import UtilityRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -135,7 +135,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Registered
from zope.interface.registry import UtilityRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -163,7 +163,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerUtility_no_provided_available(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
class Foo(object):
@@ -181,7 +181,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Registered
from zope.interface.registry import UtilityRegistration
-
+
class IFoo(InterfaceClass):
pass
class Foo(object):
@@ -210,7 +210,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerUtility_duplicates_existing_reg(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -226,7 +226,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerUtility_w_different_info(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -247,7 +247,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerUtility_w_different_names_same_component(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -274,7 +274,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.interfaces import Unregistered
from zope.interface.interfaces import Registered
from zope.interface.registry import UtilityRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -312,7 +312,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerUtility_w_existing_subscr(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -329,7 +329,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerUtility_wo_event(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -357,7 +357,7 @@ class ComponentsTests(unittest.TestCase):
def test_unregisterUtility_w_component_miss(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -374,7 +374,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Unregistered
from zope.interface.registry import UtilityRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -405,7 +405,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Unregistered
from zope.interface.registry import UtilityRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -437,7 +437,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Unregistered
from zope.interface.registry import UtilityRegistration
-
+
class IFoo(InterfaceClass):
pass
class Foo(object):
@@ -471,7 +471,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Unregistered
from zope.interface.registry import UtilityRegistration
-
+
class IFoo(InterfaceClass):
pass
class Foo(object):
@@ -503,7 +503,7 @@ class ComponentsTests(unittest.TestCase):
def test_unregisterUtility_w_existing_subscr(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -519,9 +519,77 @@ class ComponentsTests(unittest.TestCase):
comp.unregisterUtility(_to_reg, ifoo, _name2)
self.assertEqual(comp.utilities._subscribers[0][ifoo][''], (_to_reg,))
+ def test_unregisterUtility_w_existing_subscr_non_hashable(self):
+ from zope.interface.declarations import InterfaceClass
+
+ class IFoo(InterfaceClass):
+ pass
+ ifoo = IFoo('IFoo')
+ _info = u'info'
+ _name1 = u'name1'
+ _name2 = u'name2'
+ _to_reg = dict()
+ comp = self._makeOne()
+ comp.registerUtility(_to_reg, ifoo, _name1, _info)
+ comp.registerUtility(_to_reg, ifoo, _name2, _info)
+ _monkey, _events = self._wrapEvents()
+ with _monkey:
+ comp.unregisterUtility(_to_reg, ifoo, _name2)
+ self.assertEqual(comp.utilities._subscribers[0][ifoo][''], (_to_reg,))
+
+ def test_unregisterUtility_w_existing_subscr_non_hashable_fresh_cache(self):
+ # We correctly populate the cache of registrations if it has gone away
+ # (for example, the Components was unpickled)
+ from zope.interface.declarations import InterfaceClass
+ from zope.interface.registry import _UtilityRegistrations
+
+ class IFoo(InterfaceClass):
+ pass
+ ifoo = IFoo('IFoo')
+ _info = u'info'
+ _name1 = u'name1'
+ _name2 = u'name2'
+ _to_reg = dict()
+ comp = self._makeOne()
+ comp.registerUtility(_to_reg, ifoo, _name1, _info)
+ comp.registerUtility(_to_reg, ifoo, _name2, _info)
+
+ _UtilityRegistrations.clear_cache()
+
+ _monkey, _events = self._wrapEvents()
+ with _monkey:
+ comp.unregisterUtility(_to_reg, ifoo, _name2)
+ self.assertEqual(comp.utilities._subscribers[0][ifoo][''], (_to_reg,))
+
+ def test_unregisterUtility_w_existing_subscr_non_hashable_reinitted(self):
+ # We correctly populate the cache of registrations if the base objects change
+ # out from under us
+ from zope.interface.declarations import InterfaceClass
+
+ class IFoo(InterfaceClass):
+ pass
+ ifoo = IFoo('IFoo')
+ _info = u'info'
+ _name1 = u'name1'
+ _name2 = u'name2'
+ _to_reg = dict()
+ comp = self._makeOne()
+ comp.registerUtility(_to_reg, ifoo, _name1, _info)
+ comp.registerUtility(_to_reg, ifoo, _name2, _info)
+
+ # zope.component.testing does this
+ comp.__init__('base')
+ comp.registerUtility(_to_reg, ifoo, _name2, _info)
+
+ _monkey, _events = self._wrapEvents()
+ with _monkey:
+ # Nothing to do, but we don't break either
+ comp.unregisterUtility(_to_reg, ifoo, _name2)
+ self.assertEqual(0, len(comp.utilities._subscribers))
+
def test_unregisterUtility_w_existing_subscr_other_component(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -539,13 +607,35 @@ class ComponentsTests(unittest.TestCase):
self.assertEqual(comp.utilities._subscribers[0][ifoo][''],
(_other_reg,))
+ def test_unregisterUtility_w_existing_subscr_other_component_mixed_hash(self):
+ from zope.interface.declarations import InterfaceClass
+
+ class IFoo(InterfaceClass):
+ pass
+ ifoo = IFoo('IFoo')
+ _info = u'info'
+ _name1 = u'name1'
+ _name2 = u'name2'
+ # First register something hashable
+ _other_reg = object()
+ # Then it transfers to something unhashable
+ _to_reg = dict()
+ comp = self._makeOne()
+ comp.registerUtility(_other_reg, ifoo, _name1, _info)
+ comp.registerUtility(_to_reg, ifoo, _name2, _info)
+ _monkey, _events = self._wrapEvents()
+ with _monkey:
+ comp.unregisterUtility(_to_reg, ifoo, _name2)
+ self.assertEqual(comp.utilities._subscribers[0][ifoo][''],
+ (_other_reg,))
+
def test_registeredUtilities_empty(self):
comp = self._makeOne()
self.assertEqual(list(comp.registeredUtilities()), [])
def test_registeredUtilities_notempty(self):
from zope.interface.declarations import InterfaceClass
-
+
from zope.interface.registry import UtilityRegistration
class IFoo(InterfaceClass):
pass
@@ -630,7 +720,7 @@ class ComponentsTests(unittest.TestCase):
def test_getUtilitiesFor_hit(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -653,7 +743,7 @@ class ComponentsTests(unittest.TestCase):
def test_getAllUtilitiesRegisteredFor_hit(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -668,7 +758,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerAdapter_with_component_name(self):
from zope.interface.declarations import named, InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
@@ -691,7 +781,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Registered
from zope.interface.registry import AdapterRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -724,7 +814,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerAdapter_no_provided_available(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -744,7 +834,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import implementer
from zope.interface.interfaces import Registered
from zope.interface.registry import AdapterRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -779,7 +869,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerAdapter_no_required_available(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -795,7 +885,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerAdapter_w_invalid_required(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -814,7 +904,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.interface import Interface
from zope.interface.interfaces import Registered
from zope.interface.registry import AdapterRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -851,7 +941,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import implementedBy
from zope.interface.interfaces import Registered
from zope.interface.registry import AdapterRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -889,7 +979,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerAdapter_w_required_containing_junk(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -907,7 +997,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Registered
from zope.interface.registry import AdapterRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -942,7 +1032,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerAdapter_wo_event(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -1089,7 +1179,7 @@ class ComponentsTests(unittest.TestCase):
def test_registeredAdapters_notempty(self):
from zope.interface.declarations import InterfaceClass
-
+
from zope.interface.registry import AdapterRegistration
class IFoo(InterfaceClass):
pass
@@ -1359,7 +1449,7 @@ class ComponentsTests(unittest.TestCase):
def test_getAdapters_non_empty(self):
from zope.interface.declarations import InterfaceClass
from zope.interface.declarations import implementer
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -1393,7 +1483,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerSubscriptionAdapter_w_nonblank_name(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -1411,7 +1501,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Registered
from zope.interface.registry import SubscriptionRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -1449,7 +1539,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import implementer
from zope.interface.interfaces import Registered
from zope.interface.registry import SubscriptionRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -1487,7 +1577,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Registered
from zope.interface.registry import SubscriptionRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -1523,7 +1613,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerSubscriptionAdapter_wo_event(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -1546,7 +1636,7 @@ class ComponentsTests(unittest.TestCase):
def test_registeredSubscriptionAdapters_notempty(self):
from zope.interface.declarations import InterfaceClass
-
+
from zope.interface.registry import SubscriptionRegistration
class IFoo(InterfaceClass):
pass
@@ -1579,7 +1669,7 @@ class ComponentsTests(unittest.TestCase):
def test_unregisterSubscriptionAdapter_w_nonblank_name(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -1790,7 +1880,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerHandler_w_nonblank_name(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -1805,7 +1895,7 @@ class ComponentsTests(unittest.TestCase):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Registered
from zope.interface.registry import HandlerRegistration
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -1837,7 +1927,7 @@ class ComponentsTests(unittest.TestCase):
def test_registerHandler_wo_explicit_required_no_event(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -1892,10 +1982,10 @@ class ComponentsTests(unittest.TestCase):
self.assertEqual(subscribers[1].name, '')
self.assertEqual(subscribers[1].factory, _factory2)
self.assertEqual(subscribers[1].info, '')
-
+
def test_unregisterHandler_w_nonblank_name(self):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -2055,7 +2145,7 @@ class UtilityRegistrationTests(unittest.TestCase):
def _makeOne(self, component=None, factory=None):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -2240,7 +2330,7 @@ class AdapterRegistrationTests(unittest.TestCase):
def _makeOne(self, component=None):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -2449,7 +2539,7 @@ class SubscriptionRegistrationTests(unittest.TestCase):
def _makeOne(self, component=None):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')
@@ -2486,7 +2576,7 @@ class HandlerRegistrationTests(unittest.TestCase):
def _makeOne(self, component=None):
from zope.interface.declarations import InterfaceClass
-
+
class IFoo(InterfaceClass):
pass
ifoo = IFoo('IFoo')