Sphinx 不显示 class 泛型 classes 的实例化参数(即参数类型)

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

Sphinx HTML 泛型 Python 类(即参数类型)的文档不显示初始化参数。

期望输出class GenericClass(value: T)

实际输出class GenericClass(*args, **kwargs)

Python源代码(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

斯芬克斯输出

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")

使用 sphinx.ext.autodoc 扩展和配置 autodoc_typehints = 'signature'.

问题中的确切 Python 代码对我有用

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:

它也可以使用 sphinx.ext.napoleon 和波纹管配置。注意 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,它看起来像这样:

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")

Sphinx 问题 #8219 autodoc doesn't handle TypeVars or document user-defined generic classes accurately 已在版本 3.4.0 中正式修复。

来自sphinx/CHANGES

Release 3.4.0

...

Features added

  • #8219: autodoc: Parameters for generic class are not shown when super class is a generic class and show-inheritance option is given (in Python 3.7 or above)