Skip to content

Commit

Permalink
Fix #7786: autodoc: can't detect overloaded methods defined in other …
Browse files Browse the repository at this point in the history
…file
  • Loading branch information
tk0miya committed Oct 5, 2020
1 parent a8abb99 commit 6dbe28a
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGES
Expand Up @@ -42,6 +42,7 @@ Bugs fixed
* #8157: autodoc: TypeError is raised when annotation has invalid __args__
* #7964: autodoc: Tuple in default value is wrongly rendered
* #8200: autodoc: type aliases break type formatting of autoattribute
* #7786: autodoc: can't detect overloaded methods defined in other file
* #8192: napoleon: description is disappeared when it contains inline literals
* #8142: napoleon: Potential of regex denial of service in google style docs
* #8169: LaTeX: pxjahyper loaded even when latex_engine is not platex
Expand Down
30 changes: 18 additions & 12 deletions sphinx/ext/autodoc/__init__.py
Expand Up @@ -1471,22 +1471,14 @@ def format_signature(self, **kwargs: Any) -> str:
return ''

sig = super().format_signature()

overloaded = False
qualname = None
# TODO: recreate analyzer for the module of class (To be clear, owner of the method)
if self._signature_class and self._signature_method_name and self.analyzer:
qualname = '.'.join([self._signature_class.__qualname__,
self._signature_method_name])
if qualname in self.analyzer.overloads:
overloaded = True

sigs = []
if overloaded:

overloads = self.get_overloaded_signatures()
if overloads:
# Use signatures for overloaded methods instead of the implementation method.
method = safe_getattr(self._signature_class, self._signature_method_name, None)
__globals__ = safe_getattr(method, '__globals__', {})
for overload in self.analyzer.overloads.get(qualname):
for overload in overloads:
overload = evaluate_signature(overload, __globals__,
self.env.config.autodoc_type_aliases)

Expand All @@ -1500,6 +1492,20 @@ def format_signature(self, **kwargs: Any) -> str:

return "\n".join(sigs)

def get_overloaded_signatures(self) -> List[Signature]:
if self._signature_class and self._signature_method_name:
for cls in self._signature_class.__mro__:
try:
analyzer = ModuleAnalyzer.for_module(cls.__module__)
analyzer.parse()
qualname = '.'.join([cls.__qualname__, self._signature_method_name])
if qualname in analyzer.overloads:
return analyzer.overloads.get(qualname)
except PycodeError:
pass

return []

def add_directive_header(self, sig: str) -> None:
sourcename = self.get_sourcename()

Expand Down
5 changes: 5 additions & 0 deletions tests/roots/test-ext-autodoc/target/overload2.py
@@ -0,0 +1,5 @@
from target.overload import Bar


class Baz(Bar):
pass
16 changes: 16 additions & 0 deletions tests/test_ext_autodoc.py
Expand Up @@ -2002,6 +2002,22 @@ def test_overload(app):
]


@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_overload2(app):
options = {"members": None}
actual = do_autodoc(app, 'module', 'target.overload2', options)
assert list(actual) == [
'',
'.. py:module:: target.overload2',
'',
'',
'.. py:class:: Baz(x: int, y: int)',
' Baz(x: str, y: str)',
' :module: target.overload2',
'',
]


@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_pymodule_for_ModuleLevelDocumenter(app):
app.env.ref_context['py:module'] = 'target.classes'
Expand Down

0 comments on commit 6dbe28a

Please sign in to comment.