Merge pull request #8695 from tk0miya/8514_default_value_of_overloads

Close #8514: autodoc: Default values of overloads are taken from actual implementation
This commit is contained in:
Takeshi KOMIYA 2021-01-18 00:15:56 +09:00 committed by GitHub
commit 596dfba841
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 6 deletions

View File

@ -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()`

View File

@ -1355,8 +1355,11 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
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)
@ -1365,6 +1368,16 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
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:
@ -2117,8 +2130,16 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
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)
@ -2131,6 +2152,16 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
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:

View File

@ -16,7 +16,7 @@ def sum(x: str, y: str = ...) -> str:
...
def sum(x, y):
def sum(x, y=None):
"""docstring"""
return x + y
@ -36,7 +36,7 @@ class Math:
def sum(self, x: str, y: str = ...) -> str:
...
def sum(self, x, y):
def sum(self, x, y=None):
"""docstring"""
return x + y

View File

@ -2080,7 +2080,7 @@ 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',
@ -2088,7 +2088,7 @@ def test_overload(app):
'',
'.. 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',

View File

@ -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',