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.

Answer from quornian on Stack Overflow
Top answer
1 of 8
73

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.

2 of 8
45

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 
        ...
🌐
Readthedocs
sphinxcontrib-napoleon.readthedocs.io › en › latest › example_google.html
Example Google Style Python Docstrings — napoleon 0.7 documentation
Multiple paragraphs are supported in parameter descriptions. Args: param1 (int): The first parameter. param2 (:obj:`str`, optional): The second parameter. Defaults to None. Second line of description should be indented. *args: Variable length argument list. **kwargs: Arbitrary keyword arguments.
Discussions

Annotating args and kwargs in Python
You shouldn't use **kwargs in an API - APIs are boundaries, and boundaries should be as explicit as possible. You also shouldn't use *args, unless it's a simple varargs interface (like max(...)) or something with a clear definition (like str.format(...), and even then, I'm not completely on board). More on reddit.com
🌐 r/Python
33
105
January 9, 2024
python - How to document kwargs in Sphinx style? - Software Engineering Stack Exchange
I'm wondering how I can document **kwargs in Python using sphinx dostring style. For example I have the following method and I want to document more details about kwargs. def get(self, url=None... More on softwareengineering.stackexchange.com
🌐 softwareengineering.stackexchange.com
April 12, 2018
Document methods and classes when *args, **kwargs are present
A lot of functions in sympy use ... use of python language. But usage of *args, **kwargs brings in obscurity as to what possible argument the method or functions could possibly take. For example, this is the signature of collect_const · Signature: collect_const(expr, *vars, **kwargs) Docstring: A non-greedy ... More on github.com
🌐 github.com
8
December 6, 2017
Support "Keyword Arguments" sections in Google-style docstrings
Is your feature request related to a problem? Please describe. Keyword sections is useful to document the possible contents of **kwargs. Without it, users must write keyword arguments documentation in the Arguments section, under the **k... More on github.com
🌐 github.com
3
January 17, 2021
Top answer
1 of 1
12

Pycharm cannot warn you that your keywords have the wrong type but if you have the documentation panel open you can see the expected type if specified in the docstring. If not, the shortcut is ctr+q with caret at the function name. One time for a popup, two times to pin the documentation panel to the right.

You can alternativly raise an error if the type is incorrect.

After research and a lot of testing, here is everything I found. Take whatever you need:

from typing import TypedDict


class PersonData(TypedDict):
    name: str
    age: int


class Person:
    """
    a person
    """
    _ssn: int
    _data: PersonData

    def __init__(self, ssn: int, *args, **kwargs) -> None:
        """
        Create an instance of Person

        :param ssn: social security number
        :type ssn: int
        :key name: person's first name, should be a str
        :key age: person's age in years, rounded down, should be an int
        :return: __init__ should return None
        :rtype: None
        """
        self._ssn = ssn

        try:
            if not isinstance(kwargs['name'], str):
                name_type = type(kwargs["name"]).__name__
                raise TypeError(f"Person() kwargs['name']: got {name_type} but"
                                " expected type is str")
        except KeyError:
            raise KeyError("Person() missing required keyword argument 'name'")
        self._data['name'] = kwargs['name']

        try:
            age_type = type(kwargs["age"]).__name__

            if not isinstance(kwargs['age'], int):
                raise TypeError(f"Person() kwargs['age']: got {age_type} but "
                                "expected type is int")
        except KeyError:
            raise KeyError("Person() missing required keyword argument 'age'")
        self._data['age'] = kwargs['age']

Instead of key you can use keyword.

This example provides:

  • Fully documented docstring used by PyCharm to generate Documentation
  • Type checking + Raise TypeError
  • Default values (bonus: Warn user that a default value is set)

I suggest you add @property.getter and @property.setter for accessing _id and _data. And the class attribute _data is overkill, you should replace it with _name and _age as you prefer default value instead of no value. Code here.

Warning : Shadows built-in name 'id'

I suggest ssn for social security number.

Sources: PyCharm 2018.3 Help

🌐
GitHub
github.com › swig › swig › discussions › 2266
Doxygen Comments for Python Functions with **kwargs · swig/swig · Discussion #2266
Then the only option is to have a docstring entry :param **kwargs: ... and list all the keyword arguments in the one comment, or as I noted above to use, for example :keyword a: comment about parameter a....
Author: swig
🌐
GitHub
github.com › sympy › sympy › issues › 13683
Document methods and classes when *args, **kwargs are present · Issue #13683 · sympy/sympy
December 6, 2017 - A lot of functions in sympy use *args and **kwargs, which ofcourse is itself is like making a good use of python language. But usage of *args, **kwargs brings in obscurity as to what possible argument the method or functions could possibly take. For example, this is the signature of collect_const · Signature: collect_const(expr, *vars, **kwargs) Docstring: A non-greedy collection of terms with similar number coefficients in an Add expr.
Author: sympy
Find elsewhere
🌐
Python-sprints
python-sprints.github.io › pandas › guide › pandas_docstring.html
pandas docstring guide — Python documentation
Finally, the `**kwargs` parameter is missing. Parameters ---------- kind: str kind of matplotlib plot """ pass · When specifying the parameter types, Python built-in data types can be used directly (the Python type is preferred to the more verbose string, integer, boolean, etc):
🌐
Pandas
pandas.pydata.org › docs › development › contributing_docstring.html
pandas docstring guide — pandas 3.0.6 documentation
We “append” the parent docstring to the children docstrings, which are initially empty. Our files will often contain a module-level _shared_doc_kwargs with some common substitution values (things like klass, axes, etc).
🌐
GitHub
github.com › mkdocstrings › pytkdocs › issues › 88
Support "Keyword Arguments" sections in Google-style docstrings · Issue #88 · mkdocstrings/pytkdocs
January 17, 2021 - Without it, users must write keyword arguments documentation in the Arguments section, under the **kwargs parameter, using plain Markdown, therefore not benefiting from the table template.
Author: mkdocstrings
🌐
GitHub
gist.github.com › 0xaaadnf › ccc77bcbe21dfff29e636ee4c01fb134
Comprehensive analysis of documenting *args and **kwargs in Python docstrings across Google, NumPy, and Sphinx styles, including tool behavior and AI-generated examples. · GitHub
It enables Sphinx to recognize and correctly interpret the patterns these styles follow, allowing docstrings written in either format to be parsed and rendered properly. For example, Napoleon treats leading star characters in argument names (*args, **kwargs) as normal text, meaning they do not need to be escaped. However, escaping remains optional. Both escaped and unescaped forms are accepted. ... The Google Python Style Guide explicitly states that star arguments should appear in the docstring with their leading stars:
🌐
Kitchin Research Group
kitchingroup.cheme.cmu.edu › blog › 2016 › 04 › 30 › Another-approach-to-docstrings-and-validation-of-args-and-kwargs-in-Python
Another approach to docstrings and validation of args and kwargs in Python
April 30, 2016 - encut validated to ('encut', 400) xc validated to ('xc', 'PBE') ('encut', 400) ('xc', 'PBE') ('kpts', [1, 1, 1]) Help on function encut in module __main__: encut(*args, **kwargs) Planewave cutoff in eV. None · This approach obviously works. I don't think I like the syntax as much, although in most python editors, it should directly give access to the docstrings of the functions.
🌐
sqlpey
sqlpey.com › python › top-4-ways-to-document-kwargs-in-python
Top 4 Ways to Document a kwargs Parameter in Python - sqlpey
November 6, 2024 - :param first: The first parameter :type first: ``int`` :param second: The second parameter :type second: ``str`` :param **kwargs: Additional keyword arguments. :Keyword Arguments: * *extra* (``list``) -- Additional items * *supplement* (``dict``) -- Extra content needed """ In this example, the use of r""" ... """ enables the docstring to preserve raw formatting, ensuring the * is treated as a literal character, which is essential for Sphinx to process it correctly.
🌐
CodingNomads
codingnomads.com › python-args-kwargs
Python Args and Kwargs
In a future lesson, you'll learn how to add docstrings to your function definition. This adds standard documentation to it and makes it easier for you and other developers to work with the functions you're writing. ... In this lesson, you learned about using *args and **kwargs to allow your functions to take arbitrary amounts of arguments:
🌐
Python
docs.python.org › 3.7 › search.html
https://docs.python.org/3.7/search.html?q=kwarg
January 5, 2022 - Please activate JavaScript to enable the search functionality · From here you can search these documents. Enter your search words into the box below and click "search". Note that the search function will automatically search for all of the words. Pages containing fewer words won't appear in ...
🌐
Readthedocs
sphinxcontrib-napoleon.readthedocs.io › en › latest › example_numpy.html
Example NumPy Style Python Docstrings — napoleon 0.7 documentation
The ": type" is optional. Multiple paragraphs are supported in parameter descriptions. Parameters ---------- param1 : int The first parameter. param2 : :obj:`str`, optional The second parameter. *args Variable length argument list. **kwargs Arbitrary keyword arguments.
🌐
DataCamp
datacamp.com › tutorial › docstrings-python
Python Docstrings Tutorial : Examples & Format for Pydoc, Numpy, Sphinx Doc Strings | DataCamp
February 14, 2025 - Sphinx is the easy and traditional style, verbose, and was initially created specifically for Python Documentation. Sphinx uses a reStructured Text, which is similar in usage to Markdown. class Vehicle(object): ''' The Vehicle object contains lots of vehicles :param arg: The arg is used for ... :type arg: str :param `*args`: The variable arguments are used for ... :param `**kwargs`: The keyword arguments are used for ...
Top answer
1 of 2
13

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 **kwargs for 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.grid has **kwargs in Parameters section.
  • matplotlib.axes.Axes.plot has **kwargs in Other Parameters section (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.

2 of 2
6

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.

"""
🌐
BelieveMy
believemy.com › python glossary › kwargs
What is **kwargs in Python? Complete guide | Python glossary
February 10, 2026 - PYTHON · # ❌ Less readable def ... create_user(name, email, age=0): pass · When you use **kwargs, add a detailed docstring to indicate the accepted keyword arguments: PYTHON ·...
🌐
Reddit
reddit.com › r/learnpython › is this docstring correct ? should 'args' or 'parameters', can i avoid have empty line with special character?
r/learnpython on Reddit: Is this docstring correct ? should 'Args' or 'Parameters', can I avoid have empty line with special character?
October 5, 2022 -

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 database
Returns:list: A list containing folders folder Items represented as dictionaries"""

  1. 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.

  2. Is 'Args' or 'Parameters' the correct keyword ?