diff --git a/parentheses.patch b/parentheses.patch new file mode 100644 index 0000000..289b273 --- /dev/null +++ b/parentheses.patch @@ -0,0 +1,229 @@ +From 8f3af04c64c39b13f65c58a14f09433661d63a79 Mon Sep 17 00:00:00 2001 +From: eff-kay +Date: Fri, 18 Aug 2023 19:39:00 -0400 +Subject: [PATCH] fix extra parenthsis addition + +--- + lib/astunparse/unparser.py | 66 +++++++++++++++++++++++++++----------- + test_requirements.txt | 2 ++ + tests/common.py | 3 +- + tests/test_dump.py | 22 ++++++------- + tests/test_unparse.py | 14 +++++++- + tox.ini | 2 +- + 6 files changed, 76 insertions(+), 33 deletions(-) + +Index: astunparse-1.6.3/lib/astunparse/unparser.py +=================================================================== +--- astunparse-1.6.3.orig/lib/astunparse/unparser.py ++++ astunparse-1.6.3/lib/astunparse/unparser.py +@@ -56,14 +56,17 @@ class Unparser: + "Decrease the indentation level." + self._indent -= 1 + +- def dispatch(self, tree): ++ def dispatch(self, tree, parent_t=None): + "Dispatcher function, dispatching tree type T to method _T." + if isinstance(tree, list): + for t in tree: + self.dispatch(t) + return + meth = getattr(self, "_"+tree.__class__.__name__) +- meth(tree) ++ if parent_t: ++ meth(tree, parent_t=parent_t) ++ else: ++ meth(tree) + + + ############### Unparsing methods ###################### +@@ -517,7 +520,8 @@ class Unparser: + meth(t.format_spec, write) + write("}") + +- def _Name(self, t): ++ def _Name(self, t, parent_t=None): ++ + self.write(t.id) + + def _NameConstant(self, t): +@@ -535,7 +539,7 @@ class Unparser: + else: + self.write(repr(value)) + +- def _Constant(self, t): ++ def _Constant(self, t, parent_t=None): + value = t.value + if isinstance(value, tuple): + self.write("(") +@@ -659,8 +663,12 @@ class Unparser: + self.write(")") + + unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"} +- def _UnaryOp(self, t): +- self.write("(") ++ def _UnaryOp(self, t, parent_t=None): ++ if isinstance(parent_t, ast.Call): ++ pass ++ else: ++ self.write("(") ++ + self.write(self.unop[t.op.__class__.__name__]) + self.write(" ") + if six.PY2 and isinstance(t.op, ast.USub) and isinstance(t.operand, ast.Num): +@@ -674,34 +682,57 @@ class Unparser: + self.write(")") + else: + self.dispatch(t.operand) +- self.write(")") ++ ++ if isinstance(parent_t, ast.Call): ++ pass ++ else: ++ self.write(")") + + binop = { "Add":"+", "Sub":"-", "Mult":"*", "MatMult":"@", "Div":"/", "Mod":"%", + "LShift":"<<", "RShift":">>", "BitOr":"|", "BitXor":"^", "BitAnd":"&", + "FloorDiv":"//", "Pow": "**"} +- def _BinOp(self, t): +- self.write("(") ++ def _BinOp(self, t, parent_t=None): ++ if isinstance(parent_t, ast.Call): ++ pass ++ else: ++ self.write("(") + self.dispatch(t.left) + self.write(" " + self.binop[t.op.__class__.__name__] + " ") + self.dispatch(t.right) +- self.write(")") ++ if isinstance(parent_t, ast.Call): ++ pass ++ else: ++ self.write(")") + + cmpops = {"Eq":"==", "NotEq":"!=", "Lt":"<", "LtE":"<=", "Gt":">", "GtE":">=", + "Is":"is", "IsNot":"is not", "In":"in", "NotIn":"not in"} +- def _Compare(self, t): +- self.write("(") ++ def _Compare(self, t, parent_t=None): ++ if isinstance(parent_t, ast.Call): ++ pass ++ else: ++ self.write("(") + self.dispatch(t.left) + for o, e in zip(t.ops, t.comparators): + self.write(" " + self.cmpops[o.__class__.__name__] + " ") + self.dispatch(e) +- self.write(")") ++ if isinstance(parent_t, ast.Call): ++ pass ++ else: ++ self.write(")") + + boolops = {ast.And: 'and', ast.Or: 'or'} +- def _BoolOp(self, t): +- self.write("(") ++ def _BoolOp(self, t, parent_t=None): ++ if isinstance(parent_t, ast.Call): ++ pass ++ else: ++ self.write("(") ++ + s = " %s " % self.boolops[t.op.__class__] + interleave(lambda: self.write(s), self.dispatch, t.values) +- self.write(")") ++ if isinstance(parent_t, ast.Call): ++ pass ++ else: ++ self.write(")") + + def _Attribute(self,t): + self.dispatch(t.value) +@@ -720,22 +751,22 @@ class Unparser: + for e in t.args: + if comma: self.write(", ") + else: comma = True +- self.dispatch(e) ++ self.dispatch(e, parent_t=t) + for e in t.keywords: + if comma: self.write(", ") + else: comma = True +- self.dispatch(e) ++ self.dispatch(e, parent_t=t) + if sys.version_info[:2] < (3, 5): + if t.starargs: + if comma: self.write(", ") + else: comma = True + self.write("*") +- self.dispatch(t.starargs) ++ self.dispatch(t.starargs, parent_t=t) + if t.kwargs: + if comma: self.write(", ") + else: comma = True + self.write("**") +- self.dispatch(t.kwargs) ++ self.dispatch(t.kwargs, parent_t=t) + self.write(")") + + def _Subscript(self, t): +Index: astunparse-1.6.3/test_requirements.txt +=================================================================== +--- astunparse-1.6.3.orig/test_requirements.txt ++++ astunparse-1.6.3/test_requirements.txt +@@ -1,2 +1,4 @@ + coverage == 3.7.1 ++flake8 ++tox + -rrequirements.txt +Index: astunparse-1.6.3/tests/common.py +=================================================================== +--- astunparse-1.6.3.orig/tests/common.py ++++ astunparse-1.6.3/tests/common.py +@@ -262,7 +262,6 @@ class AstunparseCommonTestCase: + self.check_roundtrip("a is b is c is not d") + + def test_function_arguments(self): +- self.check_roundtrip("def f(): pass") + self.check_roundtrip("def f(a): pass") + self.check_roundtrip("def f(b = 2): pass") + self.check_roundtrip("def f(a, b): pass") +@@ -394,7 +393,7 @@ class AstunparseCommonTestCase: + self.check_roundtrip("a: int = None") + self.check_roundtrip("some_list: List[int]") + self.check_roundtrip("some_list: List[int] = []") +- self.check_roundtrip("t: Tuple[int, ...] = (1, 2, 3)") ++ self.check_roundtrip("t: Tuple[(int, ...)] = (1, 2, 3)") + self.check_roundtrip("(a): int") + self.check_roundtrip("(a): int = 0") + self.check_roundtrip("(a): int = None") +Index: astunparse-1.6.3/tests/test_dump.py +=================================================================== +--- astunparse-1.6.3.orig/tests/test_dump.py ++++ astunparse-1.6.3/tests/test_dump.py +@@ -9,16 +9,16 @@ else: + import astunparse + from tests.common import AstunparseCommonTestCase + +-class DumpTestCase(AstunparseCommonTestCase, unittest.TestCase): ++# class DumpTestCase(AstunparseCommonTestCase, unittest.TestCase): + +- def assertASTEqual(self, dump1, dump2): +- # undo the pretty-printing +- dump1 = re.sub(r"(?<=[\(\[])\n\s+", "", dump1) +- dump1 = re.sub(r"\n\s+", " ", dump1) +- self.assertEqual(dump1, dump2) ++# def assertASTEqual(self, dump1, dump2): ++# # undo the pretty-printing ++# dump1 = re.sub(r"(?<=[\(\[])\n\s+", "", dump1) ++# dump1 = re.sub(r"\n\s+", " ", dump1) ++# self.assertEqual(dump1, dump2) + +- def check_roundtrip(self, code1, filename="internal", mode="exec"): +- ast_ = compile(str(code1), filename, mode, ast.PyCF_ONLY_AST) +- dump1 = astunparse.dump(ast_) +- dump2 = ast.dump(ast_) +- self.assertASTEqual(dump1, dump2) ++# def check_roundtrip(self, code1, filename="internal", mode="exec"): ++# ast_ = compile(str(code1), filename, mode, ast.PyCF_ONLY_AST) ++# dump1 = astunparse.dump(ast_) ++# dump2 = ast.dump(ast_) ++# self.assertASTEqual(dump1, dump2) diff --git a/python-astunparse.changes b/python-astunparse.changes index 2b4e070..a919388 100644 --- a/python-astunparse.changes +++ b/python-astunparse.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Mon Dec 2 15:15:22 UTC 2024 - Markéta Machová + +- Add patch parentheses.patch to fix tests on Python 3.13 + ------------------------------------------------------------------- Thu Nov 21 10:08:41 UTC 2024 - Dirk Müller diff --git a/python-astunparse.spec b/python-astunparse.spec index ad240b0..18eca0c 100644 --- a/python-astunparse.spec +++ b/python-astunparse.spec @@ -17,7 +17,6 @@ %{?sle15_python_module_pythons} -%global skip_python313 1 Name: python-astunparse Version: 1.6.3 Release: 0 @@ -30,6 +29,9 @@ Source: https://files.pythonhosted.org/packages/source/a/astunparse/astu Patch0: astunparse-pr57-py39.patch # https://github.com/simonpercivall/astunparse/pull/59 Patch1: fix-formatted-value.patch +# https://github.com/simonpercivall/astunparse/pull/70 +# it is a bit overpowered, but it fixes the issue +Patch2: parentheses.patch BuildRequires: %{python_module pip} BuildRequires: %{python_module setuptools} BuildRequires: %{python_module six >= 1.6.1}