summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephan Richter <stephan.richter@gmail.com>2014-02-04 23:21:42 -0500
committerStephan Richter <stephan.richter@gmail.com>2014-02-04 23:21:42 -0500
commit79a266200384fa53fb3810ed316a94394166f4e3 (patch)
treefbbe989594e10ea3a34752a1b6023b03c2dfd92c /src
parentffcf2887646c268c104ee2aa7bb3c087d691149b (diff)
downloadzope-interface-79a266200384fa53fb3810ed316a94394166f4e3.tar.gz
Added ``@named(name)`` declaration.
The decorator specifies the component name, so it does not have to be passed in during registration. This in turn allows developers to define component names once globally and use it everywhere, especially when using ZCML where the name had to be specified a second time.
Diffstat (limited to 'src')
-rw-r--r--src/zope/interface/__init__.py1
-rw-r--r--src/zope/interface/declarations.py9
-rw-r--r--src/zope/interface/registry.py17
-rw-r--r--src/zope/interface/tests/test_declarations.py45
-rw-r--r--src/zope/interface/tests/test_registry.py41
5 files changed, 103 insertions, 10 deletions
diff --git a/src/zope/interface/__init__.py b/src/zope/interface/__init__.py
index ad0a766..7753e39 100644
--- a/src/zope/interface/__init__.py
+++ b/src/zope/interface/__init__.py
@@ -57,6 +57,7 @@ from zope.interface.interface import _wire
_wire()
del _wire
+from zope.interface.declarations import named
from zope.interface.declarations import Declaration
from zope.interface.declarations import alsoProvides
from zope.interface.declarations import classImplements
diff --git a/src/zope/interface/declarations.py b/src/zope/interface/declarations.py
index 0992adc..06b1688 100644
--- a/src/zope/interface/declarations.py
+++ b/src/zope/interface/declarations.py
@@ -49,6 +49,15 @@ _ADVICE_ERROR = ('Class advice impossible in Python3. '
_ADVICE_WARNING = ('The %s API is deprecated, and will not work in Python3 '
'Use the @%s class decorator instead.')
+class named(object):
+
+ def __init__(self, name):
+ self.name = name
+
+ def __call__(self, ob):
+ ob.__component_name__ = self.name
+ return ob
+
class Declaration(Specification):
"""Interface declarations"""
diff --git a/src/zope/interface/registry.py b/src/zope/interface/registry.py
index 1882e0d..f8b14b7 100644
--- a/src/zope/interface/registry.py
+++ b/src/zope/interface/registry.py
@@ -79,7 +79,7 @@ class Components(object):
lambda self, bases: self._setBases(bases),
)
- def registerUtility(self, component=None, provided=None, name=_u(''),
+ def registerUtility(self, component=None, provided=None, name=_u(''),
info=_u(''), event=True, factory=None):
if factory:
if component:
@@ -89,6 +89,9 @@ class Components(object):
if provided is None:
provided = _getUtilityProvided(component)
+ if name == _u(''):
+ name = _getName(component)
+
reg = self._utility_registrations.get((provided, name))
if reg is not None:
if reg[:2] == (component, info):
@@ -176,11 +179,13 @@ class Components(object):
def getAllUtilitiesRegisteredFor(self, interface):
return self.utilities.subscriptions((), interface)
- def registerAdapter(self, factory, required=None, provided=None,
+ def registerAdapter(self, factory, required=None, provided=None,
name=_u(''), info=_u(''), event=True):
if provided is None:
provided = _getAdapterProvided(factory)
required = _getAdapterRequired(factory, required)
+ if name == _u(''):
+ name = _getName(factory)
self._adapter_registrations[(required, provided, name)
] = factory, info
self.adapters.register(required, provided, name, factory)
@@ -234,7 +239,7 @@ class Components(object):
raise ComponentLookupError(object, interface, name)
return adapter
- def queryMultiAdapter(self, objects, interface, name=_u(''),
+ def queryMultiAdapter(self, objects, interface, name=_u(''),
default=None):
return self.adapters.queryMultiAdapter(
objects, interface, name, default)
@@ -381,6 +386,12 @@ class Components(object):
self.adapters.subscribers(objects, None)
+def _getName(component):
+ try:
+ return component.__component_name__
+ except AttributeError:
+ return _u('')
+
def _getUtilityProvided(component):
provided = list(providedBy(component))
if len(provided) == 1:
diff --git a/src/zope/interface/tests/test_declarations.py b/src/zope/interface/tests/test_declarations.py
index 49991d0..2dadc64 100644
--- a/src/zope/interface/tests/test_declarations.py
+++ b/src/zope/interface/tests/test_declarations.py
@@ -15,7 +15,7 @@
"""
import unittest
-from zope.interface._compat import _skip_under_py3k
+from zope.interface._compat import _skip_under_py3k, _u
class _SilencePy3Deprecations(unittest.TestCase):
@@ -51,7 +51,38 @@ class _Py3ClassAdvice(object):
else:
if fails_under_py3k:
self.fail("Didn't raise TypeError")
-
+
+
+class NamedTests(unittest.TestCase):
+
+ def test_class(self):
+ from zope.interface.declarations import named
+
+ @named(_u('foo'))
+ class Foo(object):
+ pass
+
+ self.assertEqual(Foo.__component_name__, _u('foo'))
+
+ def test_function(self):
+ from zope.interface.declarations import named
+
+ @named(_u('foo'))
+ def doFoo(object):
+ pass
+
+ self.assertEqual(doFoo.__component_name__, _u('foo'))
+
+ def test_instance(self):
+ from zope.interface.declarations import named
+
+ class Foo(object):
+ pass
+ foo = Foo()
+ named(_u('foo'))(foo)
+
+ self.assertEqual(foo.__component_name__, _u('foo'))
+
class DeclarationTests(_SilencePy3Deprecations):
@@ -61,7 +92,7 @@ class DeclarationTests(_SilencePy3Deprecations):
def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)
-
+
def test_ctor_no_bases(self):
decl = self._makeOne()
self.assertEqual(list(decl.__bases__), [])
@@ -217,7 +248,7 @@ class DeclarationTests(_SilencePy3Deprecations):
other = self._makeOne(IBar, IBaz)
after = before + other
self.assertEqual(list(after), [IFoo, IBar, IBaz])
-
+
class ImplementsTests(_SilencePy3Deprecations):
@@ -227,19 +258,19 @@ class ImplementsTests(_SilencePy3Deprecations):
def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)
-
+
def test_ctor_no_bases(self):
impl = self._makeOne()
self.assertEqual(impl.inherit, None)
self.assertEqual(impl.declared, ())
self.assertEqual(impl.__name__, '?')
self.assertEqual(list(impl.__bases__), [])
-
+
def test___repr__(self):
impl = self._makeOne()
impl.__name__ = 'Testing'
self.assertEqual(repr(impl), '<implementedBy Testing>')
-
+
def test___reduce__(self):
from zope.interface.declarations import implementedBy
impl = self._makeOne()
diff --git a/src/zope/interface/tests/test_registry.py b/src/zope/interface/tests/test_registry.py
index f717c59..22b26df 100644
--- a/src/zope/interface/tests/test_registry.py
+++ b/src/zope/interface/tests/test_registry.py
@@ -81,6 +81,26 @@ class ComponentsTests(_SilencePy3Deprecations):
self.assertEqual(comp.utilities.__bases__,
(base1.utilities, base2.utilities))
+ def test_registerUtility_with_component_name(self):
+ from zope.interface.declarations import named, InterfaceClass
+ from zope.interface._compat import _u
+
+ class IFoo(InterfaceClass):
+ pass
+ ifoo = IFoo('IFoo')
+
+ @named(_u('foo'))
+ class Foo(object):
+ pass
+ foo = Foo()
+ _info = _u('info')
+
+ comp = self._makeOne()
+ comp.registerUtility(foo, ifoo, info=_info)
+ self.assertEqual(
+ comp._utility_registrations[ifoo, _u('foo')],
+ (foo, _info, None))
+
def test_registerUtility_both_factory_and_component(self):
def _factory():
pass
@@ -591,6 +611,27 @@ class ComponentsTests(_SilencePy3Deprecations):
self.assertEqual(list(comp.getAllUtilitiesRegisteredFor(ifoo)),
[_to_reg])
+ def test_registerAdapter_with_component_name(self):
+ from zope.interface.declarations import named, InterfaceClass
+ from zope.interface._compat import _u
+
+ class IFoo(InterfaceClass):
+ pass
+ ifoo = IFoo('IFoo')
+ ibar = IFoo('IBar')
+
+ @named(_u('foo'))
+ class Foo(object):
+ pass
+ _info = _u('info')
+
+ comp = self._makeOne()
+ comp.registerAdapter(Foo, (ibar,), ifoo, info=_info)
+
+ self.assertEqual(
+ comp._adapter_registrations[(ibar,), ifoo, _u('foo')],
+ (Foo, _info))
+
def test_registerAdapter_w_explicit_provided_and_required(self):
from zope.interface.declarations import InterfaceClass
from zope.interface.interfaces import Registered