jensens: Is it possible that this break existing doctests? 
jamadden: > Is it possible that this break existing doctests?

Absolutely. But doctests are inherently fragile anyway and break all the time.
diff --git a/CHANGES.rst b/CHANGES.rst
index efb7b88..b484a99 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -96,6 +96,18 @@
   verify as ``IFullMapping``, ``ISequence`` and ``IReadSequence,``
   respectively on all versions of Python.
 
+- Add human-readable ``__str___`` and ``__repr___`` to ``Attribute``
+  and ``Method``. These contain the name of the defining interface
+  and the attribute. For methods, it also includes the signature.
+
+- 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)
 ==================
 
diff --git a/docs/README.rst b/docs/README.rst
index 4e83c4a..d1e58cf 100644
--- a/docs/README.rst
+++ b/docs/README.rst
@@ -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::
diff --git a/docs/verify.rst b/docs/verify.rst
index 4d5191e..6f48218 100644
--- a/docs/verify.rst
+++ b/docs/verify.rst
@@ -1,32 +1,18 @@
-===================================
-Verifying interface implementations
-===================================
+=====================================
+ 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``.
+given interface is implemented by a class or provided by an object.
 
+.. currentmodule:: zope.interface.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.
+.. autofunction:: verifyObject
 
-This doctest currently covers only the latter item.
+.. autoexception:: zope.interface.Invalid
 
 Testing for attributes
 ----------------------
@@ -52,33 +38,30 @@ Attributes of the object, be they defined by its class or added by its
    >>> verifyObject(IFoo, Foo())
    True
 
-If either attribute is missing, verification will fail:
+If either attribute is missing, verification will fail by raising an
+exception. (We'll define a helper to make this easier to show.)
 
 .. doctest::
 
+   >>> def verify_foo():
+   ...    foo = Foo()
+   ...    try:
+   ...        return verifyObject(IFoo, foo)
+   ...    except BrokenImplementation as e:
+   ...        print(e)
+
    >>> @implementer(IFoo)
    ... class Foo(object):
    ...     x = 1
-   >>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
-   ...     verifyObject(IFoo, Foo())
-   ... except BrokenImplementation as e:
-   ...     print(e)
-   An object has failed to implement interface <InterfaceClass ...IFoo>
-   <BLANKLINE>
-           The y attribute was not provided.
-   <BLANKLINE>
+   >>> verify_foo()
+   The object <Foo...> has failed to implement interface <InterfaceClass ...IFoo>: The IFoo.y attribute was not provided.
    >>> @implementer(IFoo)
    ... class Foo(object):
    ...     def __init__(self):
    ...         self.y = 2
-   >>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
-   ...     verifyObject(IFoo, Foo())
-   ... except BrokenImplementation as e:
-   ...     print(e)
-   An object has failed to implement interface <InterfaceClass ...IFoo>
-   <BLANKLINE>
-           The x attribute was not provided.
-   <BLANKLINE>
+   >>> verify_foo()
+   The object <Foo...> has failed to implement interface <InterfaceClass ...IFoo>: The IFoo.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:
@@ -92,14 +75,9 @@ when trying to get its value, the attribute is considered missing:
    ...     @property
    ...     def x(self):
    ...         raise AttributeError
-   >>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
-   ...     verifyObject(IFoo, Foo())
-   ... except BrokenImplementation as e:
-   ...     print(e)
-   An object has failed to implement interface <InterfaceClass ...IFoo>
-   <BLANKLINE>
-           The x attribute was not provided.
-   <BLANKLINE>
+   >>> verify_foo()
+   The object <Foo...> has failed to implement interface <InterfaceClass ...IFoo>: The IFoo.x attribute was not provided.
+
 
 Any other exception raised by a property will propagate to the caller of
 ``verifyObject``:
@@ -111,7 +89,7 @@ Any other exception raised by a property will propagate to the caller of
    ...     @property
    ...     def x(self):
    ...         raise Exception
-   >>> verifyObject(IFoo, Foo())
+   >>> verify_foo()
    Traceback (most recent call last):
    Exception
 
@@ -126,5 +104,115 @@ any harm:
    ...     @property
    ...     def y(self):
    ...         raise Exception
-   >>> verifyObject(IFoo, Foo())
+   >>> verify_foo()
    True
+
+
+Testing For Methods
+-------------------
+
+Methods are also validated to exist. We'll start by defining a method
+that takes one argument. If we don't provide it, we get an error.
+
+.. doctest::
+
+   >>> class IFoo(Interface):
+   ...    def simple(arg1): "Takes one positional argument"
+   >>> @implementer(IFoo)
+   ... class Foo(object):
+   ...    pass
+   >>> verify_foo()
+   The object <Foo...> has failed to implement interface <InterfaceClass builtins.IFoo>: The IFoo.simple(arg1) attribute was not provided.
+
+Once they exist, they are checked for compatible signatures. This is a
+different type of exception, so we need an updated helper.
+
+.. doctest::
+
+   >>> from zope.interface.exceptions import BrokenMethodImplementation
+   >>> def verify_foo():
+   ...    foo = Foo()
+   ...    try:
+   ...        return verifyObject(IFoo, foo)
+   ...    except BrokenMethodImplementation as e:
+   ...        print(e)
+
+Not being callable is an error.
+
+.. doctest::
+
+   >>> Foo.simple = 42
+   >>> verify_foo()
+   The object <Foo...> violates its contract in IFoo.simple(arg1): implementation is not a method.
+
+Taking too few arguments is an error.
+
+.. doctest::
+
+   >>> Foo.simple = lambda: "I take no arguments"
+   >>> verify_foo()
+   The object <Foo...> violates its contract in IFoo.simple(arg1): implementation doesn't allow enough arguments.
+
+Requiring too many arguments is an error. (Recall that the ``self``
+argument is implicit.)
+
+.. doctest::
+
+   >>> Foo.simple = lambda self, a, b: "I require two arguments"
+   >>> verify_foo()
+   The object <Foo...> violates its contract in IFoo.simple(arg1): implementation requires too many arguments.
+
+Variable arguments can be used to implement the required number, as
+can arguments with defaults.
+
+.. doctest::
+
+   >>> Foo.simple = lambda self, *args: "Varargs work."
+   >>> verify_foo()
+   True
+   >>> Foo.simple = lambda self, a=1, b=2: "Default args work."
+   >>> verify_foo()
+   True
+
+If our interface defines a method that uses variable positional or
+variable keyword arguments, the implementation must also accept them.
+
+.. doctest::
+
+   >>> class IFoo(Interface):
+   ...    def needs_kwargs(**kwargs): pass
+   >>> @implementer(IFoo)
+   ... class Foo(object):
+   ...     def needs_kwargs(self, a=1, b=2): pass
+   >>> verify_foo()
+   The object <Foo...> violates its contract in IFoo.needs_kwargs(**kwargs): implementation doesn't support keyword arguments.
+
+   >>> class IFoo(Interface):
+   ...    def needs_varargs(*args): pass
+   >>> @implementer(IFoo)
+   ... class Foo(object):
+   ...     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.
diff --git a/src/zope/interface/exceptions.py b/src/zope/interface/exceptions.py
index 9be1b8c..8d21f33 100644
--- a/src/zope/interface/exceptions.py
+++ b/src/zope/interface/exceptions.py
@@ -29,42 +29,86 @@ class Invalid(Exception):
     """A specification is violated
     """
 
-class DoesNotImplement(Invalid):
-    """ This object does not implement """
-    def __init__(self, interface):
+_NotGiven = object()
+
+class _TargetMixin(object):
+    target = _NotGiven
+
+    @property
+    def _prefix(self):
+        if self.target is _NotGiven:
+            return "An object"
+        return "The object %r" % (self.target,)
+
+class DoesNotImplement(Invalid, _TargetMixin):
+    """
+    The *target* (optional) does not implement the *interface*.
+
+    .. versionchanged:: 5.0.0
+       Add the *target* argument and attribute, and change the resulting
+       string value of this object accordingly.
+    """
+
+    def __init__(self, interface, target=_NotGiven):
+        Invalid.__init__(self)
         self.interface = interface
+        self.target = target
 
     def __str__(self):
-        return """An object does not implement interface %(interface)s
+        return "%s does not implement the interface %s." % (
+            self._prefix,
+            self.interface
+        )
 
-        """ % self.__dict__
+class BrokenImplementation(Invalid, _TargetMixin):
+    """
+    The *target* (optional) is missing the attribute *name*.
+
+    .. versionchanged:: 5.0.0
+       Add the *target* argument and attribute, and change the resulting
+       string value of this object accordingly.
 
-class BrokenImplementation(Invalid):
-    """An attribute is not completely implemented.
+       The *name* can either be a simple string or a ``Attribute`` object.
     """
 
-    def __init__(self, interface, name):
-        self.interface=interface
-        self.name=name
+    def __init__(self, interface, name, target=_NotGiven):
+        Invalid.__init__(self)
+        self.interface = interface
+        self.name = name
+        self.target = target
 
     def __str__(self):
-        return """An object has failed to implement interface %(interface)s
+        return "%s has failed to implement interface %s: The %s attribute was not provided." % (
+            self._prefix,
+            self.interface,
+            repr(self.name) if isinstance(self.name, str) else self.name
+        )
 
-        The %(name)s attribute was not provided.
-        """ % self.__dict__
+class BrokenMethodImplementation(Invalid, _TargetMixin):
+    """
+    The *target* (optional) has a *method* that violates
+    its contract in a way described by *mess*.
+
+    .. versionchanged:: 5.0.0
+       Add the *target* argument and attribute, and change the resulting
+       string value of this object accordingly.
 
-class BrokenMethodImplementation(Invalid):
-    """An method is not completely implemented.
+       The *method* can either be a simple string or a ``Method`` object.
     """
 
-    def __init__(self, method, mess):
-        self.method=method
-        self.mess=mess
+    def __init__(self, method, mess, target=_NotGiven):
+        Invalid.__init__(self)
+        self.method = method
+        self.mess = mess
+        self.target = target
 
     def __str__(self):
-        return """The implementation of %(method)s violates its contract
-        because %(mess)s.
-        """ % self.__dict__
+        return "%s violates its contract in %s: %s." % (
+            self._prefix,
+            repr(self.method) if isinstance(self.method, str) else self.method,
+            self.mess
+        )
+
 
 class InvalidInterface(Exception):
     """The interface has invalid contents
diff --git a/src/zope/interface/interface.py b/src/zope/interface/interface.py
index b5d0e92..4ed447a 100644
--- a/src/zope/interface/interface.py
+++ b/src/zope/interface/interface.py
@@ -642,6 +642,22 @@ class Attribute(Element):
 
     interface = None
 
+    def _get_str_info(self):
+        """Return extra data to put at the end of __str__."""
+        return ""
+
+    def __str__(self):
+        of = self.interface.__name__ + '.' if self.interface else ''
+        return of + self.__name__ + self._get_str_info()
+
+    def __repr__(self):
+        return "<%s.%s at 0x%x %s>" % (
+            type(self).__module__,
+            type(self).__name__,
+            id(self),
+            self
+        )
+
 
 class Method(Attribute):
     """Method interfaces
@@ -691,6 +707,8 @@ class Method(Attribute):
 
         return "(%s)" % ", ".join(sig)
 
+    _get_str_info = getSignatureString
+
 
 def fromFunction(func, interface=None, imlevel=0, name=None):
     name = name or func.__name__
diff --git a/src/zope/interface/interfaces.py b/src/zope/interface/interfaces.py
index 6d98591..6ac235a 100644
--- a/src/zope/interface/interfaces.py
+++ b/src/zope/interface/interfaces.py
@@ -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`"""
 
diff --git a/src/zope/interface/verify.py b/src/zope/interface/verify.py
index 722bb4f..a8dd952 100644
--- a/src/zope/interface/verify.py
+++ b/src/zope/interface/verify.py
@@ -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':
@@ -61,7 +68,7 @@ def _verify(iface, candidate, tentative=False, vtype=None):
         raise DoesNotImplement(iface)
 
     # Here the `desc` is either an `Attribute` or `Method` instance
-    for name, desc in iface.namesAndDescriptions(1):
+    for name, desc in iface.namesAndDescriptions(all=True):
         try:
             attr = getattr(candidate, name)
         except AttributeError:
@@ -70,7 +77,7 @@ def _verify(iface, candidate, tentative=False, vtype=None):
                 # class may provide attrs in it's __init__.
                 continue
 
-            raise BrokenImplementation(iface, name)
+            raise BrokenImplementation(iface, desc, candidate)
 
         if not isinstance(desc, Method):
             # If it's not a method, there's nothing else we can test
@@ -110,30 +117,31 @@ def _verify(iface, candidate, tentative=False, vtype=None):
             continue
         else:
             if not callable(attr):
-                raise BrokenMethodImplementation(name, "Not a method")
+                raise BrokenMethodImplementation(desc, "implementation is not a method", candidate)
             # 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)
+        mess = _incompat(desc.getSignatureInfo(), meth.getSignatureInfo())
         if mess:
             if PYPY2 and _pypy2_false_positive(mess, candidate, vtype):
                 continue
-            raise BrokenMethodImplementation(name, mess)
+            raise BrokenMethodImplementation(desc, mess, candidate)
 
     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((

Strange indentation and newlines for Invalid exceptions
While looking at #118, I noticed that the error message produced is quite strangely formatted:

```
BrokenMethodImplementation: The implementation of pop violates its contract
        because implementation requires too many arguments.
```

This comes down to the use of a multi-line string literal in `__str__`: https://github.com/zopefoundation/zope.interface/blob/0048a56bac299db7c78a9c8e52c5928e4ec06f38/src/zope/interface/exceptions.py#L64-L67
diff --git a/src/zope/interface/tests/test_exceptions.py b/src/zope/interface/tests/test_exceptions.py
index ae73f9c..34ee071 100644
--- a/src/zope/interface/tests/test_exceptions.py
+++ b/src/zope/interface/tests/test_exceptions.py
@@ -27,16 +27,24 @@ class DoesNotImplementTests(unittest.TestCase):
         from zope.interface.exceptions import DoesNotImplement
         return DoesNotImplement
 
-    def _makeOne(self):
+    def _makeOne(self, *args):
         iface = _makeIface()
-        return self._getTargetClass()(iface)
+        return self._getTargetClass()(iface, *args)
 
     def test___str__(self):
         dni = self._makeOne()
-        # XXX The trailing newlines and blank spaces are a stupid artifact.
-        self.assertEqual(str(dni),
-            'An object does not implement interface <InterfaceClass '
-               'zope.interface.tests.test_exceptions.IDummy>\n\n        ')
+        self.assertEqual(
+            str(dni),
+            'An object does not implement the interface '
+            '<InterfaceClass zope.interface.tests.test_exceptions.IDummy>.')
+
+    def test___str__w_candidate(self):
+        dni = self._makeOne('candidate')
+        self.assertEqual(
+            str(dni),
+            'The object \'candidate\' does not implement the interface '
+            '<InterfaceClass zope.interface.tests.test_exceptions.IDummy>.')
+
 
 class BrokenImplementationTests(unittest.TestCase):
 
@@ -44,17 +52,25 @@ class BrokenImplementationTests(unittest.TestCase):
         from zope.interface.exceptions import BrokenImplementation
         return BrokenImplementation
 
-    def _makeOne(self, name='missing'):
+    def _makeOne(self, *args):
         iface = _makeIface()
-        return self._getTargetClass()(iface, name)
+        return self._getTargetClass()(iface, 'missing', *args)
 
     def test___str__(self):
         dni = self._makeOne()
-        # XXX The trailing newlines and blank spaces are a stupid artifact.
-        self.assertEqual(str(dni),
-            'An object has failed to implement interface <InterfaceClass '
-               'zope.interface.tests.test_exceptions.IDummy>\n\n'
-               '        The missing attribute was not provided.\n        ')
+        self.assertEqual(
+            str(dni),
+            'An object has failed to implement interface '
+            '<InterfaceClass zope.interface.tests.test_exceptions.IDummy>: '
+            "The 'missing' attribute was not provided.")
+
+    def test___str__w_candidate(self):
+        dni = self._makeOne('candidate')
+        self.assertEqual(
+            str(dni),
+            'The object \'candidate\' has failed to implement interface '
+            '<InterfaceClass zope.interface.tests.test_exceptions.IDummy>: '
+            "The 'missing' attribute was not provided.")
 
 class BrokenMethodImplementationTests(unittest.TestCase):
 
@@ -62,11 +78,17 @@ class BrokenMethodImplementationTests(unittest.TestCase):
         from zope.interface.exceptions import BrokenMethodImplementation
         return BrokenMethodImplementation
 
-    def _makeOne(self, method='aMethod', mess='I said so'):
-        return self._getTargetClass()(method, mess)
+    def _makeOne(self, *args):
+        return self._getTargetClass()('aMethod', 'I said so', *args)
 
     def test___str__(self):
         dni = self._makeOne()
-        self.assertEqual(str(dni),
-            'The implementation of aMethod violates its contract\n'
-             '        because I said so.\n        ')
+        self.assertEqual(
+            str(dni),
+            "An object violates its contract in 'aMethod': I said so.")
+
+    def test___str__w_candidate(self):
+        dni = self._makeOne('candidate')
+        self.assertEqual(
+            str(dni),
+            "The object 'candidate' violates its contract in 'aMethod': I said so.")
diff --git a/src/zope/interface/tests/test_interface.py b/src/zope/interface/tests/test_interface.py
index 3bf26dc..1ec5117 100644
--- a/src/zope/interface/tests/test_interface.py
+++ b/src/zope/interface/tests/test_interface.py
@@ -1857,6 +1857,30 @@ class AttributeTests(ElementTests):
         from zope.interface.interface import Attribute
         return Attribute
 
+    def test__repr__w_interface(self):
+        method = self._makeOne()
+        method.interface = type(self)
+        r = repr(method)
+        self.assertTrue(r.startswith('<zope.interface.interface.Attribute at'), r)
+        self.assertTrue(r.endswith(' AttributeTests.TestAttribute>'), r)
+
+    def test__repr__wo_interface(self):
+        method = self._makeOne()
+        r = repr(method)
+        self.assertTrue(r.startswith('<zope.interface.interface.Attribute at'), r)
+        self.assertTrue(r.endswith(' TestAttribute>'), r)
+
+    def test__str__w_interface(self):
+        method = self._makeOne()
+        method.interface = type(self)
+        r = str(method)
+        self.assertEqual(r, 'AttributeTests.TestAttribute')
+
+    def test__str__wo_interface(self):
+        method = self._makeOne()
+        r = str(method)
+        self.assertEqual(r, 'TestAttribute')
+
 
 class MethodTests(AttributeTests):
 
@@ -1919,6 +1943,34 @@ class MethodTests(AttributeTests):
         method.kwargs = 'kw'
         self.assertEqual(method.getSignatureString(), "(**kw)")
 
+    def test__repr__w_interface(self):
+        method = self._makeOne()
+        method.kwargs = 'kw'
+        method.interface = type(self)
+        r = repr(method)
+        self.assertTrue(r.startswith('<zope.interface.interface.Method at'), r)
+        self.assertTrue(r.endswith(' MethodTests.TestMethod(**kw)>'), r)
+
+    def test__repr__wo_interface(self):
+        method = self._makeOne()
+        method.kwargs = 'kw'
+        r = repr(method)
+        self.assertTrue(r.startswith('<zope.interface.interface.Method at'), r)
+        self.assertTrue(r.endswith(' TestMethod(**kw)>'), r)
+
+    def test__str__w_interface(self):
+        method = self._makeOne()
+        method.kwargs = 'kw'
+        method.interface = type(self)
+        r = str(method)
+        self.assertEqual(r, 'MethodTests.TestMethod(**kw)')
+
+    def test__str__wo_interface(self):
+        method = self._makeOne()
+        method.kwargs = 'kw'
+        r = str(method)
+        self.assertEqual(r, 'TestMethod(**kw)')
+
 
 class Test_fromFunction(unittest.TestCase):
 

pip install -e .[test]
parse_log_pytest
requirements.txt
pytest pytest-cov coverage zope.event
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
coverage==7.8.0
exceptiongroup==1.2.2
iniconfig==2.1.0
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
pytest-cov==6.0.0
tomli==2.2.1
zope.event==5.0
-e git+https://github.com/zopefoundation/zope.interface.git@cc537c613ba6dd1a076202e2144fdacfccc520d2#egg=zope.interface

name: zope.interface
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - coverage==7.8.0
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - pytest-cov==6.0.0
      - tomli==2.2.1
      - zope-event==5.0
prefix: /opt/conda/envs/zope.interface

src/zope/interface/tests/test_exceptions.py::DoesNotImplementTests::test___str__ src/zope/interface/tests/test_exceptions.py::DoesNotImplementTests::test___str__w_candidate src/zope/interface/tests/test_exceptions.py::BrokenImplementationTests::test___str__ src/zope/interface/tests/test_exceptions.py::BrokenImplementationTests::test___str__w_candidate src/zope/interface/tests/test_exceptions.py::BrokenMethodImplementationTests::test___str__ src/zope/interface/tests/test_exceptions.py::BrokenMethodImplementationTests::test___str__w_candidate src/zope/interface/tests/test_interface.py::AttributeTests::test__repr__w_interface src/zope/interface/tests/test_interface.py::AttributeTests::test__repr__wo_interface src/zope/interface/tests/test_interface.py::AttributeTests::test__str__w_interface src/zope/interface/tests/test_interface.py::AttributeTests::test__str__wo_interface src/zope/interface/tests/test_interface.py::MethodTests::test__repr__w_interface src/zope/interface/tests/test_interface.py::MethodTests::test__repr__wo_interface src/zope/interface/tests/test_interface.py::MethodTests::test__str__w_interface src/zope/interface/tests/test_interface.py::MethodTests::test__str__wo_interface
src/zope/interface/tests/test_interface.py::Test_invariant::test_w_multiple src/zope/interface/tests/test_interface.py::Test_invariant::test_w_single src/zope/interface/tests/test_interface.py::Test_taggedValue::test_w_multiple src/zope/interface/tests/test_interface.py::Test_taggedValue::test_w_multiple_overwriting src/zope/interface/tests/test_interface.py::Test_taggedValue::test_w_single src/zope/interface/tests/test_interface.py::ElementTests::test_ctor_defaults src/zope/interface/tests/test_interface.py::ElementTests::test_ctor_no_doc_space_in_name src/zope/interface/tests/test_interface.py::ElementTests::test_getTaggedValue_miss src/zope/interface/tests/test_interface.py::ElementTests::test_queryTaggedValue_miss src/zope/interface/tests/test_interface.py::ElementTests::test_queryTaggedValue_miss_w_default src/zope/interface/tests/test_interface.py::ElementTests::test_setTaggedValue src/zope/interface/tests/test_interface.py::GenericSpecificationBaseTests::test_implementedBy_miss src/zope/interface/tests/test_interface.py::GenericSpecificationBaseTests::test_providedBy_miss src/zope/interface/tests/test_interface.py::SpecificationBaseTests::test_implementedBy_miss src/zope/interface/tests/test_interface.py::SpecificationBaseTests::test_optimizations src/zope/interface/tests/test_interface.py::SpecificationBaseTests::test_providedBy_miss src/zope/interface/tests/test_interface.py::SpecificationBasePyTests::test___call___hit src/zope/interface/tests/test_interface.py::SpecificationBasePyTests::test___call___miss src/zope/interface/tests/test_interface.py::SpecificationBasePyTests::test_implementedBy_hit src/zope/interface/tests/test_interface.py::SpecificationBasePyTests::test_implementedBy_miss src/zope/interface/tests/test_interface.py::SpecificationBasePyTests::test_isOrExtends_hit src/zope/interface/tests/test_interface.py::SpecificationBasePyTests::test_isOrExtends_miss src/zope/interface/tests/test_interface.py::SpecificationBasePyTests::test_providedBy_hit src/zope/interface/tests/test_interface.py::SpecificationBasePyTests::test_providedBy_miss src/zope/interface/tests/test_interface.py::GenericInterfaceBaseTests::test___call___w___conform___ob_no_provides_wo_alternate src/zope/interface/tests/test_interface.py::GenericInterfaceBaseTests::test___call___w___conform___returning_value src/zope/interface/tests/test_interface.py::GenericInterfaceBaseTests::test___call___wo___conform___ob_no_provides_w_alternate src/zope/interface/tests/test_interface.py::InterfaceBaseTests::test___call___w___conform___ob_no_provides_wo_alternate src/zope/interface/tests/test_interface.py::InterfaceBaseTests::test___call___w___conform___returning_value src/zope/interface/tests/test_interface.py::InterfaceBaseTests::test___call___wo___conform___ob_no_provides_w_alternate src/zope/interface/tests/test_interface.py::InterfaceBaseTests::test_optimizations src/zope/interface/tests/test_interface.py::InterfaceBasePyTests::test___adapt___ob_no_provides_uses_hooks src/zope/interface/tests/test_interface.py::InterfaceBasePyTests::test___adapt___ob_provides src/zope/interface/tests/test_interface.py::InterfaceBasePyTests::test___call___w___conform___miss_ob_provides src/zope/interface/tests/test_interface.py::InterfaceBasePyTests::test___call___w___conform___ob_no_provides_wo_alternate src/zope/interface/tests/test_interface.py::InterfaceBasePyTests::test___call___w___conform___returning_value src/zope/interface/tests/test_interface.py::InterfaceBasePyTests::test___call___wo___conform___ob_no_provides_w_alternate src/zope/interface/tests/test_interface.py::SpecificationTests::test___setBases_subscribes_bases_and_notifies_dependents src/zope/interface/tests/test_interface.py::SpecificationTests::test_changed_clears_volatiles_and_implied src/zope/interface/tests/test_interface.py::SpecificationTests::test_ctor src/zope/interface/tests/test_interface.py::SpecificationTests::test_extends_non_strict_w_self src/zope/interface/tests/test_interface.py::SpecificationTests::test_extends_strict_w_self src/zope/interface/tests/test_interface.py::SpecificationTests::test_extends_strict_wo_self src/zope/interface/tests/test_interface.py::SpecificationTests::test_get_hit_from_base_wo__v_attrs src/zope/interface/tests/test_interface.py::SpecificationTests::test_get_hit_w__v_attrs src/zope/interface/tests/test_interface.py::SpecificationTests::test_interfaces_skips_already_seen src/zope/interface/tests/test_interface.py::SpecificationTests::test_subscribe_again src/zope/interface/tests/test_interface.py::SpecificationTests::test_subscribe_first_time src/zope/interface/tests/test_interface.py::SpecificationTests::test_unsubscribe src/zope/interface/tests/test_interface.py::SpecificationTests::test_unsubscribe_miss src/zope/interface/tests/test_interface.py::InterfaceClassTests::test___contains___hit src/zope/interface/tests/test_interface.py::InterfaceClassTests::test___contains___miss src/zope/interface/tests/test_interface.py::InterfaceClassTests::test___getitem___hit src/zope/interface/tests/test_interface.py::InterfaceClassTests::test___getitem___miss src/zope/interface/tests/test_interface.py::InterfaceClassTests::test___hash___missing_required_attrs src/zope/interface/tests/test_interface.py::InterfaceClassTests::test___hash___normal src/zope/interface/tests/test_interface.py::InterfaceClassTests::test___iter__ src/zope/interface/tests/test_interface.py::InterfaceClassTests::test___reduce__ src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_comparison_with_None src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_comparison_with_same_instance src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_comparison_with_same_named_instance_in_other_module src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_ctor_attrs_w___annotations__ src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_ctor_attrs_w___locals__ src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_ctor_attrs_w__decorator_non_return src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_ctor_attrs_w_invalid_attr_type src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_ctor_bad_bases src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_ctor_defaults src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_ctor_w_attrs_attrib_methods src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_ctor_w_explicit___doc__ src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_direct_hit_local_miss_bases src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_direct_miss src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_getBases src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_getDescriptionFor_hit src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_getDescriptionFor_miss src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_interfaces src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_isEqualOrExtendedBy_identity src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_isEqualOrExtendedBy_subiface src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_isEqualOrExtendedBy_unrelated src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_namesAndDescriptions_w_all_False_ignores_bases src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_namesAndDescriptions_w_all_True_bases_w_same_names src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_namesAndDescriptions_w_all_True_no_bases src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_namesAndDescriptions_w_all_True_simple src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_names_w_all_False_ignores_bases src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_names_w_all_True_bases_w_same_names src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_names_w_all_True_no_bases src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_names_w_all_True_w_bases_simple src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_queryDescriptionFor_hit src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_queryDescriptionFor_miss src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_validateInvariants_fail_in_base_w_errors_passed src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_validateInvariants_fail_in_base_wo_errors_passed src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_validateInvariants_fail_w_errors_passed src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_validateInvariants_fail_wo_errors_passed src/zope/interface/tests/test_interface.py::InterfaceClassTests::test_validateInvariants_pass src/zope/interface/tests/test_interface.py::InterfaceTests::testInterfaceExtendsInterface src/zope/interface/tests/test_interface.py::InterfaceTests::test___call___defers_to___conform___ src/zope/interface/tests/test_interface.py::InterfaceTests::test___call___miss_w_alternate src/zope/interface/tests/test_interface.py::InterfaceTests::test___call___miss_wo_alternate src/zope/interface/tests/test_interface.py::InterfaceTests::test___call___object_implements src/zope/interface/tests/test_interface.py::InterfaceTests::test___call___w_adapter_hook src/zope/interface/tests/test_interface.py::InterfaceTests::test___contains__derived src/zope/interface/tests/test_interface.py::InterfaceTests::test___contains__nonesuch src/zope/interface/tests/test_interface.py::InterfaceTests::test___contains__simple src/zope/interface/tests/test_interface.py::InterfaceTests::test___doc___as_element src/zope/interface/tests/test_interface.py::InterfaceTests::test___doc___element src/zope/interface/tests/test_interface.py::InterfaceTests::test___doc___non_element src/zope/interface/tests/test_interface.py::InterfaceTests::test___getitem___derived src/zope/interface/tests/test_interface.py::InterfaceTests::test___getitem__nonesuch src/zope/interface/tests/test_interface.py::InterfaceTests::test___getitem__simple src/zope/interface/tests/test_interface.py::InterfaceTests::test___iter__derived src/zope/interface/tests/test_interface.py::InterfaceTests::test___iter__empty src/zope/interface/tests/test_interface.py::InterfaceTests::test___iter__simple src/zope/interface/tests/test_interface.py::InterfaceTests::test_attributes_link_to_interface src/zope/interface/tests/test_interface.py::InterfaceTests::test_classImplements_base_and_derived src/zope/interface/tests/test_interface.py::InterfaceTests::test_classImplements_base_not_derived src/zope/interface/tests/test_interface.py::InterfaceTests::test_classImplements_multiple src/zope/interface/tests/test_interface.py::InterfaceTests::test_classImplements_multiple_w_explict_implements src/zope/interface/tests/test_interface.py::InterfaceTests::test_classImplements_simple src/zope/interface/tests/test_interface.py::InterfaceTests::test_description_cache_management src/zope/interface/tests/test_interface.py::InterfaceTests::test_function_attributes_become_tagged_values src/zope/interface/tests/test_interface.py::InterfaceTests::test_getDescriptionFor_derived src/zope/interface/tests/test_interface.py::InterfaceTests::test_getDescriptionFor_nonesuch_no_default src/zope/interface/tests/test_interface.py::InterfaceTests::test_getDescriptionFor_simple src/zope/interface/tests/test_interface.py::InterfaceTests::test_interface_object_provides_Interface src/zope/interface/tests/test_interface.py::InterfaceTests::test_invariant_as_decorator src/zope/interface/tests/test_interface.py::InterfaceTests::test_invariant_mutandis src/zope/interface/tests/test_interface.py::InterfaceTests::test_invariant_nested src/zope/interface/tests/test_interface.py::InterfaceTests::test_invariant_simple src/zope/interface/tests/test_interface.py::InterfaceTests::test_methods_link_to_interface src/zope/interface/tests/test_interface.py::InterfaceTests::test_namesAndDescriptions_derived src/zope/interface/tests/test_interface.py::InterfaceTests::test_namesAndDescriptions_simple src/zope/interface/tests/test_interface.py::InterfaceTests::test_names_derived src/zope/interface/tests/test_interface.py::InterfaceTests::test_names_simple src/zope/interface/tests/test_interface.py::InterfaceTests::test_taggedValue src/zope/interface/tests/test_interface.py::InterfaceTests::test_verifyClass src/zope/interface/tests/test_interface.py::InterfaceTests::test_verifyObject src/zope/interface/tests/test_interface.py::AttributeTests::test_ctor_defaults src/zope/interface/tests/test_interface.py::AttributeTests::test_ctor_no_doc_space_in_name src/zope/interface/tests/test_interface.py::AttributeTests::test_getTaggedValue_miss src/zope/interface/tests/test_interface.py::AttributeTests::test_queryTaggedValue_miss src/zope/interface/tests/test_interface.py::AttributeTests::test_queryTaggedValue_miss_w_default src/zope/interface/tests/test_interface.py::AttributeTests::test_setTaggedValue src/zope/interface/tests/test_interface.py::MethodTests::test___call___raises_BrokenImplementation src/zope/interface/tests/test_interface.py::MethodTests::test_ctor_defaults src/zope/interface/tests/test_interface.py::MethodTests::test_ctor_no_doc_space_in_name src/zope/interface/tests/test_interface.py::MethodTests::test_getSignatureInfo_bare src/zope/interface/tests/test_interface.py::MethodTests::test_getSignatureString_bare src/zope/interface/tests/test_interface.py::MethodTests::test_getSignatureString_w_kwargs src/zope/interface/tests/test_interface.py::MethodTests::test_getSignatureString_w_only_required src/zope/interface/tests/test_interface.py::MethodTests::test_getSignatureString_w_optional src/zope/interface/tests/test_interface.py::MethodTests::test_getSignatureString_w_varargs src/zope/interface/tests/test_interface.py::MethodTests::test_getTaggedValue_miss src/zope/interface/tests/test_interface.py::MethodTests::test_optional_as_property src/zope/interface/tests/test_interface.py::MethodTests::test_queryTaggedValue_miss src/zope/interface/tests/test_interface.py::MethodTests::test_queryTaggedValue_miss_w_default src/zope/interface/tests/test_interface.py::MethodTests::test_setTaggedValue src/zope/interface/tests/test_interface.py::Test_fromFunction::test_bare src/zope/interface/tests/test_interface.py::Test_fromFunction::test_full_spectrum src/zope/interface/tests/test_interface.py::Test_fromFunction::test_w_interface src/zope/interface/tests/test_interface.py::Test_fromFunction::test_w_kwargs src/zope/interface/tests/test_interface.py::Test_fromFunction::test_w_name src/zope/interface/tests/test_interface.py::Test_fromFunction::test_w_only_required src/zope/interface/tests/test_interface.py::Test_fromFunction::test_w_optional src/zope/interface/tests/test_interface.py::Test_fromFunction::test_w_optional_self src/zope/interface/tests/test_interface.py::Test_fromFunction::test_w_varargs src/zope/interface/tests/test_interface.py::Test_fromMethod::test_full_spectrum src/zope/interface/tests/test_interface.py::Test_fromMethod::test_no_args src/zope/interface/tests/test_interface.py::Test_fromMethod::test_w_non_method
src/zope/interface/exceptions.py src/zope/interface/interface.py docs/README.rst src/zope/interface/verify.py CHANGES.rst docs/verify.rst src/zope/interface/interfaces.py
src/zope/interface/exceptions.py src/zope/interface/interface.py docs/README.rst src/zope/interface/verify.py CHANGES.rst docs/verify.rst src/zope/interface/interfaces.py