def classImplements(cls, *interfaces): """Declare additional interfaces implemented for instances of a class The arguments after the class are one or more interfaces or interface specifications (`~zope.interface.interfaces.IDeclaration` objects). The interfaces given (including the interfaces in the specifications) are added to any interfaces previously declared. """ spec = implementedBy(cls) spec.declared += tuple(_normalizeargs(interfaces)) # compute the bases bases = [] seen = {} for b in spec.declared: if b not in seen: seen[b] = 1 bases.append(b) if spec.inherit is not None: for c in spec.inherit.__bases__: b = implementedBy(c) if b not in seen: seen[b] = 1 bases.append(b) spec.__bases__ = tuple(bases)
def classImplements(cls, *interfaces): """Declare additional interfaces implemented for instances of a class The arguments after the class are one or more interfaces or interface specifications (``IDeclaration`` objects). The interfaces given (including the interfaces in the specifications) are added to any interfaces previously declared. """ spec = implementedBy(cls) spec.declared += tuple(_normalizeargs(interfaces)) # compute the bases bases = [] seen = {} for b in spec.declared: if b not in seen: seen[b] = 1 bases.append(b) if spec.inherit is not None: for c in spec.inherit.__bases__: b = implementedBy(c) if b not in seen: seen[b] = 1 bases.append(b) spec.__bases__ = tuple(bases)
def __init__(self, cls, metacls, *interfaces): self._cls = cls self._implements = implementedBy(cls) self.__args = ( cls, metacls, ) + interfaces Declaration.__init__(self, *(interfaces + (implementedBy(metacls), )))
def providedByFallback(ob): # Here we have either a special object, an old-style declaration # or a descriptor # Try to get __providedBy__ try: r = ob.__providedBy__ except AttributeError: # Not set yet. Fall back to lower-level thing that computes it return getObjectSpecification(ob) try: # We might have gotten a descriptor from an instance of a # class (like an ExtensionClass) that doesn't support # descriptors. We'll make sure we got one by trying to get # the only attribute, which all specs have. r.extends except AttributeError: # The object's class doesn't understand descriptors. # Sigh. We need to get an object descriptor, but we have to be # careful. We want to use the instance's __provides__, if # there is one, but only if it didn't come from the class. try: r = ob.__provides__ except AttributeError: # No __provides__, so just fall back to implementedBy return implementedBy(ob.__class__) # We need to make sure we got the __provides__ from the # instance. We'll do this by making sure we don't get the same # thing from the class: try: cp = ob.__class__.__provides__ except AttributeError: # The ob doesn't have a class or the class has no # provides, assume we're done: return r if r is cp: # Oops, we got the provides from the class. This means # the object doesn't have it's own. We should use implementedBy return implementedBy(ob.__class__) return r
def __get__(self, inst, cls): """Get an object specification for an object """ if inst is None: return getObjectSpecification(cls) provides = getattr(inst, '__provides__', None) if provides is not None: return provides return implementedBy(cls)
def classImplementsOnly(cls, *interfaces): """Declare the only interfaces implemented by instances of a class The arguments after the class are one or more interfaces or interface specifications (`~zope.interface.interfaces.IDeclaration` objects). The interfaces given (including the interfaces in the specifications) replace any previous declarations. """ spec = implementedBy(cls) spec.declared = () spec.inherit = None classImplements(cls, *interfaces)
def classImplementsOnly(cls, *interfaces): """Declare the only interfaces implemented by instances of a class The arguments after the class are one or more interfaces or interface specifications (``IDeclaration`` objects). The interfaces given (including the interfaces in the specifications) replace any previous declarations. """ spec = implementedBy(cls) spec.declared = () spec.inherit = None classImplements(cls, *interfaces)
def getObjectSpecificationFallback(ob): provides = getattr(ob, '__provides__', None) if provides is not None: if isinstance(provides, SpecificationBase): return provides try: cls = ob.__class__ except AttributeError: # We can't get the class, so just consider provides return _empty return implementedBy(cls)
def implementedByFallback(cls): """Return the interfaces implemented for a class' instances The value returned is an `~zope.interface.interfaces.IDeclaration`. """ try: spec = cls.__dict__.get('__implemented__') except AttributeError: # we can't get the class dict. This is probably due to a # security proxy. If this is the case, then probably no # descriptor was installed for the class. # We don't want to depend directly on zope.security in # zope.interface, but we'll try to make reasonable # accommodations in an indirect way. # We'll check to see if there's an implements: spec = getattr(cls, '__implemented__', None) if spec is None: # There's no spec stred in the class. Maybe its a builtin: spec = BuiltinImplementationSpecifications.get(cls) if spec is not None: return spec return _empty if spec.__class__ == Implements: # we defaulted to _empty or there was a spec. Good enough. # Return it. return spec # TODO: need old style __implements__ compatibility? # Hm, there's an __implemented__, but it's not a spec. Must be # an old-style declaration. Just compute a spec for it return Declaration(*_normalizeargs((spec, ))) if isinstance(spec, Implements): return spec if spec is None: spec = BuiltinImplementationSpecifications.get(cls) if spec is not None: return spec # TODO: need old style __implements__ compatibility? spec_name = _implements_name(cls) if spec is not None: # old-style __implemented__ = foo declaration spec = (spec, ) # tuplefy, as it might be just an int spec = Implements.named(spec_name, *_normalizeargs(spec)) spec.inherit = None # old-style implies no inherit del cls.__implemented__ # get rid of the old-style declaration else: try: bases = cls.__bases__ except AttributeError: if not callable(cls): raise TypeError("ImplementedBy called for non-factory", cls) bases = () spec = Implements.named(spec_name, *[implementedBy(c) for c in bases]) spec.inherit = cls try: cls.__implemented__ = spec if not hasattr(cls, '__providedBy__'): cls.__providedBy__ = objectSpecificationDescriptor if (isinstance(cls, DescriptorAwareMetaClasses) and '__provides__' not in cls.__dict__): # Make sure we get a __provides__ descriptor cls.__provides__ = ClassProvides( cls, getattr(cls, '__class__', type(cls)), ) except TypeError: if not isinstance(cls, type): raise TypeError("ImplementedBy called for non-type", cls) BuiltinImplementationSpecifications[cls] = spec return spec
def __init__(self, cls, metacls, *interfaces): self._cls = cls self._implements = implementedBy(cls) self.__args = (cls, metacls, ) + interfaces Declaration.__init__(self, *(interfaces + (implementedBy(metacls), )))
def implementedByFallback(cls): """Return the interfaces implemented for a class' instances The value returned is an IDeclaration. """ try: spec = cls.__dict__.get('__implemented__') except AttributeError: # we can't get the class dict. This is probably due to a # security proxy. If this is the case, then probably no # descriptor was installed for the class. # We don't want to depend directly on zope.security in # zope.interface, but we'll try to make reasonable # accommodations in an indirect way. # We'll check to see if there's an implements: spec = getattr(cls, '__implemented__', None) if spec is None: # There's no spec stred in the class. Maybe its a builtin: spec = BuiltinImplementationSpecifications.get(cls) if spec is not None: return spec return _empty if spec.__class__ == Implements: # we defaulted to _empty or there was a spec. Good enough. # Return it. return spec # TODO: need old style __implements__ compatibility? # Hm, there's an __implemented__, but it's not a spec. Must be # an old-style declaration. Just compute a spec for it return Declaration(*_normalizeargs((spec, ))) if isinstance(spec, Implements): return spec if spec is None: spec = BuiltinImplementationSpecifications.get(cls) if spec is not None: return spec # TODO: need old style __implements__ compatibility? spec_name = _implements_name(cls) if spec is not None: # old-style __implemented__ = foo declaration spec = (spec, ) # tuplefy, as it might be just an int spec = Implements.named(spec_name, *_normalizeargs(spec)) spec.inherit = None # old-style implies no inherit del cls.__implemented__ # get rid of the old-style declaration else: try: bases = cls.__bases__ except AttributeError: if not callable(cls): raise TypeError("ImplementedBy called for non-factory", cls) bases = () spec = Implements.named(spec_name, *[implementedBy(c) for c in bases]) spec.inherit = cls try: cls.__implemented__ = spec if not hasattr(cls, '__providedBy__'): cls.__providedBy__ = objectSpecificationDescriptor if (isinstance(cls, DescriptorAwareMetaClasses) and '__provides__' not in cls.__dict__): # Make sure we get a __provides__ descriptor cls.__provides__ = ClassProvides( cls, getattr(cls, '__class__', type(cls)), ) except TypeError: if not isinstance(cls, type): raise TypeError("ImplementedBy called for non-type", cls) BuiltinImplementationSpecifications[cls] = spec return spec