Verifying interface implementations¶
The zope.interface.verify
module provides functions that test whether a
given interface is implemented by a class or provided by an object, resp.
Verifying classes¶
This is covered by unit tests defined in zope.interface.tests.test_verify
.
Verifying objects¶
An object provides an interface if
- either its class declares that it implements the interfaces, or the object declares that it directly provides the interface
- the object defines all the methods required by the interface
- all the methods have the correct signature
- the object defines all non-method attributes required by the interface
This doctest currently covers only the latter item.
Testing for attributes¶
Attributes of the object, be they defined by its class or added by its
__init__
method, will be recognized:
>>> from zope.interface import Interface, Attribute, implements
>>> from zope.interface.exceptions import BrokenImplementation
>>> class IFoo(Interface):
... x = Attribute("The X attribute")
... y = Attribute("The Y attribute")
>>> class Foo(object):
... implements(IFoo)
... x = 1
... def __init__(self):
... self.y = 2
>>> from zope.interface.verify import verifyObject
>>> verifyObject(IFoo, Foo())
True
If either attribute is missing, verification will fail:
>>> class Foo(object):
... implements(IFoo)
... x = 1
>>> try:
... verifyObject(IFoo, Foo())
... except BrokenImplementation, e:
... print str(e)
An object has failed to implement interface <InterfaceClass ...IFoo>
The y attribute was not provided.
>>> class Foo(object):
... implements(IFoo)
... def __init__(self):
... self.y = 2
>>> try:
... verifyObject(IFoo, Foo())
... except BrokenImplementation, e:
... print str(e)
An object has failed to implement interface <InterfaceClass ...IFoo>
The x attribute was not provided.
If an attribute is implemented as a property that raises an AttributeError when trying to get its value, the attribute is considered missing:
>>> class IFoo(Interface):
... x = Attribute('The X attribute')
>>> class Foo(object):
... implements(IFoo)
... @property
... def x(self):
... raise AttributeError
>>> try:
... verifyObject(IFoo, Foo())
... except BrokenImplementation, e:
... print str(e)
An object has failed to implement interface <InterfaceClass ...IFoo>
The x attribute was not provided.
Any other exception raised by a property will propagate to the caller of
verifyObject
:
>>> class Foo(object):
... implements(IFoo)
... @property
... def x(self):
... raise Exception
>>> verifyObject(IFoo, Foo())
Traceback (most recent call last):
Exception
Traceback (most recent call last):
Exception
Of course, broken properties that are not required by the interface don’t do any harm:
>>> class Foo(object):
... implements(IFoo)
... x = 1
... @property
... def y(self):
... raise Exception
>>> verifyObject(IFoo, Foo())
True