Source code for grokcore.component.decorators

##############################################################################
#
# Copyright (c) 2006 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Grok
"""
import sys
import types

import zope.component
import zope.interface
from martian.error import GrokImportError
from martian.util import frame_is_module


[docs] class subscribe: """Declares that a function is to be registered as an event handler for the specified objects. Normally, an event handler is simply registered as a subscriber for the event interface. In case of object events, the event handler is registered as a subscriber for the object type and the event interface. """ def __init__(self, *args): self.subscribed = args def __call__(self, function): frame = sys._getframe(1) if not frame_is_module(frame): raise GrokImportError("@grok.subscribe can only be used on module " "level.") if not self.subscribed: raise GrokImportError("@grok.subscribe requires at least one " "argument.") # Add the function and subscribed interfaces to the # grok.subscribers module annotation. subscribers = frame.f_locals.get('__grok_subscribers__', None) if subscribers is None: frame.f_locals['__grok_subscribers__'] = subscribers = [] subscribers.append((function, self.subscribed)) # Also store the subscribed interfaces on the # attribute__component_adapts__ for provideHandler to register # the subscriber (in case you don't grok your package and # register it manually) return zope.component.adapter(*self.subscribed)(function)
[docs] class adapter(zope.component.adapter): """Registers the function as an adapter for the specific interface. The ``name`` argument must be a keyword argument and is optional. If given, a named adapter is registered. """ # Override the z.c.adapter decorator to force sanity checking and # have better error reporting and add the ability to capture the name def __init__(self, *interfaces, **kw): if not interfaces: raise GrokImportError( "@grok.adapter requires at least one argument.") if isinstance(interfaces[0], types.FunctionType): raise GrokImportError( "@grok.adapter requires at least one argument.") self.name = "" if kw: if 'name' in kw: self.name = kw.pop('name') if kw: raise GrokImportError( "@grok.adapter got unexpected keyword arguments: %s" % ','.join(kw.keys())) zope.component.adapter.__init__(self, *interfaces) def __call__(self, ob): ob = zope.component.adapter.__call__(self, ob) if self.name: ob.__component_name__ = self.name return ob
[docs] class implementer(zope.interface.implementer): """Declares that the function implements a certain interface (or a number of interfaces). This is useful when a function serves as an object factory, e.g. as an adapter. """ def __call__(self, ob): if not isinstance(ob, type): frame = sys._getframe(1) adapters = frame.f_locals.get('__grok_adapters__', None) if adapters is None: frame.f_locals['__grok_adapters__'] = adapters = [] adapters.append(ob) return zope.interface.implementer.__call__(self, ob)
class provider: """Declares that the function object provides a certain interface (or a number of interfaces). This is akin to calling directlyProvides() on the function object. """ def __init__(self, *interfaces): self.interfaces = interfaces def __call__(self, ob): if isinstance(ob, type): raise TypeError("Can't use implementer with classes. Use one of " "the class-declaration functions instead.") zope.interface.alsoProvides(ob, *self.interfaces) return ob