← Back to team overview

fenics team mailing list archive

Re: Generation of docstring module

 

[snip]

> > But how do we extract the different arguments? I suppose this is
> > collected by Doxygen, and we just need to parse these and output them in
> > a correct way?
> 
> I don't think we need to parse the arguments and output them. We just
> get the function name and if we have more than one set of arguments
> i.e., a different signature we know that we have an overloaded method
> and how to handle it.

And I guess the almighty generate_cpp_documentation.py script are able to 
extract the argument information?

> The arguments should be described in the *Arguments* section of the
> individual docstring with links to classes formatted like
> _MeshEntity_, which we will substitute with :py:class:`MeshEntity` or
> 
> :cpp:class:`MeshEntity` depending on which interface we document.

Ok, but we only want that once for each method in python, even if it is 
overloaded?

> Although I just realized that standard C++ stuff like double* which
> end up as numpy.array etc. should probably be handled.

Yes this part I am a little worried about... But maybe a god handwritten 
lookup table will do the trick? At least for 99% of the cases ;)

> On a related note:
> int some_func()
> and
> const int some_func() const
> are different in C++, but in Python we don't have const right?
> This will simplify the documentation a lot.

Yes, we tend to %ignore all const versions of different methods.

[snap]

> >> >  * Extended methods needs to be handled in one of three ways:
> >> >    1) Write the docstring directly into the foo_post.i file
> 
> I like this option, if this is where we have the code for a function,
> then this is where the docstring should be as it increases the
> probability of the docstring being up to date.

Ok, lets settle on this one. We also need to make sure that all %extended 
methods in the C++ layer gets a proper docstring. However I am not really sure 
how this can be done :P

[snup]

> > Why do we need to assign to these methods? They already get their
> > docstrings from the docstrings.i file. However if we want to get rid of
> > the new_instancemethod assignment above, we can just remove the
> 
> Some history.
> Initially, we wanted to have all docstrings separated from the DOLFIN
> code and collected in the fenics-doc module. The easiest way to get
> the >>> help(dolfin) docstring correct is to assign to __doc__
> dynamically.
> If we could do this we wouldn't even need the docstrings.i file and
> things would be simple.
> However, we discovered that this was not possible, and because of that
> we still need to generate the docstrings.i file.
> Then, still assuming we wanted to separate docs from code and keeping
> docstrings in fenics-doc, I thought it would be easier to generate the
> docstrings.i file from the handwritten docstrings module in
> fenics-doc.
> Some methods don't get their docstrings from the docstrings.i file
> though, so we still need to assign to __doc__ which is the easiest
> thing to do.
> Just recently we decided to extract the docstrings from the C++
> implementation thus moving the docs back into DOLFIN. This makes the
> docstrings module almost superfluous with the only practical usage is
> to have documentation for the extended methods defined in the _post.i
> files but if we put the docstrings directly in the _post.i files we no
> longer need it.

Ok, then I do not see any reason for a separate docstring module, makes life a 
lite bit easier...

[snep] 

> > I am confused. Do you suggest that we just document the extended Python
> > layer directly in the python module as it is today? Why should we then
> > dumpt the docstrings in a separate docstring module? So autodoc can have
> > something to shew on? Couldn't autodoc just shew on the dolfin module
> > directly?
> 
> I'm confused too. :) I guess my head has not been properly reset
> between the changes in documentation strategies.
> The Sphinx autodoc can only handle one dolfin module, so we need to
> either import the 'real' one or the docstrings dolfin module.
> If we can completely remove the need for the docstrings module, then
> we should of course include the 'real' one.

Ok!

> >> Then programmer's writing the Python
> >> layer just need to document while they're coding, where they are
> >> coding just like they do (or should anyways) for the C++ part.
> > 
> > Still confused why we need a certain docstring module.
> 
> Maybe we don't.
> 
> >> >  2) for the extended Python layer in the cpp.py
> >> > 
> >> > For the rest, and this will be the main part, we rely on parsed
> >> > docstrings from the headers.
> >> > 
> >> > The python programmers reference will then be generated based on the
> >> > actual dolfin module using sphinx and autodoc.
> >> 
> >> We could/should probably use either the dolfin module or the generated
> >> docstring module to generate the relevant reST files. Although we
> >> might need to run some cross-checks with the Doxygen xml to get the
> >> correct file names where the classes are defined in DOLFIN such that
> >> we retain the original DOLFIN source tree structure. Otherwise all our
> >> documentation will end up in cpp.rst which I would hate to navigate
> >> through as a user.
> > 
> > This one got to technical for me. Do you say that there is no way to
> > split the documentation into smaller parts without relying on the c++
> > module/file structure?
> 
> But how would you split it? 

I do not know. But then I do not know what the generation step can take as 
different inputs.

> It makes sense to keep the classes Mesh
> and MeshEntity in the mesh/ part of the documentation. Unfortunately,
> Swig doesn't add info to the classes in the cpp.py module about where
> they were originally defined. This is why we need to pair it with info
> from the xml output.

Ok, but say we keep all documentation in one module. If you are able to pair 
the different classes or functions with a module name, or file name you are 
able to create documentation which is structured after this hierarchy?
 
> >> I vote for using the generated docstrings module for the documentation
> >> since it should contain all classes even if some HAS_* was not
> >> switched on, which brings me to the last question, how do we handle
> >> the case where some ifdefs result in classes not being generated in
> >> cpp.py? They should still be documented of course.
> > 
> > I think we are fine if the server that generate the documentation has all
> > optional packages, so the online documentation is fully up to date.
> 
> Maybe, but I think I saw somewhere that depending on the ifdefs some
> names would be different and we need the documentation to be complete
> regardless of the users installation.

Yes, I think this is most relevant for the different la backends.

> >> Another issue we need to handle is any example code in the C++ docs
> >> which must be translated into Python syntax. Either automatically, or
> >> by some looking up in a dictionary, but that brings us right back to
> >> something < 100% automatic.
> > 
> > Would it be possible to have just pointers to demos instead of example
> > code. I know it is common to have example code in Python docstrings but
> > I do not think it is equally common to have this in C++ header files.
> 
> Since when did we care about common in FEniCS? :) I think small
> input/output examples are good even for C++, look at the Mesh class
> for instance.

Ok, but put it in another way. It does look quite funny with a Python example 
in the C++ header. But if we start putting these in their own lookup file we 
are back again to the separate file we just abandone. We could maybe add some 
more markup for c++ and Python examples directly in the header?

[snop] sorry ran out of vowels...
 
> > Which should serve us well.
> 
> OK, looks reasonable. So it might be possible to do this after all.

Well, I think we have to let the almight script have a go first ;)

Johan



Follow ups

References