diff --git a/Lib/ast.py b/Lib/ast.py index 7a43581c0e6..1de37b9567e 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -1190,10 +1190,10 @@ class _Unparser(NodeVisitor): unop = {"Invert": "~", "Not": "not", "UAdd": "+", "USub": "-"} unop_precedence = { - "~": _Precedence.FACTOR, "not": _Precedence.NOT, + "~": _Precedence.FACTOR, "+": _Precedence.FACTOR, - "-": _Precedence.FACTOR + "-": _Precedence.FACTOR, } def visit_UnaryOp(self, node): @@ -1201,7 +1201,10 @@ class _Unparser(NodeVisitor): operator_precedence = self.unop_precedence[operator] with self.require_parens(operator_precedence, node): self.write(operator) - self.write(" ") + # factor prefixes (+, -, ~) shouldn't be seperated + # from the value they belong, (e.g: +1 instead of + 1) + if operator_precedence is not _Precedence.FACTOR: + self.write(" ") self.set_precedence(operator_precedence, node.operand) self.traverse(node.operand) diff --git a/Lib/test/test_unparse.py b/Lib/test/test_unparse.py index 2be44b246aa..1393bcce741 100644 --- a/Lib/test/test_unparse.py +++ b/Lib/test/test_unparse.py @@ -347,7 +347,7 @@ class CosmeticTestCase(ASTTestCase): self.check_src_roundtrip("(1 + 2) / 3") self.check_src_roundtrip("(1 + 2) * 3 + 4 * (5 + 2)") self.check_src_roundtrip("(1 + 2) * 3 + 4 * (5 + 2) ** 2") - self.check_src_roundtrip("~ x") + self.check_src_roundtrip("~x") self.check_src_roundtrip("x and y") self.check_src_roundtrip("x and y and z") self.check_src_roundtrip("x and (y and x)") @@ -401,6 +401,12 @@ class CosmeticTestCase(ASTTestCase): self.check_ast_roundtrip(src) self.check_src_dont_roundtrip(src) + def test_unary_op_factor(self): + for prefix in ("+", "-", "~"): + self.check_src_roundtrip(f"{prefix}1") + for prefix in ("not",): + self.check_src_roundtrip(f"{prefix} 1") + class DirectoryTestCase(ASTTestCase): """Test roundtrip behaviour on all files in Lib and Lib/test."""