mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #9799 from tk0miya/9781_autodoc_preserve_hexadecimal
Fix #9781: autodoc_preserve_defaults does not support hexadecimal
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -71,6 +71,8 @@ Bugs fixed
|
|||||||
* #9756: autodoc: Crashed if classmethod does not have __func__ attribute
|
* #9756: autodoc: Crashed if classmethod does not have __func__ attribute
|
||||||
* #9757: autodoc: :confval:`autodoc_inherit_docstrings` does not effect to
|
* #9757: autodoc: :confval:`autodoc_inherit_docstrings` does not effect to
|
||||||
overriden classmethods
|
overriden classmethods
|
||||||
|
* #9781: autodoc: :confval:`autodoc_preserve_defaults` does not support
|
||||||
|
hexadecimal numeric
|
||||||
* #9630: autosummary: Failed to build summary table if :confval:`primary_domain`
|
* #9630: autosummary: Failed to build summary table if :confval:`primary_domain`
|
||||||
is not 'py'
|
is not 'py'
|
||||||
* #9670: html: Fix download file with special characters
|
* #9670: html: Fix download file with special characters
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
|
|
||||||
import ast
|
import ast
|
||||||
import inspect
|
import inspect
|
||||||
from typing import Any, Dict
|
import sys
|
||||||
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
@@ -49,11 +50,32 @@ def get_function_def(obj: Any) -> ast.FunctionDef:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_default_value(lines: List[str], position: ast.AST) -> Optional[str]:
|
||||||
|
try:
|
||||||
|
if sys.version_info < (3, 8): # only for py38+
|
||||||
|
return None
|
||||||
|
elif position.lineno == position.end_lineno:
|
||||||
|
line = lines[position.lineno - 1]
|
||||||
|
return line[position.col_offset:position.end_col_offset]
|
||||||
|
else:
|
||||||
|
# multiline value is not supported now
|
||||||
|
return None
|
||||||
|
except (AttributeError, IndexError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def update_defvalue(app: Sphinx, obj: Any, bound_method: bool) -> None:
|
def update_defvalue(app: Sphinx, obj: Any, bound_method: bool) -> None:
|
||||||
"""Update defvalue info of *obj* using type_comments."""
|
"""Update defvalue info of *obj* using type_comments."""
|
||||||
if not app.config.autodoc_preserve_defaults:
|
if not app.config.autodoc_preserve_defaults:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
lines = inspect.getsource(obj).splitlines()
|
||||||
|
if lines[0].startswith((' ', r'\t')):
|
||||||
|
lines.insert(0, '') # insert a dummy line to follow what get_function_def() does.
|
||||||
|
except OSError:
|
||||||
|
lines = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
function = get_function_def(obj)
|
function = get_function_def(obj)
|
||||||
if function.args.defaults or function.args.kw_defaults:
|
if function.args.defaults or function.args.kw_defaults:
|
||||||
@@ -64,11 +86,17 @@ def update_defvalue(app: Sphinx, obj: Any, bound_method: bool) -> None:
|
|||||||
for i, param in enumerate(parameters):
|
for i, param in enumerate(parameters):
|
||||||
if param.default is not param.empty:
|
if param.default is not param.empty:
|
||||||
if param.kind in (param.POSITIONAL_ONLY, param.POSITIONAL_OR_KEYWORD):
|
if param.kind in (param.POSITIONAL_ONLY, param.POSITIONAL_OR_KEYWORD):
|
||||||
value = DefaultValue(ast_unparse(defaults.pop(0))) # type: ignore
|
default = defaults.pop(0)
|
||||||
parameters[i] = param.replace(default=value)
|
value = get_default_value(lines, default)
|
||||||
|
if value is None:
|
||||||
|
value = ast_unparse(default) # type: ignore
|
||||||
|
parameters[i] = param.replace(default=DefaultValue(value))
|
||||||
else:
|
else:
|
||||||
value = DefaultValue(ast_unparse(kw_defaults.pop(0))) # type: ignore
|
default = kw_defaults.pop(0)
|
||||||
parameters[i] = param.replace(default=value)
|
value = get_default_value(lines, default)
|
||||||
|
if value is None:
|
||||||
|
value = ast_unparse(default) # type: ignore
|
||||||
|
parameters[i] = param.replace(default=DefaultValue(value))
|
||||||
sig = sig.replace(parameters=parameters)
|
sig = sig.replace(parameters=parameters)
|
||||||
obj.__signature__ = sig
|
obj.__signature__ = sig
|
||||||
except (AttributeError, TypeError):
|
except (AttributeError, TypeError):
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ SENTINEL = object()
|
|||||||
|
|
||||||
def foo(name: str = CONSTANT,
|
def foo(name: str = CONSTANT,
|
||||||
sentinel: Any = SENTINEL,
|
sentinel: Any = SENTINEL,
|
||||||
now: datetime = datetime.now()) -> None:
|
now: datetime = datetime.now(),
|
||||||
|
color: int = 0xFFFFFF) -> None:
|
||||||
"""docstring"""
|
"""docstring"""
|
||||||
|
|
||||||
|
|
||||||
@@ -15,5 +16,5 @@ class Class:
|
|||||||
"""docstring"""
|
"""docstring"""
|
||||||
|
|
||||||
def meth(self, name: str = CONSTANT, sentinel: Any = SENTINEL,
|
def meth(self, name: str = CONSTANT, sentinel: Any = SENTINEL,
|
||||||
now: datetime = datetime.now()) -> None:
|
now: datetime = datetime.now(), color: int = 0xFFFFFF) -> None:
|
||||||
"""docstring"""
|
"""docstring"""
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from .test_ext_autodoc import do_autodoc
|
from .test_ext_autodoc import do_autodoc
|
||||||
@@ -16,6 +18,11 @@ from .test_ext_autodoc import do_autodoc
|
|||||||
@pytest.mark.sphinx('html', testroot='ext-autodoc',
|
@pytest.mark.sphinx('html', testroot='ext-autodoc',
|
||||||
confoverrides={'autodoc_preserve_defaults': True})
|
confoverrides={'autodoc_preserve_defaults': True})
|
||||||
def test_preserve_defaults(app):
|
def test_preserve_defaults(app):
|
||||||
|
if sys.version_info < (3, 8):
|
||||||
|
color = "16777215"
|
||||||
|
else:
|
||||||
|
color = "0xFFFFFF"
|
||||||
|
|
||||||
options = {"members": None}
|
options = {"members": None}
|
||||||
actual = do_autodoc(app, 'module', 'target.preserve_defaults', options)
|
actual = do_autodoc(app, 'module', 'target.preserve_defaults', options)
|
||||||
assert list(actual) == [
|
assert list(actual) == [
|
||||||
@@ -30,14 +37,14 @@ def test_preserve_defaults(app):
|
|||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
' .. py:method:: Class.meth(name: str = CONSTANT, sentinel: Any = SENTINEL, '
|
' .. py:method:: Class.meth(name: str = CONSTANT, sentinel: Any = SENTINEL, '
|
||||||
'now: datetime.datetime = datetime.now()) -> None',
|
'now: datetime.datetime = datetime.now(), color: int = %s) -> None' % color,
|
||||||
' :module: target.preserve_defaults',
|
' :module: target.preserve_defaults',
|
||||||
'',
|
'',
|
||||||
' docstring',
|
' docstring',
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
'.. py:function:: foo(name: str = CONSTANT, sentinel: Any = SENTINEL, now: '
|
'.. py:function:: foo(name: str = CONSTANT, sentinel: Any = SENTINEL, now: '
|
||||||
'datetime.datetime = datetime.now()) -> None',
|
'datetime.datetime = datetime.now(), color: int = %s) -> None' % color,
|
||||||
' :module: target.preserve_defaults',
|
' :module: target.preserve_defaults',
|
||||||
'',
|
'',
|
||||||
' docstring',
|
' docstring',
|
||||||
|
|||||||
Reference in New Issue
Block a user