summaryrefslogtreecommitdiff
path: root/sphinx/pycode
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2020-10-04 01:45:47 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2020-10-05 01:08:14 +0900
commit0b32e72635f6e117824b5cba3b8b38254a6a2644 (patch)
treea8da5ca1e41df54b03cfedec4d7676d4bf9fa0ea /sphinx/pycode
parenta8abb9995f71b9bc02b6f83592751c779ae0f75a (diff)
downloadsphinx-git-0b32e72635f6e117824b5cba3b8b38254a6a2644.tar.gz
pycode: ast.unparse() construct number literals using source code
Developers can write number literals in several ways. For example, decimal (1234), hexadecimal (0x1234), octal decimal (0o1234) and so on. But, AST module don't mind how the numbers written in the code. As a result, ast.unparse() could not reproduce the original form of number literals. This allows to construct number literals as possible using original source code. Note: This is only available in Python 3.8+.
Diffstat (limited to 'sphinx/pycode')
-rw-r--r--sphinx/pycode/ast.py11
1 files changed, 9 insertions, 2 deletions
diff --git a/sphinx/pycode/ast.py b/sphinx/pycode/ast.py
index 2583448d5..17d78f4eb 100644
--- a/sphinx/pycode/ast.py
+++ b/sphinx/pycode/ast.py
@@ -58,17 +58,19 @@ def parse(code: str, mode: str = 'exec') -> "ast.AST":
return ast.parse(code, mode=mode)
-def unparse(node: Optional[ast.AST]) -> Optional[str]:
+def unparse(node: Optional[ast.AST], code: str = '') -> Optional[str]:
"""Unparse an AST to string."""
if node is None:
return None
elif isinstance(node, str):
return node
- return _UnparseVisitor().visit(node)
+ return _UnparseVisitor(code).visit(node)
# a greatly cut-down version of `ast._Unparser`
class _UnparseVisitor(ast.NodeVisitor):
+ def __init__(self, code: str = '') -> None:
+ self.code = code
def _visit_op(self, node: ast.AST) -> str:
return OPERATORS[node.__class__]
@@ -195,6 +197,11 @@ class _UnparseVisitor(ast.NodeVisitor):
def visit_Constant(self, node: ast.Constant) -> str:
if node.value is Ellipsis:
return "..."
+ elif isinstance(node.value, (int, float, complex)):
+ if self.code and sys.version_info > (3, 8):
+ return ast.get_source_segment(self.code, node)
+ else:
+ return repr(node.value)
else:
return repr(node.value)