summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Madden <jamadden@gmail.com>2021-03-17 10:01:49 -0500
committerJason Madden <jamadden@gmail.com>2021-03-17 10:01:49 -0500
commit9967fcc5ac3c84abbac3de8b9778efd5870b2314 (patch)
tree708ff351ab97bc92d50cda8d4503ad9a593633ee
parentdd69666aae99afe0d47b3af81149fbd7e97f59fe (diff)
downloadzope-interface-issue229-take2.tar.gz
Update documentation and Provides repr for better debugging.issue229-take2
Fixes #229. Replaces #232
-rw-r--r--CHANGES.rst4
-rw-r--r--src/zope/interface/declarations.py3
-rw-r--r--src/zope/interface/ro.py23
-rw-r--r--src/zope/interface/tests/test_declarations.py11
4 files changed, 37 insertions, 4 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index ff3254c..e4a7ed3 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -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
diff --git a/src/zope/interface/declarations.py b/src/zope/interface/declarations.py
index 9a0146c..e6efbae 100644
--- a/src/zope/interface/declarations.py
+++ b/src/zope/interface/declarations.py
@@ -750,10 +750,11 @@ class Provides(Declaration): # Really named ProvidesClass
Declaration.__init__(self, *(interfaces + (implementedBy(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):
diff --git a/src/zope/interface/ro.py b/src/zope/interface/ro.py
index 20338ed..89dde67 100644
--- a/src/zope/interface/ro.py
+++ b/src/zope/interface/ro.py
@@ -45,6 +45,10 @@ ZOPE_INTERFACE_STRICT_IRO
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
@@ -56,6 +60,25 @@ ZOPE_INTERFACE_USE_LEGACY_IRO
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'
diff --git a/src/zope/interface/tests/test_declarations.py b/src/zope/interface/tests/test_declarations.py
index 9ef192a..a52274a 100644
--- a/src/zope/interface/tests/test_declarations.py
+++ b/src/zope/interface/tests/test_declarations.py
@@ -1305,13 +1305,18 @@ class ProvidesClassTests(unittest.TestCase):
self.assertRaises(AttributeError, _test)
def test__repr__(self):
- inst = self._makeOne(type(self))
+ from zope.interface.interface import InterfaceClass
+ IFoo = InterfaceClass("IFoo")
+
+ inst = self._makeOne(type(self), IFoo)
self.assertEqual(
repr(inst),
- "<zope.interface.Provides for %r>" % type(self)
+ "<zope.interface.Provides for instances of %r providing %s>" % (
+ type(self),
+ (IFoo,)
+ )
)
-
class Test_Provides(unittest.TestCase):
def _callFUT(self, *args, **kw):