Skip to content

Commit

Permalink
Fix sphinx-doc#8693: autodoc: Default values for overloads are render…
Browse files Browse the repository at this point in the history
…ed 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.
  • Loading branch information
tk0miya committed Jan 16, 2021
1 parent 7c340e1 commit ebaaa37
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -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 (-,
Expand Down
14 changes: 12 additions & 2 deletions sphinx/util/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,16 @@ 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 __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
Expand Down Expand Up @@ -704,7 +714,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,
Expand All @@ -714,7 +724,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,
Expand Down
12 changes: 6 additions & 6 deletions tests/roots/test-ext-autodoc/target/overload.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@


@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:
...


Expand All @@ -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):
Expand Down
12 changes: 6 additions & 6 deletions tests/test_ext_autodoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down

0 comments on commit ebaaa37

Please sign in to comment.