summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2022-06-17 03:02:48 +0900
committerGitHub <noreply@github.com>2022-06-17 03:02:48 +0900
commit103117541823d297560ee003b45cab1ddeab804e (patch)
tree0cc0e9088d835a292aaa4c4dae641c7bf5727070
parent4d7558e968d74f73e11c5460fe095b51a5a9f172 (diff)
parentbed8e94cfc6fdd619d7141f1c918060fca1ae732 (diff)
downloadsphinx-git-103117541823d297560ee003b45cab1ddeab804e.tar.gz
Merge pull request #10551 from AA-Turner/fix-extra-whitespace
Remove extra space from the unparser
-rw-r--r--CHANGES3
-rw-r--r--sphinx/pycode/ast.py9
-rw-r--r--tests/test_domain_py.py27
-rw-r--r--tests/test_pycode_ast.py10
4 files changed, 43 insertions, 6 deletions
diff --git a/CHANGES b/CHANGES
index 5ab2a694d..4fb96d00b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -16,6 +16,9 @@ Features added
Bugs fixed
----------
+* #10031: py domain: Fix spurious whitespace in unparsing various operators (``+``,
+ ``-``, ``~``, and ``**``). Patch by Adam Turner.
+
Testing
--------
diff --git a/sphinx/pycode/ast.py b/sphinx/pycode/ast.py
index 755116475..d4646f0b7 100644
--- a/sphinx/pycode/ast.py
+++ b/sphinx/pycode/ast.py
@@ -141,6 +141,9 @@ class _UnparseVisitor(ast.NodeVisitor):
return "%s.%s" % (self.visit(node.value), node.attr)
def visit_BinOp(self, node: ast.BinOp) -> str:
+ # Special case ``**`` to not have surrounding spaces.
+ if isinstance(node.op, ast.Pow):
+ return "".join(map(self.visit, (node.left, node.op, node.right)))
return " ".join(self.visit(e) for e in [node.left, node.op, node.right])
def visit_BoolOp(self, node: ast.BoolOp) -> str:
@@ -202,7 +205,11 @@ class _UnparseVisitor(ast.NodeVisitor):
return "%s[%s]" % (self.visit(node.value), self.visit(node.slice))
def visit_UnaryOp(self, node: ast.UnaryOp) -> str:
- return "%s %s" % (self.visit(node.op), self.visit(node.operand))
+ # UnaryOp is one of {UAdd, USub, Invert, Not}, which refer to ``+x``,
+ # ``-x``, ``~x``, and ``not x``. Only Not needs a space.
+ if isinstance(node.op, ast.Not):
+ return "%s %s" % (self.visit(node.op), self.visit(node.operand))
+ return "%s%s" % (self.visit(node.op), self.visit(node.operand))
def visit_Tuple(self, node: ast.Tuple) -> str:
if len(node.elts) == 0:
diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py
index 014067e84..baad0c2da 100644
--- a/tests/test_domain_py.py
+++ b/tests/test_domain_py.py
@@ -452,6 +452,33 @@ def test_pyfunction_signature_full(app):
[desc_sig_name, pending_xref, "str"])])])
+def test_pyfunction_with_unary_operators(app):
+ text = ".. py:function:: menu(egg=+1, bacon=-1, sausage=~1, spam=not spam)"
+ doctree = restructuredtext.parse(app, text)
+ assert_node(doctree[1][0][1],
+ [desc_parameterlist, ([desc_parameter, ([desc_sig_name, "egg"],
+ [desc_sig_operator, "="],
+ [nodes.inline, "+1"])],
+ [desc_parameter, ([desc_sig_name, "bacon"],
+ [desc_sig_operator, "="],
+ [nodes.inline, "-1"])],
+ [desc_parameter, ([desc_sig_name, "sausage"],
+ [desc_sig_operator, "="],
+ [nodes.inline, "~1"])],
+ [desc_parameter, ([desc_sig_name, "spam"],
+ [desc_sig_operator, "="],
+ [nodes.inline, "not spam"])])])
+
+
+def test_pyfunction_with_binary_operators(app):
+ text = ".. py:function:: menu(spam=2**64)"
+ doctree = restructuredtext.parse(app, text)
+ assert_node(doctree[1][0][1],
+ [desc_parameterlist, ([desc_parameter, ([desc_sig_name, "spam"],
+ [desc_sig_operator, "="],
+ [nodes.inline, "2**64"])])])
+
+
@pytest.mark.skipif(sys.version_info < (3, 8), reason='python 3.8+ is required.')
def test_pyfunction_signature_full_py38(app):
# case: separator at head
diff --git a/tests/test_pycode_ast.py b/tests/test_pycode_ast.py
index 6143105eb..31018baca 100644
--- a/tests/test_pycode_ast.py
+++ b/tests/test_pycode_ast.py
@@ -25,7 +25,7 @@ from sphinx.pycode import ast
("...", "..."), # Ellipsis
("a // b", "a // b"), # FloorDiv
("Tuple[int, int]", "Tuple[int, int]"), # Index, Subscript
- ("~ 1", "~ 1"), # Invert
+ ("~1", "~1"), # Invert
("lambda x, y: x + y",
"lambda x, y: ..."), # Lambda
("[1, 2, 3]", "[1, 2, 3]"), # List
@@ -37,14 +37,14 @@ from sphinx.pycode import ast
("1234", "1234"), # Num
("not a", "not a"), # Not
("a or b", "a or b"), # Or
- ("a ** b", "a ** b"), # Pow
+ ("a**b", "a**b"), # Pow
("a >> b", "a >> b"), # RShift
("{1, 2, 3}", "{1, 2, 3}"), # Set
("a - b", "a - b"), # Sub
("'str'", "'str'"), # Str
- ("+ a", "+ a"), # UAdd
- ("- 1", "- 1"), # UnaryOp
- ("- a", "- a"), # USub
+ ("+a", "+a"), # UAdd
+ ("-1", "-1"), # UnaryOp
+ ("-a", "-a"), # USub
("(1, 2, 3)", "(1, 2, 3)"), # Tuple
("()", "()"), # Tuple (empty)
("(1,)", "(1,)"), # Tuple (single item)