def registerFacet(cls, facet, *ifaces): """Registers a facet for class cls. The 'facet' argument is an adapter class which will be registered using its interfaces specified in __implements__ argument. Notes: the assigned key will have the name of the class cls. :param cls: :param facet: :param ifaces: optional list of interfaces to attach """ if not hasattr(cls, '_facets'): cls._facets = {} if not ifaces: raise ValueError("It is not possible to register a facet " "without specifing an interface") for iface in ifaces: if not isinstance(iface, InterfaceClass): raise TypeError('iface must be an Interface') if qual(iface) in cls._facets.keys(): raise TypeError( '%s does already have a facet for interface %s' % (cls.__name__, iface.__name__)) cls._facets[qual(iface)] = facet
def _adapter_hook(iface, obj): # Twisted's IPathImportMapper occasionally sends in None # which breaks isinstance, work-around. Johan 2008-09-29 if not isinstance(obj, Adaptable): return name = qual(iface) adapterCache = getattr(obj, '_adapterCache', {}) if name in adapterCache: return adapterCache[name] try: obj.getFacetType(iface) except LookupError: # zope.interface will handle this and raise TypeError, # see InterfaceClass.__call__ in zope/interface/interface.py return None
def getFacetType(cls, iface): """Fetches a facet type associated with an interface, or raise LookupError if the facet type cannot be found. :param iface: interface name for the facet to grab :returns: the facet type for the interface """ facets = getattr(cls, '_facets', []) iface_str = qual(iface) if not iface_str in facets: raise LookupError( "%s doesn't have a facet for interface %s" % (cls.__name__, iface.__name__)) return facets[iface_str]
def removeFacet(self, iface, *args, **kwargs): """Removes a facet from the current object :param iface: interface of the facet to remove """ if not isinstance(iface, InterfaceClass): raise TypeError('iface must be an Interface') facets = self.__class__._facets if not iface in facets: raise AdapterError('%s does not have a facet for interface %s' % (self.__class__.__name__, iface.__name__)) funcName = 'facet_%s_remove' % iface.__name__ func = getattr(self, funcName, None) if func: func(*args, **kwargs) k = qual(iface) del facets[k] if k in self._adapterCache: del self._adapterCache[k]
def addFacet(self, iface, *args, **kwargs): """Adds a facet implementing iface for the current object :param iface: interface of the facet to add :returns: the facet """ if isinstance(self, Adapter): raise TypeError("An adapter can not be adapted to another " "object.") if not isinstance(iface, InterfaceClass): raise TypeError('iface must be an Interface') if not hasattr(self, '_adapterCache'): self._adapterCache = {} k = qual(iface) if k in self._adapterCache: raise AdapterError('%s already has a facet for interface %s' % (self.__class__.__name__, iface.__name__)) facets = self.__class__._facets funcName = 'facet_%s_add' % iface.__name__ func = getattr(self, funcName, None) if func: adapter = func(*args, **kwargs) elif k in facets: adapterClass = facets[k] adapter = adapterClass(self, *args, **kwargs) else: raise AdapterError("The object type %s doesn't implement an " "adapter for interface %s" % (type(self), iface)) if adapter: self._adapterCache[k] = adapter return adapter