Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sphinx does not show class instantiation arguments for generic classes (i.e. parametric types)

Sphinx HTML documentation for generic Python classes (i.e. parametric types) does not show the initialization arguments.

Desired output: class GenericClass(value: T)

Actual output: class GenericClass(*args, **kwargs)

Python source code (class_test.py)

from typing import Generic, TypeVar

#:TypeVar("T"): Type variable serving as a parameter for generic types.
T = TypeVar("T")


class GenericClass(Generic[T]):
    """A class that accepts a generic type parameter.

    Attributes:
        value: A value of generic type ``T``.
    """
    def __init__(self, value: T):
        self.value: T = value


class RegularClass:
    """A regular class that is explicitly typed.

    Attributes:
        value: A string value.
    """
    def __init__(self, value: str):
        self.value: str = value

Sphinx Output

enter image description here

conf.py

import os
import sys
sys.path.insert(0, os.path.abspath('../..'))

# -- Project information -----------------------------------------------------
project = 'sphinx-autodoc-generic-class-bug'
copyright = '2020, Christopher Peisert'
author = 'Christopher Peisert'

# The short X.Y.Z version.
version = "0.0.1"

# -- General configuration ---------------------------------------------------

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.napoleon',
]

# autodoc options
autodoc_typehints = 'signature'

autodoc_default_options = {
    'autoclass_content': 'class',
    'member-order': 'bysource',
    'members': True,
    'show-inheritance': True,
}

# Napoleon settings
napoleon_google_docstring = True
napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False
napoleon_use_param = False  # Show the Parameter Types in separate line.
napoleon_use_rtype = True   # Show the Return Type in separate line.


# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build']

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
source_suffix = ['.rst']

# The master toctree document.
master_doc = 'index'


# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
html_theme = 'classic'


# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

class_test.rst

=========================
Generic vs. Regular Class
=========================

.. automodule:: src.class_test
    :exclude-members: T

    .. autodata:: T
        :annotation: = TypeVar("T")
like image 629
Christopher Peisert Avatar asked Oct 19 '25 08:10

Christopher Peisert


1 Answers

The exact Python code in the question works for me using the sphinx.ext.autodoc extension together with the configuration autodoc_typehints = 'signature'.

enter image description here

conf.py

extensions = [
    'sphinx.ext.autodoc',
]

autodoc_typehints = 'signature'

autodoc_default_options = {
    'members':           True,
    'undoc-members':     True,
    'member-order':      'bysource',
}

type_var_test.rst

=============
type_var_test
=============

.. automodule:: type_var_test
    :show-inheritance:

It also works using sphinx.ext.napoleon with the bellow configurations. Notice typing.TypeVar is a class so you can cross-reference it as such, altough in the .rst it is best declared as a module level variable using .. autodata::. This leaves several choices of style, should you go for Google style type annotations in docstrings, it would look like this:

enter image description here

conf.py

extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.napoleon',
]

# Napoleon settings
napoleon_google_docstring = True
napoleon_numpy_docstring = True
napoleon_include_init_with_doc = False
napoleon_include_private_with_doc = False
napoleon_include_special_with_doc = False
napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False
napoleon_use_ivar = False
napoleon_use_param = False
napoleon_use_rtype = False

type_var_test.py

from typing import Generic, TypeVar

#:TypeVar("T"): Type variables exist primarily for the benefit of static type checkers.
T = TypeVar("T")



class GenericClass(Generic[T]):
    """A class that accepts a generic type parameter.

    Attributes:
        value (:class:`T`): Google style with types in docstrings.
    """
    def __init__(self, value: T):
        self.value: T = value

type_var_test.rst

=============
type_var_test
=============

.. automodule:: type_var_test
    :show-inheritance:
    :exclude-members: T

    .. autodata:: T
        :annotation: = TypeVar("T")
like image 127
bad_coder Avatar answered Oct 21 '25 21:10

bad_coder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!