[Interface-dev] subclasses of classes which implement interfaces
are not documented by pydoc
glyph at divmod.com
glyph at divmod.com
Sat Sep 30 01:18:01 EDT 2006
I noticed this issue has come up on the zope3 list recently as well.
Twisted uses pydoctor for generating documentation, and I know that Zope uses APIDoc, so I understand that this is not a particularly high priority issue. I can also see that pydoc's implementation is... questionable, at best, due to the way it semi-randomly throws away any error information.
However, I tracked down the problem a bit, so perhaps these investigations will serve useful:
The problem, as described in the topic, can be expressed by this code:
# dontdocme.py
from zope.interface import Interface, implements
class IDestroyDocs(Interface):
"""
I am a random interface.
"""
class A:
"""
I implement a thing.
"""
implements(IDestroyDocs)
class B(A):
"""
Voila: I have no documentation.
"""
# Without the following line, this class will not work with pydoc:
# implements(IDestroyDocs)
"help(B)" at an interactive interpreter or "pydoc dontdocme.B" at a commandline will not show any information about B.
If you look down in the guts of pydoc for what's happening, it's due to the fact that attributes of A aren't showing up on B. I think that in reality this is a bug in pydoc, but it seems that it might break other code.
>>> pydoc.text.docclass(dontdocme.B)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "C:\Python24\lib\pydoc.py", line 1170, in docclass
inspect.classify_class_attrs(object))
File "C:\Python24\lib\inspect.py", line 211, in classify_class_attrs
obj = getattr(cls, name)
AttributeError: __provides__
Pydoc then erroneously catches AttributeError from this code and falls back to a simplistic str() based approach. Really this is a special case of the following:
>>> dontdocme.A.__provides__.__get__(None, dontdocme.A)
<zope.interface.declarations.ClassProvides object at 0x00AFCFD0>
>>> dontdocme.A.__provides__.__get__(None, dontdocme.B)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: __provides__
It's not really clear to me why this works this way; IDestroyDocs is implemented by B as well as A due to inheritance, so why aren't its various magical attributes visible there as well? I realize these are implementation details, but the behavior seems inconsistent unless B also needed to explicitly declare all the interfaces it implemented.
More information about the Interface-dev
mailing list