How do I document a constructor for a class using Python dataclasses? How do I document a constructor for a class using Python dataclasses? python python

How do I document a constructor for a class using Python dataclasses?


The napoleon-style docstrings as they are described in the sphinx docs (see the ExampleError class for their take on it) explicitly touch on your case:

The __init__ method may be documented in either the class level docstring, or as a docstring on the __init__ method itself.

And if you do not want this behavior, you have to explicitly tell sphinx that the constructor docstring and the class docstring are not the same thing.

Meaning, you can just paste your constructor info into the body of the class docstring.


In case you build documents from your docstrings, these are the granularities that can be achieved:

1) The bare minimum:

@dataclassclass TestClass:    """This is a test class for dataclasses.    This is the body of the docstring description.    """    var_int: int    var_str: str

enter image description here

2) Additional constructor parameter description:

@dataclassclass TestClass:    """This is a test class for dataclasses.    This is the body of the docstring description.    Args:        var_int (int): An integer.        var_str (str): A string.    """    var_int: int    var_str: str

enter image description here

3) Additional attribute description:

@dataclassclass TestClass:    """This is a test class for dataclasses.    This is the body of the docstring description.    Attributes:        var_int (int): An integer.        var_str (str): A string.    """    var_int: int    var_str: str

enter image description here


Parameter and attribute descriptions can of course be combined as well, but since dataclasses should be straight forward mappings I don't see a reason to do so.

In my opinion, 1) would do for small or simple dataclasses -- it already includes the constructor signature with their respective types, which is plenty for a dataclass. If you want to say more about each attribute, 3) would serve best.


A major advantage of dataclasses is that they are self-documenting. Assuming the reader of your code knows how dataclasses work (and your attributes are appropriately named), the type-annotated class attributes should be excellent documentation of the constructor. See this example from the official dataclass docs:

@dataclassclass InventoryItem:    '''Class for keeping track of an item in inventory.'''    name: str    unit_price: float    quantity_on_hand: int = 0    def total_cost(self) -> float:        return self.unit_price * self.quantity_on_hand

If you don't expect that readers of your code would know how dataclasses work then you might want to reconsider using them or adding an explanation or link to the docs in an inline comment after the @dataclass decorator. If you really need a docstring for a dataclass, I'd recommend putting the constructor docstring within the class docstring. For the example above:

'''Class for keeping track of an item in inventory.Constructor arguments::param name: name of the item:param unit_price: price in USD per unit of the item:param quantity_on_hand: number of units currently available'''


I think the easiest way is:

@dataclassclass TestClass:    """This is a test class for dataclasses.    This is the body of the docstring description.    """    var_int: int  #: An integer.    #: A string.    #: (Able to have multiple lines.)    var_str: str    var_float: float    """A float. (Able to have multiple lines.)"""

Not sure why rendered results by @Arne look like that. In my case, attributes in a dataclass will always show regardless of the docstring. That is:

1) The bare minimum:

2) Additional constructor parameter description:

3) Additional attribute description:

Probably because I have set something wrong in my conf.py (Sphinx v3.4.3, Python 3.7):

extensions = [    "sphinx.ext.napoleon",    "sphinx.ext.autodoc",    "sphinx_autodoc_typehints",    "sphinx.ext.viewcode",    "sphinx.ext.autosectionlabel",]# Napoleon settingsnapoleon_google_docstring = Truenapoleon_include_init_with_doc = True