Guidelines for writing docstrings for temporian's public API.
Note that these guidelines are useful for internal docstrings too (a.k.a. the ones intended as documentation for other developers of the library rather than its users) but we do not enforce it on those. Internal docstrings can be leaner.
The only purpose of reference material in general is to describe, as succinctly as possible, and in a consistent and orderly way. Good technical reference is essential to provide users with the confidence to do their work.
Users hardly read reference material; they consult it. A docstring's objective is not to delight its readers with vocabulary and style.
Docstrings should be:
- Austere.
- Accurate.
- To the point.
- Unambiguous.
- Reliable.
- Consistent (in language, structure, terminology and tone).
Docstrings should do nothing but describe.
Docstrings should not attempt to show how to perform tasks, but may include a succinct example of the correct way to use what its documenting.
Temporian uses Google's docstring style.
Note that the descriptions below are a distilled and opinionated version of that document.
Use three-double-quote format """
.
A docstring should be composed of:
- A summary line (one physical line not exceeding 80 chars) terminated by a period.
- A blank line.
- When writing more (recommended) the rest of the docstring.
Every file should contain license boilerplate.
Docstrings that do not provide any new information should be avoided:
def lag_operator_test(self):
"""Test for lag operator."""
A module's docstring should describe the contents and usage of the module.
Note that in Python every file is a module.
In temporian we do not (yet) consider module docstrings to be mandatory.
Example:
"""A one-line summary of the module, terminated by a period.
Leave one blank line. The rest of this docstring should contain an
overall description of the module. Optionally, it may also contain a brief
description of exported classes and functions and/or usage examples.
Example:
```python
foo = ClassFoo()
bar = foo.FunctionBar()
```
"""
Note the indentation after the "Example:" clause, which makes mkdocs render it as a dropdown component, and the use of "```", which makes it be rendered as a code block. The same applies for class docstrings.
Module-level docstrings for test files are not required and should only be included when there is additional information that can be provided.
A docstring is mandatory for every function that has one or more of the following properties:
- being part of the public API
- non-trivial size
- non-obvious logic
The docstring's style must be descriptive rather than imperative, i.e.,
"""Shifts the sampling backwards"""
instead of """Shift the sampling backwards"""
.
The docstring's style must not be prefixed with a noun, i.e. """Shifts the sampling backwards"""
instead of """Function that shifts the sampling backwards"""
or """Operator that shifts the sampling backwards"""
, since it
provides no extra information to the reader, who already knows it is a function.
A method that overrides a method from a base class may have a docstring such
as """See base class."""
, unless its behavior is substantially different.
Certain aspects of a function should be documented in the special sections listed below. Each section has a heading, which ends with a colon, and its content is indented 4 spaces in (consistent with project's indentation).
Args:
List each parameter by name.
Do not document the parameter's expected type (type hints are enough).
A description should follow the name, and be separated by a colon followed by a
space.
If the description goes over the max line length, break into a new line with an
additional indentation of 4 spaces.
If a function accepts *args
and/or **kwargs
they should be listed as such.
Omit unnecessary prepositions at the start of each arg's description, such as
The
or A
.
Returns: (or Yields: for generators)
Describe the semantics of the return value.
If more than a single line, break into a new line with an extra indentation.
Do not document the expected return type (type hints are enough).
Do not include the section for functions that return None
.
If a tuple is returned, describe it as: Returns: A tuple (a, b) where a is...
.
Raises:
List and describe all exceptions that are relevant to the interface. Use the same name + colon + space and indent style as in Args:. Do not document exceptions that get raised if the API specified in the docstring is violated.
Example:
"""Fetches rows from a Smalltable.
Retrieves rows pertaining to the given keys from the Table instance
represented by table_handle. String keys will be UTF-8 encoded.
Example:
```python
rows = fetch_rows(handle, keys)
```
Args:
table_handle: Open `smalltable.Table` instance.
keys: Sequence of strings representing the key of each table row to
fetch. String keys will be UTF-8 encoded.
require_all_keys: If `True`, only rows with values set for all keys
will be returned.
Returns:
Dict mapping keys to the corresponding table row data fetched. Each row
is represented as a tuple of strings.
For example:
```
{b'Serak': ('Rigel VII', 'Preparer'),
b'Zim': ('Irk', 'Invader'),
b'Lrrr': ('Omicron Persei 8', 'Emperor')}
```
Returned keys are always bytes. If a key from the keys argument is
missing from the dictionary, then that row was not found in the
table (and `require_all_keys` must have been False).
Raises:
IOError: An error occurred accessing the smalltable.
"""
Classes should have a docstring below the class definition describing them.
If the class has public attributes, they can be documented here in an Attributes: section and follow the same formatting as a function's Args: section.
Example:
"""Summary of class here.
Longer class information...
Longer class information...
Attributes:
likes_spam: Boolean indicating if we like SPAM or not.
eggs: Integer count of the eggs we have laid.
"""
- Diátaxis framework for documentation authoring (recommended read)
- Google's Python style guide