Add warning to change note about string changes breaking doctests.
Also tweak documentation to DRY for verifyObject/verifyClass.
This commit is contained in:
parent
e8a4da9d5e
commit
83f4f55699
|
@ -100,11 +100,13 @@
|
|||
and ``Method``. These contain the name of the defining interface
|
||||
and the attribute. For methods, it also includes the signature.
|
||||
|
||||
- Change the error strings returned by ``verifyObject`` and
|
||||
- Change the error strings raised by ``verifyObject`` and
|
||||
``verifyClass``. They now include more human-readable information
|
||||
and exclude extraneous lines and spaces. See `issue 170
|
||||
<https://github.com/zopefoundation/zope.interface/issues/170>`_.
|
||||
|
||||
.. caution:: This will break consumers (such as doctests) that
|
||||
depended on the exact error messages.
|
||||
|
||||
4.7.1 (2019-11-11)
|
||||
==================
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
Interfaces
|
||||
==========
|
||||
|
||||
.. currentmodule:: zope.interface
|
||||
|
||||
Interfaces are objects that specify (document) the external behavior
|
||||
of objects that "provide" them. An interface specifies behavior
|
||||
through:
|
||||
|
@ -296,6 +298,7 @@ be used for classes, but in 3.6.0 and higher it can:
|
|||
Note that class decorators using the ``@implementer(IFoo)`` syntax are only
|
||||
supported in Python 2.6 and later.
|
||||
|
||||
.. autofunction:: implementer
|
||||
|
||||
Declaring provided interfaces
|
||||
-----------------------------
|
||||
|
@ -412,6 +415,8 @@ We can find out what interfaces are directly provided by an object:
|
|||
>>> list(zope.interface.directlyProvidedBy(newfoo))
|
||||
[]
|
||||
|
||||
.. autofunction:: provider
|
||||
|
||||
Inherited declarations
|
||||
----------------------
|
||||
|
||||
|
@ -466,6 +471,8 @@ be used for this purpose:
|
|||
>>> list(zope.interface.implementedBy(C))
|
||||
[<InterfaceClass builtins.IFoo>]
|
||||
|
||||
.. autofunction:: classImplements
|
||||
|
||||
We can use ``classImplementsOnly`` to exclude inherited interfaces:
|
||||
|
||||
.. doctest::
|
||||
|
@ -477,6 +484,7 @@ We can use ``classImplementsOnly`` to exclude inherited interfaces:
|
|||
>>> list(zope.interface.implementedBy(C))
|
||||
[<InterfaceClass builtins.ISpecial>]
|
||||
|
||||
.. autofunction:: classImplementsOnly
|
||||
|
||||
|
||||
Declaration Objects
|
||||
|
@ -791,7 +799,7 @@ exceptions as its argument:
|
|||
... except Invalid as e:
|
||||
... str(e)
|
||||
'[RangeError(Range(2, 1))]'
|
||||
|
||||
|
||||
And the list will be filled with the individual exceptions:
|
||||
|
||||
.. doctest::
|
||||
|
|
|
@ -3,30 +3,16 @@
|
|||
=====================================
|
||||
|
||||
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``.
|
||||
given interface is implemented by a class or provided by an object.
|
||||
|
||||
.. currentmodule:: zope.interface.verify
|
||||
|
||||
Verifying objects
|
||||
=================
|
||||
|
||||
An object provides an interface if
|
||||
.. autofunction:: verifyObject
|
||||
|
||||
- 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.
|
||||
.. autoexception:: zope.interface.Invalid
|
||||
|
||||
Testing for attributes
|
||||
----------------------
|
||||
|
@ -208,3 +194,25 @@ variable keyword arguments, the implementation must also accept them.
|
|||
... def needs_varargs(self, **kwargs): pass
|
||||
>>> verify_foo()
|
||||
The object <Foo...> violates its contract in IFoo.needs_varargs(*args): implementation doesn't support variable arguments.
|
||||
|
||||
Verifying Classes
|
||||
=================
|
||||
|
||||
The function `verifyClass` is used to check that a class implements
|
||||
an interface properly, meaning that its instances properly provide the
|
||||
interface. Most of the same things that `verifyObject` checks can be
|
||||
checked for classes.
|
||||
|
||||
.. autofunction:: verifyClass
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> from zope.interface.verify import verifyClass
|
||||
>>> def verify_foo_class():
|
||||
... try:
|
||||
... return verifyClass(IFoo, Foo)
|
||||
... except BrokenMethodImplementation as e:
|
||||
... print(e)
|
||||
|
||||
>>> verify_foo_class()
|
||||
The object <class 'Foo'> violates its contract in IFoo.needs_varargs(*args): implementation doesn't support variable arguments.
|
||||
|
|
|
@ -580,6 +580,10 @@ class IInterfaceDeclaration(Interface):
|
|||
|
||||
Instances of ``C`` implement ``I1``, ``I2``, and whatever interfaces
|
||||
instances of ``A`` and ``B`` implement.
|
||||
|
||||
.. deprecated:: 5.0
|
||||
This only works for Python 2. The `implementer` decorator
|
||||
is preferred for all versions.
|
||||
"""
|
||||
|
||||
def implementsOnly(*interfaces):
|
||||
|
@ -612,6 +616,10 @@ class IInterfaceDeclaration(Interface):
|
|||
|
||||
Instances of ``C`` implement ``I1``, ``I2``, regardless of what
|
||||
instances of ``A`` and ``B`` implement.
|
||||
|
||||
.. deprecated:: 5.0
|
||||
This only works for Python 2. The `implementer_only` decorator
|
||||
is preferred for all versions.
|
||||
"""
|
||||
|
||||
def classProvides(*interfaces):
|
||||
|
@ -642,7 +650,12 @@ class IInterfaceDeclaration(Interface):
|
|||
directlyProvides(theclass, I1)
|
||||
|
||||
after the class has been created.
|
||||
|
||||
.. deprecated:: 5.0
|
||||
This only works for Python 2. The `provider` decorator
|
||||
is preferred for all versions.
|
||||
"""
|
||||
|
||||
def provider(*interfaces):
|
||||
"""A class decorator version of `classProvides`"""
|
||||
|
||||
|
|
|
@ -36,20 +36,27 @@ MethodTypes = (MethodType, )
|
|||
|
||||
|
||||
def _verify(iface, candidate, tentative=False, vtype=None):
|
||||
"""Verify that *candidate* might correctly implement *iface*.
|
||||
"""
|
||||
Verify that *candidate* might correctly provide *iface*.
|
||||
|
||||
This involves:
|
||||
|
||||
- Making sure the candidate defines all the necessary methods
|
||||
- Making sure the candidate claims that it provides the
|
||||
interface using ``iface.providedBy`` (unless *tentative* is `True`,
|
||||
in which case this step is skipped). This means that the candidate's class
|
||||
declares that it `implements <zope.interface.implementer>` the interface,
|
||||
or the candidate itself declares that it `provides <zope.interface.provider>`
|
||||
the interface
|
||||
|
||||
- Making sure the methods have the correct signature
|
||||
- Making sure the candidate defines all the necessary methods
|
||||
|
||||
- Making sure the candidate asserts that it implements the interface
|
||||
- Making sure the methods have the correct signature (to the
|
||||
extent possible)
|
||||
|
||||
Note that this isn't the same as verifying that the class does
|
||||
implement the interface.
|
||||
- Making sure the candidate defines all the necessary attributes
|
||||
|
||||
If *tentative* is true (not the default), suppress the "is implemented by" test.
|
||||
:raises zope.interface.Invalid: If any of the previous
|
||||
conditions does not hold.
|
||||
"""
|
||||
|
||||
if vtype == 'c':
|
||||
|
@ -126,11 +133,15 @@ def _verify(iface, candidate, tentative=False, vtype=None):
|
|||
return True
|
||||
|
||||
def verifyClass(iface, candidate, tentative=False):
|
||||
"""
|
||||
Verify that the *candidate* might correctly provide *iface*.
|
||||
"""
|
||||
return _verify(iface, candidate, tentative, vtype='c')
|
||||
|
||||
def verifyObject(iface, candidate, tentative=False):
|
||||
return _verify(iface, candidate, tentative, vtype='o')
|
||||
|
||||
verifyObject.__doc__ = _verify.__doc__
|
||||
|
||||
_MSG_TOO_MANY = 'implementation requires too many arguments'
|
||||
_KNOWN_PYPY2_FALSE_POSITIVES = frozenset((
|
||||
|
|
Loading…
Reference in New Issue