← Back to team overview

fenics team mailing list archive

Re: FEniCS Documentation -- PyDOLFIN doc-strings

 

On Wednesday June 23 2010 07:35:56 Kristian Oelgaard wrote:
> On 23 June 2010 10:55, Kristian Oelgaard <k.b.oelgaard@xxxxxxxxx> wrote:
> > On 22 June 2010 19:03, Johan Hake <johan.hake@xxxxxxxxx> wrote:
> >> On Tuesday June 22 2010 08:28:37 Kristian Oelgaard wrote:
> >>> I've started writing the programmer's reference for FEniCS.
> >>> One of the features that we decided on was that doc-strings for
> >>> PyDOLFIN should be written and maintained as part of the documentation
> >>> project and then added to the dolfin module on import.
> >>> 
> >>> I thought about doing this in the following way:
> >>> 
> >>> 1) Create a pseudo module 'dolfin-doc' which is a copy of the classes
> >>> and functions in the 'real' dolfin module only it contains no code at
> >>> all, just doc-strings. (This approach will also make it easy to create
> >>> a script to check if all functions are documented or if any docs are
> >>> obsolete).
> >> 
> >> Sounds good. I first thought of a structure (other than a dummy class)
> >> that just mimics the class hierarchy, but in some way that is what you
> >> actually suggests and it is probably as easy as anything else.
> >> 
> >>> 2) Use the autodoc functionality of Sphinx to create parts of the
> >>> documentation for functions and classes
> >>> 
> >>> 3) Manually add additional information (in the reST file) and links to
> >>> other parts of the documentation like demos etc. This will not be
> >>> available using help() in the Python interpreter.
> >>> 
> >>> 4) In the dolfin.__init__.py function import the 'dolfin-doc' module
> >>> and copy the doc-strings from all classes and functions to the classes
> >>> and functions in the real dolfin module as was suggested by Johan
> >>> Hake.
> >>> 
> >>> The problem with this approach is that assigning to __doc__ is not
> >>> permitted for objects of 'type' type.
> >>> 
> >> :(
> >> 
> >> I did not anticipate this. Not sure why this is. I have got the
> >> impression that numpy get around this. They use numpydoc to dynamically
> >> add their documentation. It makes heavy use of sphinx, but I couldn't
> >> figure how they get around that __doc__ is read-only.
> > 
> > To me it looks like numpydoc is a Sphinx extension that translates the
> > Numpy docstrings into something that Sphinx can understand, not the
> > other way around which is what we want.
> > 
> > http://projects.scipy.org/numpy/browser/trunk/doc/sphinxext/README.txt
> > 
> > So I think our best bet is to proceed with your suggestions below.
> > 
> > Kristian
> > 
> >> While it might be cool to look into what NumPy have done, (they also
> >> define a pseudo classes, which they populate with docstrings, (look
> >> into phantom_import.py), and they also define some nice format for the
> >> reST used in the docstrings), I suggest two things we can do:
> >> 
> >> 1) SWIG can generate docstrings. We do that allready using parsed
> >> doxygen documentation. All of this is gathered in docstrings.i. I
> >> suggest generating such a file from our documentation. We need to turn
> >> of %feature("autodoc","1") in dolfin.i to get rid of the long and
> >> sometimes faulty generated signatures.
> 
> I turns out that it's only the __doc__ of the class I can't assign to,
> not the __doc__ of member functions (and regular functions).
> A simpler solution (at least for me) is to parse the cpp.py module
> once generated and substitute all docstrings of classes with the
> docstrings from the dolfindoc module rather than creating the
> docstrings.i file.
> 
> Then for the classes that we manually add we use the method you
> described below, but only for class.__doc__ .
> 
> class Foo(object):
>     __doc__ = dolfindoc.Foo.__doc__
>     def bar(self):
>         "this doc string will be substituted with the
> dolfindoc.Foo.__dict__["bar"].__doc__."
>         pass
> 
> then in dolfin/__init__.py we load the classes as we do now from the
> dolfin module, and then iterate over all functions and member
> functions and substitute docstrings from the dolfindoc module.

Sounds good to me. And remember that we only need to use the SWIG docstring 
feature for classes that we do not extend in our own Python layer.

Have we landed on a unified way of expressing parameters to methods, functions 
and class initialization? NumPy relies on reST and they have defined what 
should go into a docstring. Their example is quite extensive and we should 
probably cut it down, but I think it is a nice reference:

  http://projects.scipy.org/numpy/browser/trunk/doc/EXAMPLE_DOCSTRING.txt

Johan


> Kristian
> 
> >> 2) The added python classes and methods can be documented using your
> >> suggested approach, but instead of adding the docstring after class
> >> creation, do it during class (method or function) creation, a la:
> >> 
> >>  class Foo(object):
> >>      __doc__ = docstrings.Foo.__doc__
> >>      ...
> >> 
> >> where docstrings is the generated module containing the docstrings.
> >> 
> >> Johan
> >> 
> >>> In other words we can't assign to the __doc__ of
> >>> 
> >>> class Foo(object):
> >>>     "Foo doc"
> >>>     pass
> >>> 
> >>> Which is a new-style class and found in UFL and the SWIG code in
> >>> DOLFIN.
> >>> 
> >>> It works fine for
> >>> 
> >>> def some_function(v):
> >>>     "function doc"
> >>>     return 2*v
> >>> 
> >>> and
> >>> 
> >>> class Bar:
> >>>     "Bar doc"
> >>>     pass
> >>> 
> >>> which is the old-style class often found in FFC.
> >>> 
> >>> Does anyone have a solution or comments to the above approach, or
> >>> maybe we can do it in a completely different way.
> >>> 
> >>> I read about some workaround for the 'assign to __doc__' problem, but
> >>> it doesn't seem that nice and it might be a problem to incorporate in
> >>> the SWIG generated code?
> >>> 
> >>> http://stackoverflow.com/questions/71817/using-the-docstring-from-one-m
> >>> etho d-to-automatically-overwrite-that-of-another-me
> >>> 
> >>> 
> >>> Kristian
> >>> 
> >>> _______________________________________________
> >>> Mailing list: https://launchpad.net/~fenics
> >>> Post to     : fenics@xxxxxxxxxxxxxxxxxxx
> >>> Unsubscribe : https://launchpad.net/~fenics
> >>> More help   : https://help.launchpad.net/ListHelp
> 
> _______________________________________________
> Mailing list: https://launchpad.net/~fenics
> Post to     : fenics@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~fenics
> More help   : https://help.launchpad.net/ListHelp



Follow ups

References