zaknotzach zaknotzach - 4 months ago 23
Python Question

How to document Structure fields in Python using Sphinx

I have python classes declared in the following way:

class Foo(Structure):
_fields_ = [
("vr", c_double),
("vi", c_double),
("vm", c_float),
("va", c_float)]


They are subclasses of
Structure
because I am using
ctypes
to wrap a C DLL and these are the mirrors of the C structs. I can't figure out how to generate documentation for these. The auto-generated documentation is very ugly and useless:

va
Structure/Union member
vi
Structure/Union member
vm
Structure/Union member
vr
Structure/Union member


Does anyone have any idea how I can define these?

I just wanted to clarify that
_fields_
sort of doesn't actually exist. It is a special feature of
ctypes
that provides a way of declaring members in a way that you can line up with a C struct. So if I instantiate the object:
foo = Foo()
then I would never access
_fields_
but rather the members directly as if they were just declared as normal instance variables. So, using the instance above, to access
vr
I would do something like
print foo.vr
.

What is tripping me up here is that I want to add descriptions of those variables. The auto-generation calls them "structure/union members" which makes sense, since they are members of a structure, but I want to add a more descriptive and useful description. For example, I would like to add a note that "vm" is magnitude and "va" is angle.

Answer

The unwanted auto-generated documentation disappears if the :undoc-members: option to the automodule directive is removed.


Add a docstring to the Foo class. In that docstring, describe the the _fields_ class variable. Perhaps the easiest way to do that is to simply include the definition verbatim. Something like this:

class Foo(Structure):
    """
    This class is used to...

    The ``_fields_`` class variable is defined as follows::

      _fields_ = [
         ("vr", c_double),
         ("vi", c_double),
         ("vm", c_float),
         ("va", c_float)]
    """

    _fields_ = [
        ("vr", c_double),
        ("vi", c_double),
        ("vm", c_float),
        ("va", c_float)]

Here is another way of doing it that might be closer to what you want:

class Foo(Structure):
    """
    This class is used to...

    Instances of this class have the following members:

    * ``vr`` (type: c_double): whatever
    * ``vi`` (type: c_double): something
    * ``vm`` (type: c_float): magnitude 
    * ``va`` (type: c_float): angle
    """

    _fields_ = [
        ("vr", c_double),
        ("vi", c_double),
        ("vm", c_float),
        ("va", c_float)]

Yet another alternative (using info fields):

class Foo(Structure):
    """
    This class is used to...

    :ivar vr: whatever
    :vartype vr: c_double
    :ivar vi: something
    :vartype vi: c_double
    :ivar vm: magnitude
    :vartype vm: c_float
    :ivar va: angle
    :vartype va: c_float
    """

    _fields_ = [
        ("vr", c_double),
        ("vi", c_double),
        ("vm", c_float),
        ("va", c_float)]