Skip to content

Commit

Permalink
Merge pull request #234 from zopefoundation/issue229-take2
Browse files Browse the repository at this point in the history
Update documentation and Provides repr for better debugging.
  • Loading branch information
jamadden committed Mar 18, 2021
2 parents cfe4075 + f46bc4f commit 5db4d7c
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGES.rst
Expand Up @@ -5,6 +5,10 @@
5.3.0 (unreleased)
==================

- Improve the repr of ``zope.interface.Provides`` to remove ambiguity
about what is being provided. This is especially helpful diagnosing
IRO issues.

- Allow subclasses of ``BaseAdapterRegistry`` (including
``AdapterRegistry`` and ``VerifyingAdapterRegistry``) to have
control over the data structures. This allows persistent
Expand Down
3 changes: 2 additions & 1 deletion src/zope/interface/declarations.py
Expand Up @@ -763,10 +763,11 @@ def __init__(self, cls, *interfaces):
Declaration.__init__(self, *self._add_interfaces_to_cls(interfaces, cls))

def __repr__(self):
return "<%s.%s for %s>" % (
return "<%s.%s for instances of %s providing %s>" % (
self.__class__.__module__,
self.__class__.__name__,
self._cls,
self.__args[1:],
)

def __reduce__(self):
Expand Down
23 changes: 23 additions & 0 deletions src/zope/interface/ro.py
Expand Up @@ -45,6 +45,10 @@
If this is set to "1", any attempt to use :func:`ro` that would produce a non-C3
ordering will fail by raising :class:`InconsistentResolutionOrderError`.
.. important::
``ZOPE_INTERFACE_STRICT_IRO`` is intended to become the default in the future.
There are two environment variables that are independent.
ZOPE_INTERFACE_LOG_CHANGED_IRO
Expand All @@ -56,6 +60,25 @@
legacy IRO will be used instead. This is a temporary measure and will be removed in the
future. It is intended to help during the transition.
It implies ``ZOPE_INTERFACE_LOG_CHANGED_IRO``.
.. rubric:: Debugging Behaviour Changes in zope.interface 5
Most behaviour changes from zope.interface 4 to 5 are related to
inconsistent resolution orders. ``ZOPE_INTERFACE_STRICT_IRO`` is the
most effective tool to find such inconsistent resolution orders, and
we recommend running your code with this variable set if at all
possible. Doing so will ensure that all interface resolution orders
are consistent, and if they're not, will immediately point the way to
where this is violated.
Occasionally, however, this may not be enough. This is because in some
cases, a C3 ordering can be found (the resolution order is fully
consistent) that is substantially different from the ad-hoc legacy
ordering. In such cases, you may find that you get an unexpected value
returned when adapting one or more objects to an interface. To debug
this, *also* enable ``ZOPE_INTERFACE_LOG_CHANGED_IRO`` and examine the
output. The main thing to look for is changes in the relative
positions of interfaces for which there are registered adapters.
"""
from __future__ import print_function
__docformat__ = 'restructuredtext'
Expand Down
16 changes: 14 additions & 2 deletions src/zope/interface/tests/test_declarations.py
Expand Up @@ -1305,10 +1305,22 @@ def _test():
self.assertRaises(AttributeError, _test)

def test__repr__(self):
inst = self._makeOne(type(self))
from zope.interface.interface import InterfaceClass
IFoo = InterfaceClass("IFoo")
assert IFoo.__name__ == 'IFoo'
assert IFoo.__module__ == __name__
assert repr(IFoo) == '<InterfaceClass %s.IFoo>' % (__name__,)

IBar = InterfaceClass("IBar")

inst = self._makeOne(type(self), IFoo, IBar)
self.assertEqual(
repr(inst),
"<zope.interface.Provides for %r>" % type(self)
"<zope.interface.Provides "
"for instances of <class '%(mod)s.ProvidesClassTests'> "
"providing (<InterfaceClass %(mod)s.IFoo>, <InterfaceClass %(mod)s.IBar>)>" % {
'mod': __name__,
}
)


Expand Down

0 comments on commit 5db4d7c

Please sign in to comment.