Fix #8693: autodoc: Default values for overloads are rendered as string

The default values for overloaded functions are rendered as string
literal unexpectedly because autodoc extracts code snippets from
the source code, not actual value (ex. int, ellipsis, and so on).

This introduces a simple wrapper class; `DefaultValue` to render these
code snippets like actual values, not string literals.
This commit is contained in:
Takeshi KOMIYA 2021-01-17 01:50:31 +09:00
parent 7c340e1c1c
commit 425cd1af02
4 changed files with 28 additions and 14 deletions

View File

@ -45,6 +45,7 @@ Bugs fixed
* #8315: autodoc: Failed to resolve struct.Struct type annotation
* #8652: autodoc: All variable comments in the module are ignored if the module
contains invalid type comments
* #8693: autodoc: Default values for overloaded functions are rendered as string
* #8306: autosummary: mocked modules are documented as empty page when using
:recursive: option
* #8618: html: kbd role produces incorrect HTML when compound-key separators (-,

View File

@ -499,6 +499,19 @@ def is_builtin_class_method(obj: Any, attr_name: str) -> bool:
return getattr(builtins, name, None) is cls
class DefaultValue:
"""A simple wrapper for default value of the parameters of overload functions."""
def __init__(self, value: str) -> None:
self.value = value
def __eq__(self, other: object) -> bool:
return self.value == other
def __repr__(self) -> str:
return self.value
def _should_unwrap(subject: Callable) -> bool:
"""Check the function should be unwrapped on getting signature."""
if (safe_getattr(subject, '__globals__', None) and
@ -704,7 +717,7 @@ def signature_from_ast(node: ast.FunctionDef, code: str = '') -> inspect.Signatu
if defaults[i] is Parameter.empty:
default = Parameter.empty
else:
default = ast_unparse(defaults[i], code)
default = DefaultValue(ast_unparse(defaults[i], code))
annotation = ast_unparse(arg.annotation, code) or Parameter.empty
params.append(Parameter(arg.arg, Parameter.POSITIONAL_ONLY,
@ -714,7 +727,7 @@ def signature_from_ast(node: ast.FunctionDef, code: str = '') -> inspect.Signatu
if defaults[i + posonlyargs] is Parameter.empty:
default = Parameter.empty
else:
default = ast_unparse(defaults[i + posonlyargs], code)
default = DefaultValue(ast_unparse(defaults[i + posonlyargs], code))
annotation = ast_unparse(arg.annotation, code) or Parameter.empty
params.append(Parameter(arg.arg, Parameter.POSITIONAL_OR_KEYWORD,

View File

@ -2,17 +2,17 @@ from typing import Any, overload
@overload
def sum(x: int, y: int) -> int:
def sum(x: int, y: int = 0) -> int:
...
@overload
def sum(x: "float", y: "float") -> "float":
def sum(x: "float", y: "float" = 0.0) -> "float":
...
@overload
def sum(x: str, y: str) -> str:
def sum(x: str, y: str = ...) -> str:
...
@ -25,15 +25,15 @@ class Math:
"""docstring"""
@overload
def sum(self, x: int, y: int) -> int:
def sum(self, x: int, y: int = 0) -> int:
...
@overload
def sum(self, x: "float", y: "float") -> "float":
def sum(self, x: "float", y: "float" = 0.0) -> "float":
...
@overload
def sum(self, x: str, y: str) -> str:
def sum(self, x: str, y: str = ...) -> str:
...
def sum(self, x, y):

View File

@ -2078,17 +2078,17 @@ def test_overload(app):
' docstring',
'',
'',
' .. py:method:: Math.sum(x: int, y: int) -> int',
' Math.sum(x: float, y: float) -> float',
' Math.sum(x: str, y: str) -> str',
' .. 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',
' :module: target.overload',
'',
' docstring',
'',
'',
'.. py:function:: sum(x: int, y: int) -> int',
' sum(x: float, y: float) -> float',
' sum(x: str, y: str) -> str',
'.. py:function:: sum(x: int, y: int = 0) -> int',
' sum(x: float, y: float = 0.0) -> float',
' sum(x: str, y: str = ...) -> str',
' :module: target.overload',
'',
' docstring',