Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

autodoc: fix constructor signatures for classes derived from typing.Generic #8142

Merged
merged 2 commits into from Oct 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions sphinx/ext/autodoc/__init__.py
Expand Up @@ -1317,6 +1317,12 @@ def format_args(self, **kwargs: Any) -> Any:
]


# Types whose __new__ signature is a pass-thru.
_CLASS_NEW_BLACKLIST = [
'typing.Generic.__new__',
]


class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: ignore
"""
Specialized Documenter subclass for classes.
Expand Down Expand Up @@ -1385,6 +1391,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 _CLASS_NEW_BLACKLIST:
new = None

if new is not None:
self.env.app.emit('autodoc-before-process-signature', new, True)
try:
Expand Down
12 changes: 12 additions & 0 deletions tests/roots/test-ext-autodoc/target/generic_class.py
@@ -0,0 +1,12 @@
from typing import TypeVar, Generic


T = TypeVar('T')


# Test that typing.Generic's __new__ method does not mask our class'
# __init__ signature.
class A(Generic[T]):
"""docstring for A"""
def __init__(self, a, b=None):
pass
15 changes: 15 additions & 0 deletions tests/test_ext_autodoc.py
Expand Up @@ -290,6 +290,21 @@ def foo3(self, d='\n'):
'(b, c=42, *d, **e)'


@pytest.mark.skipif(sys.version_info < (3, 5), reason='typing is available since python3.5.')
@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_autodoc_process_signature_typing_generic(app):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you rewrite testcase using do_autodoc()?

  • Add a target class to tests/roots/test-ext-autodoc/targets/
  • Call do_autodoc(). There are many examples in this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I added a new file because I did not feel it fit in any of the existing test files.

actual = do_autodoc(app, 'class', 'target.generic_class.A', {})

assert list(actual) == [
'',
'.. py:class:: A(a, b=None)',
' :module: target.generic_class',
'',
' docstring for A',
'',
]


def test_autodoc_process_signature_typehints(app):
captured = []

Expand Down