Chapter 22
Documentation

The NekPy package certainly had to be documented in order to provide an easily accessible information about the wrapped classes to both users and developers. Ideally, the documentation should be:

Traditionally, Python classes and functions are documented using a docstring – a string occurring as the very first statement after the function or class is defined. This string is then accessible as the __doc__ attribute of the function or class. The conventions associated with Python docstrings are described in PEP 257 document [36].

Boost.Python provides an easy way to include docstrings in the wrapped methods and classes as shown in Listing 22.1. The included docstrings will appear when Python help method is used.


Listing 22.1: Example of class and method documentation in Boost.Python
1void export_Points() 
2
3        py::class_<PointsKey>("PointsKey", 
4        "Create a PointsKey which uniquely defines quadrature points.\n" 
5        "\n" 
6        "Args:\n" 
7        "\tnQuadPoints (integer): The number of quadrature points.\n" 
8        "\tpointsType (PointsType object): The type of quadrature points.", 
9        py::init<const int, const PointsType&>()) 
10                 
11            .def("GetNumPoints", &PointsKey::GetNumPoints, 
12            "Get the number of quadrature points in PointsKey.\n" 
13            "\n" 
14            "Args:\n" 
15            "\tNone\n" 
16            "Returns:\n" 
17            "\tInteger defining the number of quadrature points in PointsKey.") 
18}

In order to fully document the existing bindings a number of enumeration type classes such as PointsType had to have docstrings included which proved to be a challenge since Boost.Python does not provide a way to do this. Instead a direct call to Python C API has to be made and the method adapted from [58] was used, as shown in Listing 22.2. A downside of this solution is that it does requires the developer to manually update the Python documentation if the enumeration type is ever changed (e.g. adding a new type of point) as the code does not automatically gather information from the C++ class. In theory it could be possible to create a Python script which would generate Python docstrings based on the existing C++ documentation using regular expressions; however it would be difficult to integrate this solution into the existing framework.


Listing 22.2: Code used to include dosctings in enumetation type classes - part of NekPyConfig.hpp
1#define NEKPY_WRAP_ENUM_STRING_DOCS(ENUMNAME,MAPNAME,DOCSTRING)    \ 
2    {                                                              \ 
3        py::enum_<ENUMNAME> tmp(#ENUMNAME);                        \ 
4        for (int a = 0; a < (int)SIZENAME(ENUMNAME); ++a)          \ 
5        {                                                          \ 
6            tmp.value(MAPNAME[a].c_str(), (ENUMNAME)a);            \ 
7        }                                                          \ 
8        tmp.export_values();                                       \ 
9        PyTypeObject * pto =                                       \ 
10            reinterpret_cast<PyTypeObject*>(tmp.ptr());            \ 
11        PyDict_SetItemString(pto->tp_dict, "__doc__",              \ 
12            PyString_FromString(DOCSTRING));                       \ 
13    }

There are many docstrings conventions that are popular in Python such as Epytext, reST and Google therefore a choice had to be made as to which docstring style to use. After considering the criteria which the documentation had to fulfill it was decided to use Google Python Style [59] as it is highly readable by humans (and hence an excellent choice for documentation which will be primarily accessible by Python help method) and can be used to generate automated documentation pages with Sphinx (a tool for creating Python documentation).

Unfortunately, it proved to be difficult to include the documentation of NumPy package in the existing doxygen-based documentation due to the fact that the docstrings are generated by Boost.Python. It was decided that if the time constraints of the project permit this problem could be resolved at a later date and the possibility of accessing the documentation though inbuilt help method was deemed sufficient.