After finding this question I settled on the following, which is valid Sphinx and works fairly well:
def some_function(first, second="two", **kwargs):
r"""Fetches and returns this thing
:param first:
The first parameter
:type first: ``int``
:param second:
The second parameter
:type second: ``str``
:param \**kwargs:
See below
:Keyword Arguments:
* *extra* (``list``) --
Extra stuff
* *supplement* (``dict``) --
Additional content
"""
The r"""...""" is required to make this a "raw" docstring and thus keep the \* intact (for Sphinx to pick up as a literal * and not the start of "emphasis").
The chosen formatting (bulleted list with parenthesized type and m-dash-separated description) is simply to match the automated formatting provided by Sphinx.
Once you've gone to this effort of making the "Keyword Arguments" section look like the default "Parameters" section, it seems like it might be easier to roll your own parameters section from the outset (as per some of the other answers), but as a proof of concept this is one way to achieve a nice look for supplementary **kwargs if you're already using Sphinx.
After finding this question I settled on the following, which is valid Sphinx and works fairly well:
def some_function(first, second="two", **kwargs):
r"""Fetches and returns this thing
:param first:
The first parameter
:type first: ``int``
:param second:
The second parameter
:type second: ``str``
:param \**kwargs:
See below
:Keyword Arguments:
* *extra* (``list``) --
Extra stuff
* *supplement* (``dict``) --
Additional content
"""
The r"""...""" is required to make this a "raw" docstring and thus keep the \* intact (for Sphinx to pick up as a literal * and not the start of "emphasis").
The chosen formatting (bulleted list with parenthesized type and m-dash-separated description) is simply to match the automated formatting provided by Sphinx.
Once you've gone to this effort of making the "Keyword Arguments" section look like the default "Parameters" section, it seems like it might be easier to roll your own parameters section from the outset (as per some of the other answers), but as a proof of concept this is one way to achieve a nice look for supplementary **kwargs if you're already using Sphinx.
Google Style docstrings parsed by Sphinx
Disclaimer: not tested.
From this cutout of the sphinx docstring example, the *args and **kwargs are left unexpanded:
def module_level_function(param1, *args, param2=None, **kwargs):
"""
...
Args:
param1 (int): The first parameter.
param2 (Optional[str]): The second parameter. Defaults to None.
Second line of description should be indented.
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.
I would suggest the following solution for compactness:
"""
Args:
param1 (int): The first parameter.
param2 (Optional[str]): The second parameter. Defaults to None.
Second line of description should be indented.
*param3 (int): description
*param4 (str):
...
**key1 (int): description
**key2 (int): description
...
Notice how, Optional is not required for **key arguments.
Otherwise, you can try to explicitly list the *args under Other Parameters and **kwargs under the Keyword Args (see docstring sections):
"""
Args:
param1 (int): The first parameter.
param2 (Optional[str]): The second parameter. Defaults to None.
Second line of description should be indented.
Other Parameters:
param3 (int): description
param4 (str):
...
Keyword Args:
key1 (int): description
key2 (int): description
...
Annotating args and kwargs in Python
python - How to document kwargs in Sphinx style? - Software Engineering Stack Exchange
Document methods and classes when *args, **kwargs are present
Support "Keyword Arguments" sections in Google-style docstrings
I tend to avoid *args and **kwargs in Python as they often obscure public APIs. But I'm glad that it's now at least possible to annotate them somewhat precisely.
https://rednafi.com/python/annotate_args_and_kwargs/
Summary
The **kwargs are not typically listed in the function, but instead the final destination of the **kwargs is mentioned. For example:
**kwargs
Instructions on how to decorate your plots.
The keyword arguments are passed to `matplotlib.axes.Axes.plot()`
- If there are multiple possible targets, they are all listed (see below)
- If you happen to use some automation tool to interpolate and link your documentation, then you might list the possible keyword arguments in
**kwargsfor the convenience of the end users. This kind of approach is used in matplotlib, for example. (see below)
How and when document **kwargs (Numpydoc)
1) When to use **kwargs?
First thing to note here is that **kwargs should be used to pass arguments to underlying functions and methods. If the argument inside **kwargs would be used in the function (and not passed down), it should be written out as normal keyword argument, instead.
2) Where to put **kwargs decription?
The location of **kwargs description is in the Parameters section. Sometimes it is appropriate to list them in the Other Parameters section, but remember: Other Parameters should only be used if a function has a large number of keyword parameters, to prevent cluttering the Parameters section.
matplotlib.axes.Axes.gridhas**kwargsinParameterssection.matplotlib.axes.Axes.plothas**kwargsinOther Parameterssection (reasoning probably to large number of keyword arguments).
3) Syntax for **kwargs decription
The syntax for the description for the **kwargs is, following Numpydoc styleguide
Parameters
----------
... (other lines)
**kwargs : sometype
Some description on what the kwargs are
used for.
or
Parameters
----------
... (other lines)
**kwargs
Some description on what the kwargs are
used for.
The one describing the type is more appropriate, as [source].
For the parameter types, be as precise as possible
One exception for this is for example when the **kwargs could be passed to one of many functions based on other parameter values, as in seaborn.kdeplot. Then, the line for the type would become too long for describing all the types and it would be cleaner to use a bullet point list, which also describes the conditions on when the **kwargs are forwarded to where. Eg.:
Parameters
----------
fill: bool or None
If True, fill in the area under univariate density curves or between
bivariate contours. If None, the default depends on multiple.
**kwargs
Other keyword arguments are passed to one of the following matplotlib
functions:
* matplotlib.axes.Axes.plot() (univariate, fill=False),
* matplotlib.axes.Axes.fill_between() (univariate, fill=True),
* matplotlib.axes.Axes.contour() (bivariate, fill=False),
* matplotlib.axes.contourf() (bivariate, fill=True).
You may also add listing of the valid keyword arguments in **kwargs like in matplotlib.axes.Axes.grid. Here is the interpolated python doc/text version:
Parameters
----------
... (other lines)
**kwargs : `.Line2D` properties
Define the line properties of the grid, e.g.::
grid(color='r', linestyle='-', linewidth=2)
Valid keyword arguments are:
Properties:
agg_filter: a filter function, which takes a (m, n, 3) float array and a dpi value, and returns a (m, n, 3) array
alpha: float or None
animated: bool
antialiased or aa: bool
clip_box: `.Bbox`
clip_on: bool
clip_path: Patch or (Path, Transform) or None
color or c: color
contains: unknown
dash_capstyle: {'butt', 'round', 'projecting'}
dash_joinstyle: {'miter', '
... (more lines)
This is convenient for the user, but challenging for the developer. In matplotlib this kind of luxury is made possible with the automatization using some special documentation decorators and linking1. Manual writing of allowed kwargs will surely become a code maintenance nightmare.
4) Notes related to **kwargs / Extended help
Some additional info about the **kwargs could be included in the Notes section.
For example matplotlib.axes.Axes.plot discusses marker styles, line styles and colors in the Notes section. [2]
[1] They use a @docstring.dedent_interpd decorator which pulls the meaning of the kwargs to the final docs. So that is happening in place of %(Line2D:kwdoc)s, for example.
[2] See: help(ax.plot) where ax is instance of matplotlib.axes.Axes.
Usually kwargs that need to be described in the Parameters section would typically be handled like other named arguments and the **kwargs is left unexpanded. However, the numpy style guide also has an Other Parameters section than can be used for providing descriptions of kwargs without cluttering the Parameters section. The style guide describes it as:
An optional section used to describe infrequently used parameters. It should only be used if a function has a large number of keyword parameters, to prevent cluttering the Parameters section.
The numpydoc repo gives this example:
"""
Other Parameters
----------------
only_seldom_used_keyword : int, optional
Infrequently used parameters can be described under this optional
section to prevent cluttering the Parameters section.
**kwargs : dict
Other infrequently used keyword arguments. Note that all keyword
arguments appearing after the first parameter specified under the
Other Parameters section, should also be described under this
section.
"""
So, the additional kwargs could be added as
"""
Other Parameters
----------------
first_kwarg: int
This is an integer
second_kwarg: str
This is a string
**kwargs : dict
Other infrequently used keyword arguments.
"""
Hi, can you please give me your feedback about the way I am writing Python docstring ?Mine looks usually like this: https://imgur.com/a/V6QJLJpand in full text (as I cannot insert the image directly):
def getItemsByFolder(folderId):"""Get all Items from database that belong to a particular folder.
Args:folderId (str): A valid folder Id that is present in the Items databaseReturns:list: A list containing folders folder Items represented as dictionaries"""
-
Is there a possibility to avoid this empty line above 'Args' ? (with a special character for example)I do not like it because it takes a lot of screen real-estate for nothing it makes functions hard to read.
-
Is 'Args' or 'Parameters' the correct keyword ?
