From b557b32e63579c8f9d1eadedc01297cc2b7bb674 Mon Sep 17 00:00:00 2001 From: Jason Madden Date: Tue, 10 Mar 2020 14:17:28 -0500 Subject: [PATCH] Fix doctest by making sure the default type repr can be used. --- src/zope/interface/interface.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/zope/interface/interface.py b/src/zope/interface/interface.py index 0d2c8a33..ba6bf15f 100644 --- a/src/zope/interface/interface.py +++ b/src/zope/interface/interface.py @@ -20,6 +20,7 @@ import weakref from zope.interface._compat import _use_c_impl +from zope.interface._compat import PYTHON3 as PY3 from zope.interface.exceptions import Invalid from zope.interface.ro import ro @@ -414,8 +415,18 @@ def get(self, name, default=None): return default if attr is None else attr -class _ModuleDescriptor(object): +class _ModuleDescriptor(str): + # type.__repr__ accesses self.__dict__['__module__'] + # and checks to see if it's a native string. If it's not, + # the repr just uses the __name__. So for things to work out nicely + # it's best for us to subclass str. + if PY3: + # Python 2 doesn't allow non-empty __slots__ for str + # subclasses. + __slots__ = ('_saved',) + def __init__(self, saved): + str.__init__(self) self._saved = saved def __get__(self, inst, kind): @@ -426,6 +437,9 @@ def __get__(self, inst, kind): def __set__(self, inst, val): inst.__ibmodule__ = val + def __str__(self): + return self._saved + # The simple act of having *any* metaclass besides type # makes our __module__ shenanigans work. Doing this at the class level, # and manually copying it around doesn't work. @@ -437,7 +451,7 @@ def __new__(cls, name, bases, attrs): _InterfaceClassBase = _MC( 'InterfaceClass', (Element, InterfaceBase, Specification), - {'__module__': __name__}) + {'__module__': __name__, '__qualname__': __name__ + 'InterfaceClass'}) class InterfaceClass(_InterfaceClassBase):