def __init__(self, name, bases=(), attrs=None, __doc__=None, __module__=None): if attrs is not None: if __module__ == None and attrs.has_key('__module__'): __module__ = attrs['__module__'] del attrs['__module__'] if __doc__ == None and attrs.has_key('__doc__'): __doc__ = attrs['__doc__'] del attrs['__doc__'] for k, v in attrs.items(): if isinstance(v, types.FunctionType): # Look here: the following line is the only useful thing # this function is actually doing. z.i interfaces don't # specify self as the first argument, but t.p.c interfaces # do, so we need to use the imlevel=1 argument. attrs[k] = interface.fromFunction(v, name, name=k, imlevel=1) elif not isinstance(v, interface.Attribute): raise interface.InvalidInterface("Concrete attribute, %s" % k) # BEHOLD A GREAT EVIL SHALL COME UPON THEE if __module__ == None: __module__ = sys._getframe(1).f_globals['__name__'] if not __module__.startswith("twisted."): # Don't warn for use within twisted, because twisted classes must # not be switched to z.i.Interface yet, b/c we forgot to deprecate # the "default" kwarg to __call__. Also when t.p.c.Interface is # removed, the rest of twisted can be updated simultaneously. But # everyone else should just use z.i.Interface directly now. warnings.warn("twisted.python.components.Interface is deprecated in Twisted 2.3. Use zope.interface.Interface instead. (also note that you should not use 'self' as the first arg on function decls in z.i.Interfaces).", ComponentsDeprecationWarning, stacklevel=2) return interface.InterfaceClass.__init__(self, name, bases, attrs, __doc__, __module__)
def __init__(self, name, bases=(), attrs=None, __doc__=None, __module__=None): self.__attrs = {} if attrs is not None: if __module__ == None and attrs.has_key('__module__'): __module__ = attrs['__module__'] del attrs['__module__'] if __doc__ == None and attrs.has_key('__doc__'): __doc__ = attrs['__doc__'] del attrs['__doc__'] if attrs.has_key("__adapt__"): warnings.warn("Please don't use __adapt__ on Interface subclasses", ComponentsDeprecationWarning, stacklevel=2) self.__instadapt__ = attrs["__adapt__"] del attrs["__adapt__"] for k, v in attrs.items(): if isinstance(v, types.FunctionType): attrs[k] = interface.fromFunction(v, name, name=k, imlevel=1) elif not isinstance(v, interface.Attribute): why = "Please only use functions and zope.interface.Attributes as Interface class attributes (.%s)" % (k,) warnings.warn(why, ComponentsDeprecationWarning, stacklevel=2) self.__attrs[k] = v attrs[k] = interface.Attribute(repr(v)) # BEHOLD A GREAT EVIL SHALL COME UPON THEE if __module__ == None: __module__ = sys._getframe(1).f_globals['__name__'] return interface.InterfaceClass.__init__(self, name, bases, attrs, __doc__, __module__)
def _verify(iface, candidate, tentative=0, vtype=None): """Verify that 'candidate' might correctly implements 'iface'. This involves: o Making sure the candidate defines all the necessary methods o Making sure the methods have the correct signature o Making sure the candidate asserts that it implements the interface Note that this isn't the same as verifying that the class does implement the interface. If optional tentative is true, suppress the "is implemented by" test. """ if vtype == 'c': tester = iface.implementedBy else: tester = iface.providedBy if not tentative and not tester(candidate): raise DoesNotImplement(iface) for n, d in iface.namesAndDescriptions(1): if not hasattr(candidate, n): if (not isinstance(d, Method)) and vtype == 'c': # We can't verify non-methods on classes, since the # class may provide attrs in it's __init__. continue raise BrokenImplementation(iface, n) attr = getattr(candidate, n) if not isinstance(d, Method): # If it's not a method, there's nothing else we can test continue if type(attr) is FunctionType: # should never get here meth = fromFunction(attr, n) elif (isinstance(attr, MethodTypes) and type(attr.im_func) is FunctionType): meth = fromMethod(attr, n) else: if not callable(attr): raise BrokenMethodImplementation(n, "Not a method") # sigh, it's callable,but we don't know how to intrspect it, so # we have to give it a pass. continue d=d.getSignatureInfo() meth = meth.getSignatureInfo() mess = _incompat(d, meth) if mess: raise BrokenMethodImplementation(n, mess) return True
def __setitem__(self, name, value): value = removeAllProxies(value) if isinstance(value, Attribute): value.interface = name if not value.__name__: value.__name__ = name elif isinstance(value, FunctionType): attrs[name] = fromFunction(value, name, name=name) else: raise InvalidInterface("Concrete attribute, %s" % name) setitem(self, self._attrs.__setitem__, name, value)
def __method_from_function(self, function, name): method = fromFunction(function, self, name=name) # Eliminate the leading *self*, which is implied in # an interface, but explicit in an ABC. method.positional = method.positional[1:] return method
def _verify(iface, candidate, tentative=0, vtype=None): """Verify that 'candidate' might correctly implements 'iface'. This involves: o Making sure the candidate defines all the necessary methods o Making sure the methods have the correct signature o Making sure the candidate asserts that it implements the interface Note that this isn't the same as verifying that the class does implement the interface. If optional tentative is true, suppress the "is implemented by" test. """ if vtype == 'c': tester = iface.implementedBy else: tester = iface.providedBy if not tentative and not tester(candidate): raise DoesNotImplement(iface) # Here the `desc` is either an `Attribute` or `Method` instance for name, desc in iface.namesAndDescriptions(1): try: attr = getattr(candidate, name) except AttributeError: if (not isinstance(desc, Method)) and vtype == 'c': # We can't verify non-methods on classes, since the # class may provide attrs in it's __init__. continue raise BrokenImplementation(iface, name) if not isinstance(desc, Method): # If it's not a method, there's nothing else we can test continue if isinstance(attr, FunctionType): if sys.version_info[0] >= 3 and isinstance(candidate, type) and vtype == 'c': # This is an "unbound method" in Python 3. # Only unwrap this if we're verifying implementedBy; # otherwise we can unwrap @staticmethod on classes that directly # provide an interface. meth = fromFunction(attr, iface, name=name, imlevel=1) else: # Nope, just a normal function meth = fromFunction(attr, iface, name=name) elif (isinstance(attr, MethodTypes) and type(attr.__func__) is FunctionType): meth = fromMethod(attr, iface, name) elif isinstance(attr, property) and vtype == 'c': # We without an instance we cannot be sure it's not a # callable. continue else: if not callable(attr): raise BrokenMethodImplementation(name, "Not a method") # sigh, it's callable, but we don't know how to introspect it, so # we have to give it a pass. continue # Make sure that the required and implemented method signatures are # the same. desc = desc.getSignatureInfo() meth = meth.getSignatureInfo() mess = _incompat(desc, meth) if mess: raise BrokenMethodImplementation(name, mess) return True
def _verify(iface, candidate, tentative=0, vtype=None): """Verify that 'candidate' might correctly implements 'iface'. This involves: o Making sure the candidate defines all the necessary methods o Making sure the methods have the correct signature o Making sure the candidate asserts that it implements the interface Note that this isn't the same as verifying that the class does implement the interface. If optional tentative is true, suppress the "is implemented by" test. """ if vtype == 'c': tester = iface.implementedBy else: tester = iface.providedBy if not tentative and not tester(candidate): raise DoesNotImplement(iface) # Here the `desc` is either an `Attribute` or `Method` instance for name, desc in iface.namesAndDescriptions(1): try: attr = getattr(candidate, name) except AttributeError: if (not isinstance(desc, Method)) and vtype == 'c': # We can't verify non-methods on classes, since the # class may provide attrs in it's __init__. continue raise BrokenImplementation(iface, name) if not isinstance(desc, Method): # If it's not a method, there's nothing else we can test continue if isinstance(attr, FunctionType): if sys.version[0] == '3' and isinstance(candidate, type): # This is an "unbound method" in Python 3. meth = fromFunction(attr, iface, name=name, imlevel=1) #pragma NO COVERAGE else: # Nope, just a normal function meth = fromFunction(attr, iface, name=name) elif (isinstance(attr, MethodTypes) and type(attr.__func__) is FunctionType): meth = fromMethod(attr, iface, name) elif isinstance(attr, property) and vtype == 'c': # We without an instance we cannot be sure it's not a # callable. continue else: if not callable(attr): raise BrokenMethodImplementation(name, "Not a method") # sigh, it's callable, but we don't know how to introspect it, so # we have to give it a pass. continue #pragma NO COVERAGE # Make sure that the required and implemented method signatures are # the same. desc = desc.getSignatureInfo() meth = meth.getSignatureInfo() mess = _incompat(desc, meth) if mess: raise BrokenMethodImplementation(name, mess) return True
def _verify(iface, candidate, tentative=0, vtype=None): """Verify that 'candidate' might correctly implements 'iface'. This involves: o Making sure the candidate defines all the necessary methods o Making sure the methods have the correct signature o Making sure the candidate asserts that it implements the interface Note that this isn't the same as verifying that the class does implement the interface. If optional tentative is true, suppress the "is implemented by" test. """ if vtype == 'c': tester = iface.implementedBy else: tester = iface.providedBy violations = [] def format(e): return " " + str(e).strip() + "\n" if not tentative and not tester(candidate): violations.append(format(DoesNotImplement(iface))) # Here the `desc` is either an `Attribute` or `Method` instance for name, desc in iface.namesAndDescriptions(1): if not hasattr(candidate, name): if (not isinstance(desc, Method)) and vtype == 'c': # We can't verify non-methods on classes, since the # class may provide attrs in it's __init__. continue if isinstance(desc, Method): violations.append(" The %r method was not provided.\n" % (name,)) else: violations.append(" The %r attribute was not provided.\n" % (name,)) continue attr = getattr(candidate, name) if not isinstance(desc, Method): # If it's not a method, there's nothing else we can test continue if isinstance(attr, FunctionType): # should never get here, since classes should not provide functions meth = fromFunction(attr, iface, name=name) elif (isinstance(attr, MethodTypes) and type(attr.im_func) is FunctionType): meth = fromMethod(attr, iface, name) else: if not callable(attr): violations.append(format(BrokenMethodImplementation(name, "Not a method"))) # sigh, it's callable, but we don't know how to intrspect it, so # we have to give it a pass. continue # Make sure that the required and implemented method signatures are # the same. desc = desc.getSignatureInfo() meth = meth.getSignatureInfo() mess = _incompat(desc, meth) if mess: violations.append(format(BrokenMethodImplementation(name, mess))) if violations: raise Exception("".join(violations)) return True
def _verify_element(iface, name, desc, candidate, vtype): # Here the `desc` is either an `Attribute` or `Method` instance try: attr = getattr(candidate, name) except AttributeError: if (not isinstance(desc, Method)) and vtype == 'c': # We can't verify non-methods on classes, since the # class may provide attrs in it's __init__. return # TODO: On Python 3, this should use ``raise...from`` raise BrokenImplementation(iface, desc, candidate) if not isinstance(desc, Method): # If it's not a method, there's nothing else we can test return if inspect.ismethoddescriptor(attr) or inspect.isbuiltin(attr): # The first case is what you get for things like ``dict.pop`` # on CPython (e.g., ``verifyClass(IFullMapping, dict))``). The # second case is what you get for things like ``dict().pop`` on # CPython (e.g., ``verifyObject(IFullMapping, dict()))``. # In neither case can we get a signature, so there's nothing # to verify. Even the inspect module gives up and raises # ValueError: no signature found. The ``__text_signature__`` attribute # isn't typically populated either. # # Note that on PyPy 2 or 3 (up through 7.3 at least), these are # not true for things like ``dict.pop`` (but might be true for C extensions?) return if isinstance(attr, FunctionType): if sys.version_info[0] >= 3 and isinstance(candidate, type) and vtype == 'c': # This is an "unbound method" in Python 3. # Only unwrap this if we're verifying implementedBy; # otherwise we can unwrap @staticmethod on classes that directly # provide an interface. meth = fromFunction(attr, iface, name=name, imlevel=1) else: # Nope, just a normal function meth = fromFunction(attr, iface, name=name) elif (isinstance(attr, MethodTypes) and type(attr.__func__) is FunctionType): meth = fromMethod(attr, iface, name) elif isinstance(attr, property) and vtype == 'c': # Without an instance we cannot be sure it's not a # callable. # TODO: This should probably check inspect.isdatadescriptor(), # a more general form than ``property`` return else: if not callable(attr): raise BrokenMethodImplementation(desc, "implementation is not a method", attr, iface, candidate) # sigh, it's callable, but we don't know how to introspect it, so # we have to give it a pass. return # Make sure that the required and implemented method signatures are # the same. mess = _incompat(desc.getSignatureInfo(), meth.getSignatureInfo()) if mess: if PYPY2 and _pypy2_false_positive(mess, candidate, vtype): return raise BrokenMethodImplementation(desc, mess, attr, iface, candidate)