Dynamic documentation for instances of classes#
The functionality in this module allows to define specific docstrings
of instances of a class, which are different from the class docstring.
A typical use case is given by cached methods: the documentation of a
cached method should not be the documentation of the class
CachedMethod
; it should be the documentation of the underlying
method.
In order to use this, define a class docstring as usual. Also define a
method def _instancedoc_(self)
which should return the docstring of
the instance self
. Finally, add the decorator @instancedoc
to
the class.
Warning
Since the __doc__
attribute is never inherited, the decorator
@instancedoc
must be added to all subclasses of the class
defining _instancedoc_
. Doing it on the base class is not
sufficient.
EXAMPLES:
sage: from sage.misc.instancedoc import instancedoc
sage: @instancedoc
....: class X():
....: "Class docstring"
....: def _instancedoc_(self):
....: return "Instance docstring"
sage: X.__doc__
'Class docstring'
sage: X().__doc__
'Instance docstring'
For a Cython cdef class
, a decorator cannot be used. Instead, call
instancedoc()
as a function after defining the class:
sage: cython(''' # optional - sage.misc.cython
....: from sage.misc.instancedoc import instancedoc
....: cdef class Y:
....: "Class docstring"
....: def _instancedoc_(self):
....: return "Instance docstring"
....: instancedoc(Y)
....: ''')
sage: Y.__doc__
'File:...\nClass docstring'
sage: Y().__doc__
'Instance docstring'
One can still add a custom __doc__
attribute on a particular
instance:
sage: obj = X()
sage: obj.__doc__ = "Very special doc"
sage: print(obj.__doc__)
Very special doc
This normally does not work on extension types:
sage: Y().__doc__ = "Very special doc"
Traceback (most recent call last):
...
AttributeError: attribute '__doc__' of 'Y' objects is not writable
This is an example involving a metaclass, where the instances are
classes. In this case, the _instancedoc_
from the metaclass is only
used if the instance of the metaclass (the class) does not have a
docstring:
sage: @instancedoc
....: class Meta(type):
....: "Metaclass doc"
....: def _instancedoc_(self):
....: return "Docstring for {}".format(self)
sage: class T(metaclass=Meta):
....: pass
sage: print(T.__doc__)
Docstring for <class '__main__.T'>
sage: class U(metaclass=Meta):
....: "Special doc for U"
sage: print(U.__doc__)
Special doc for U