Skip to content

Commit

Permalink
Merge pull request #8695 from tk0miya/8514_default_value_of_overloads
Browse files Browse the repository at this point in the history
Close #8514: autodoc: Default values of overloads are taken from actual implementation
  • Loading branch information
tk0miya committed Jan 17, 2021
2 parents 240f755 + d88166e commit 596dfba
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -20,6 +20,8 @@ Features added
* #8022: autodoc: autodata and autoattribute directives does not show right-hand
value of the variable if docstring contains ``:meta hide-value:`` in
info-field-list
* #8514: autodoc: Default values of overloaded functions are taken from actual
implementation if they're ellipsis
* #8619: html: kbd role generates customizable HTML tags for compound keys
* #8634: html: Allow to change the order of JS/CSS via ``priority`` parameter
for :meth:`Sphinx.add_js_file()` and :meth:`Sphinx.add_css_file()`
Expand Down
31 changes: 31 additions & 0 deletions sphinx/ext/autodoc/__init__.py
Expand Up @@ -1355,8 +1355,11 @@ def format_signature(self, **kwargs: Any) -> str:
documenter.objpath = [None]
sigs.append(documenter.format_signature())
if overloaded:
actual = inspect.signature(self.object,
type_aliases=self.config.autodoc_type_aliases)
__globals__ = safe_getattr(self.object, '__globals__', {})
for overload in self.analyzer.overloads.get('.'.join(self.objpath)):
overload = self.merge_default_value(actual, overload)
overload = evaluate_signature(overload, __globals__,
self.config.autodoc_type_aliases)

Expand All @@ -1365,6 +1368,16 @@ def format_signature(self, **kwargs: Any) -> str:

return "\n".join(sigs)

def merge_default_value(self, actual: Signature, overload: Signature) -> Signature:
"""Merge default values of actual implementation to the overload variants."""
parameters = list(overload.parameters.values())
for i, param in enumerate(parameters):
actual_param = actual.parameters.get(param.name)
if actual_param and param.default == '...':
parameters[i] = param.replace(default=actual_param.default)

return overload.replace(parameters=parameters)

def annotate_to_first_argument(self, func: Callable, typ: Type) -> None:
"""Annotate type hint to the first argument of function if needed."""
try:
Expand Down Expand Up @@ -2117,8 +2130,16 @@ def format_signature(self, **kwargs: Any) -> str:
documenter.objpath = [None]
sigs.append(documenter.format_signature())
if overloaded:
if inspect.isstaticmethod(self.object, cls=self.parent, name=self.object_name):
actual = inspect.signature(self.object, bound_method=False,
type_aliases=self.config.autodoc_type_aliases)
else:
actual = inspect.signature(self.object, bound_method=True,
type_aliases=self.config.autodoc_type_aliases)

__globals__ = safe_getattr(self.object, '__globals__', {})
for overload in self.analyzer.overloads.get('.'.join(self.objpath)):
overload = self.merge_default_value(actual, overload)
overload = evaluate_signature(overload, __globals__,
self.config.autodoc_type_aliases)

Expand All @@ -2131,6 +2152,16 @@ def format_signature(self, **kwargs: Any) -> str:

return "\n".join(sigs)

def merge_default_value(self, actual: Signature, overload: Signature) -> Signature:
"""Merge default values of actual implementation to the overload variants."""
parameters = list(overload.parameters.values())
for i, param in enumerate(parameters):
actual_param = actual.parameters.get(param.name)
if actual_param and param.default == '...':
parameters[i] = param.replace(default=actual_param.default)

return overload.replace(parameters=parameters)

def annotate_to_first_argument(self, func: Callable, typ: Type) -> None:
"""Annotate type hint to the first argument of function if needed."""
try:
Expand Down
4 changes: 2 additions & 2 deletions tests/roots/test-ext-autodoc/target/overload.py
Expand Up @@ -16,7 +16,7 @@ def sum(x: str, y: str = ...) -> str:
...


def sum(x, y):
def sum(x, y=None):
"""docstring"""
return x + y

Expand All @@ -36,7 +36,7 @@ def sum(self, x: "float", y: "float" = 0.0) -> "float":
def sum(self, x: str, y: str = ...) -> str:
...

def sum(self, x, y):
def sum(self, x, y=None):
"""docstring"""
return x + y

Expand Down
4 changes: 2 additions & 2 deletions tests/test_ext_autodoc.py
Expand Up @@ -2080,15 +2080,15 @@ def test_overload(app):
'',
' .. py:method:: Math.sum(x: int, y: int = 0) -> int',
' Math.sum(x: float, y: float = 0.0) -> float',
' Math.sum(x: str, y: str = ...) -> str',
' Math.sum(x: str, y: str = None) -> str',
' :module: target.overload',
'',
' docstring',
'',
'',
'.. py:function:: sum(x: int, y: int = 0) -> int',
' sum(x: float, y: float = 0.0) -> float',
' sum(x: str, y: str = ...) -> str',
' sum(x: str, y: str = None) -> str',
' :module: target.overload',
'',
' docstring',
Expand Down
4 changes: 2 additions & 2 deletions tests/test_ext_autodoc_configs.py
Expand Up @@ -647,13 +647,13 @@ def test_autodoc_typehints_none_for_overload(app):
' docstring',
'',
'',
' .. py:method:: Math.sum(x, y)',
' .. py:method:: Math.sum(x, y=None)',
' :module: target.overload',
'',
' docstring',
'',
'',
'.. py:function:: sum(x, y)',
'.. py:function:: sum(x, y=None)',
' :module: target.overload',
'',
' docstring',
Expand Down

0 comments on commit 596dfba

Please sign in to comment.