[Doc-SIG] suggestions for a PEP

Edward Welbourne Edward Welbourne <eddy@chaos.org.uk>
Sat, 17 Mar 2001 13:50:26 +0000 (GMT)

> If it's usually *not* what you want, or if we want to keep things 
> simpler, the following seems to work (I don't know why you don't 
> need to use .im_func here)::

>   class B(A):
>       def f(x):
>           return x+1
>       B.f.__doc__ = A.f.__doc__

Close, but not quite - B isn't in scope yet when you say that:
>>> class B:
... 	def f(s): return
... 	B.f.__doc__ = 'hello there'
Traceback (innermost last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in B
NameError: B


>>> class B:
... 	def f(s): return
... 	f.__doc__ = 'hello there'

works fine; and the reason you don't need to use .im_func here is that
the code of B's body gets executed in an empty namespace; the resulting
contents of the namespace get massaged and packaged to become B's
namespace, but only *afterwards* (read types-sig in late 1999 to find
out why I don't like that: but it's how it is).  So, when f.__doc__ got
assigned, f was still a function:

>>> class B:
... 	def f(s): return
... 	print type(f)
<type 'function'>

(subject to usual caveats about my installed python still being 1.5.2)

> I'd be happy with either.

I'd solidly prefer to require an empty doc-string in a method which
doesn't want to inherit the doc-string of its parent.  In principle, at
least when the method is part of the abstract data type spec of the base
class, the derived class shouldn't really be messing with `what does
this guarantee' statements which (as I understand it) you want doc
strings to contain, albeit it may be refining it slightly.

Plus, having to put the empty string in as doc-string is trivial,
doesn't involve typing any magic __tokens__ and happens inside the body
of B.f, rather than after it; and I *really* don't like having to
*assign* B.f's __doc__ in order to get it to show something it should be
inheriting/acquiring from A.f, at least under the rules of abstract data
types.  Notably, consider the case where a base class defines the API to
be supplied by a family of allied classes; the base class exists to
document what they all do, each derived class exists to implement one of
the flavours of the relevant kind of object.

However, shoe-horning that into an implementation may be an issue.