Skip to content

Commit

Permalink
Fix sphinx-doc#8219: autodoc: A signature of constructor of generic c…
Browse files Browse the repository at this point in the history
…lass is incorrect

Ignore the signature of typing.Generic.__new__() to get correct a
signature of the constructor from a subclass.
  • Loading branch information
tk0miya committed Sep 21, 2020
1 parent 3c017dc commit 95bb8fe
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Bugs fixed
* #8143: autodoc: AttributeError is raised when False value is passed to
autodoc_default_options
* #8103: autodoc: functools.cached_property is not considered as a property
* #8219: autodoc: A signature of constructor of generic class is incorrect
* #8192: napoleon: description is disappeared when it contains inline literals
* #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex
* #8093: The highlight warning has wrong location in some builders (LaTeX,
Expand Down
15 changes: 12 additions & 3 deletions sphinx/ext/autodoc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1312,13 +1312,17 @@ def format_args(self, **kwargs: Any) -> Any:
return None


# Types which have confusing metaclass signatures it would be best not to show.
# These are listed by name, rather than storing the objects themselves, to avoid
# needing to import the modules.
# Types which have confusing metaclass signatures and superclass signatures it
# would be best not to show. These are listed by name, rather than storing the
# objects themselves, to avoid needing to import the modules.
_METACLASS_CALL_BLACKLIST = [
'enum.EnumMeta.__call__',
]

_SUPERCLASS_NEW_BLACKLIST = [
'typing.Generic.__new__',
]


class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: ignore
"""
Expand Down Expand Up @@ -1388,6 +1392,11 @@ def get_user_defined_function_or_method(obj: Any, attr: str) -> Any:

# Now we check if the 'obj' class has a '__new__' method
new = get_user_defined_function_or_method(self.object, '__new__')

if new is not None:
if "{0.__module__}.{0.__qualname__}".format(new) in _SUPERCLASS_NEW_BLACKLIST:
new = None

if new is not None:
self.env.app.emit('autodoc-before-process-signature', new, True)
try:
Expand Down
11 changes: 11 additions & 0 deletions tests/roots/test-ext-autodoc/target/classes.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
from typing import Generic, TypeVar


T = TypeVar("T")


class Foo:
pass

Expand All @@ -10,3 +16,8 @@ def __init__(self, x, y):
class Baz:
def __new__(cls, x, y):
pass


class Qux(Generic[T]):
def __init__(self, x, y):
pass
25 changes: 25 additions & 0 deletions tests/test_ext_autodoc_autoclass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""
test_ext_autodoc_autoclass
~~~~~~~~~~~~~~~~~~~~~~~~~~
Test the autodoc extension. This tests mainly the Documenters; the auto
directives are tested in a test source file translated by test_build.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import pytest

from test_ext_autodoc import do_autodoc


@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_generic_class(app):
actual = do_autodoc(app, 'class', 'target.classes.Qux')
assert list(actual) == [
'',
'.. py:class:: Qux(x, y)',
' :module: target.classes',
'',
]

0 comments on commit 95bb8fe

Please sign in to comment.