\chapter{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:
\begin{itemize}
  \item easily readable by humans,
  \item accessible using Python's inbuilt \texttt{help} method,
  \item compatible with the existing Nektar++ doxygen-based documentation.
\end{itemize}

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 \texttt{\_\_doc\_\_} attribute of
the function or class. The conventions associated with Python docstrings are
described in PEP 257 document \cite{PEP257}.

\texttt{pybind11} provides an easy way to include docstrings in the wrapped methods
and classes as shown in Listing \ref{lst:doc_example}. The included docstrings
will appear when Python \texttt{help} method is used.

\begin{lstlisting}[caption={Example of class and method documentation in pybind11}, label={lst:doc_example}, language=C++]
void export_Points(py::module &m)
{
	py::class_<PointsKey>(m, "PointsKey", 
        "Create a PointsKey which uniquely defines quadrature points.\n"
        "\n"
        "Args:\n"
        "\tnQuadPoints (integer): The number of quadrature points.\n"
        "\tpointsType (PointsType object): The type of quadrature points.")
            .def(py::init<const int, const PointsType&>())
            .def("GetNumPoints", &PointsKey::GetNumPoints,
            "Get the number of quadrature points in PointsKey.\n"
            "\n"
            "Args:\n"
            "\tNone\n"
            "Returns:\n"
            "\tInteger defining the number of quadrature points in PointsKey.")
}
\end{lstlisting}

In order to fully document the existing bindings a number of enumeration type
classes such as \texttt{PointsType} had to have docstrings included which proved
to be a challenge since \texttt{pybind11} 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 \cite{PythonEnumDocstring} was used, as shown in Listing
\ref{lst:enum_doc}. 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.

\begin{lstlisting}[caption={Code used to include dosctings in enumetation type classes - part of \texttt{NekPyConfig.hpp}}, label={lst:enum_doc}, language=C++]
#define NEKPY_WRAP_ENUM_STRING_DOCS(ENUMNAME,MAPNAME,DOCSTRING)    \
    {                                                              \
        py::enum_<ENUMNAME> tmp(#ENUMNAME);                        \
        for (int a = 0; a < (int)SIZENAME(ENUMNAME); ++a)          \
        {                                                          \
            tmp.value(MAPNAME[a].c_str(), (ENUMNAME)a);            \
        }                                                          \
        tmp.export_values();                                       \
        PyTypeObject * pto =                                       \
            reinterpret_cast<PyTypeObject*>(tmp.ptr());            \
        PyDict_SetItemString(pto->tp_dict, "__doc__",              \
            PyString_FromString(DOCSTRING));                       \
    }
\end{lstlisting}

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 \cite{PythonGoogle} as it is
highly readable by humans (and hence an excellent choice for documentation which
will be primarily accessible by Python \texttt{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 \texttt{pybind11}.  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 \texttt{help}
method was deemed sufficient.
