summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Madden <jason+github@nextthought.com>2016-08-30 09:50:16 -0500
committerGitHub <noreply@github.com>2016-08-30 09:50:16 -0500
commit4ad360e44ec52b742750c8201676d7fe934f5f2a (patch)
treefbff0354b5618d43094f8bd382321933589c6d08
parent8138c73db26b17ca1967daa2908845b2d2f21cb8 (diff)
parent1e2b756500b7b8518884ff4c3bd8bd64e62641a4 (diff)
downloadzope-interface-4ad360e44ec52b742750c8201676d7fe934f5f2a.tar.gz
Merge pull request #48 from zopefoundation/fix-46
Use dictionary lookups for testing subscribed status.
-rw-r--r--.coveragerc2
-rw-r--r--CHANGES.rst6
-rw-r--r--src/zope/interface/registry.py153
-rw-r--r--src/zope/interface/tests/test_registry.py190
4 files changed, 276 insertions, 75 deletions
diff --git a/.coveragerc b/.coveragerc
index 58d9a3a..507ddc7 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,4 +1,4 @@
[report]
exclude_lines =
- # pragma: no cover
+ pragma: no cover
class I[A-Z]\w+\((Interface|I[A-Z].*)\):
diff --git a/CHANGES.rst b/CHANGES.rst
index 191f2fe..643b5f4 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -12,6 +12,12 @@ Changes
- Make ``setuptools`` a hard dependency of ``setup.py``.
(https://github.com/zopefoundation/zope.interface/issues/13)
+- Change a linear algorithm (O(n)) in ``Components.registerUtility`` and
+ ``Components.unregisterUtility`` into a dictionary lookup (O(1)) for
+ hashable components. This substantially improves the time taken to
+ manipulate utilities in large registries at the cost of some
+ additional memory usage. (https://github.com/zopefoundation/zope.interface/issues/46)
+
4.2.0 (2016-06-10)
------------------
diff --git a/src/zope/interface/registry.py b/src/zope/interface/registry.py
index 83fcea2..2e1b085 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,129 @@ from zope.interface._compat import CLASS_TYPES
from zope.interface._compat import STRING_TYPES
+class _UnhashableComponentCounter(object):
+ # defaultdict(int)-like object for unhashable components
+
+ def __init__(self, otherdict):
+ # [(component, count)]
+ self._data = [item for item in otherdict.items()]
+
+ def __getitem__(self, key):
+ for component, count in self._data:
+ if component == 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, components):
+ # 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[components]
+ 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 components.utilities
+ or regs._utility_registrations is not components._utility_registrations):
+ regs = None
+
+ if regs is None:
+ regs = cls(components.utilities, components._utility_registrations)
+ cls._regs_for_components[components] = 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:
+ # The component is not hashable, and we have a dict. Switch to a strategy
+ # that doesn't use hashing.
+ prov = self._cache[provided] = _UnhashableComponentCounter(self._cache[provided])
+ prov[component] += 1
+
+ def __uncache_utility(self, provided, component):
+ provided = self._cache[provided]
+ # It seems like this line could raise a TypeError if component isn't
+ # hashable and we haven't yet switched to _UnhashableComponentCounter. 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 = provided[component]
+ count -= 1
+ if count == 0:
+ del provided[component]
+ else:
+ 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 +224,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 +254,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')