diff options
| author | Stephan Richter <stephan.richter@gmail.com> | 2014-02-04 23:21:42 -0500 |
|---|---|---|
| committer | Stephan Richter <stephan.richter@gmail.com> | 2014-02-04 23:21:42 -0500 |
| commit | 79a266200384fa53fb3810ed316a94394166f4e3 (patch) | |
| tree | fbbe989594e10ea3a34752a1b6023b03c2dfd92c /src | |
| parent | ffcf2887646c268c104ee2aa7bb3c087d691149b (diff) | |
| download | zope-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__.py | 1 | ||||
| -rw-r--r-- | src/zope/interface/declarations.py | 9 | ||||
| -rw-r--r-- | src/zope/interface/registry.py | 17 | ||||
| -rw-r--r-- | src/zope/interface/tests/test_declarations.py | 45 | ||||
| -rw-r--r-- | src/zope/interface/tests/test_registry.py | 41 |
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 |
