https://github.com/python-rope/rope/pull/333 From a63ae26035c5493dc8b7c3bf6a70fc05dba2be98 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Sun, 14 Mar 2021 10:17:47 -0400 Subject: [PATCH 1/3] Fix test expectations for Python 3.9 AST changes Fixes the following two tests under Python 3.9: FAILED ropetest/refactor/patchedasttest.py::PatchedASTTest::test_ext_slice_node - AssertionError: Node cannot be found FAILED ropetest/refactor/patchedasttest.py::PatchedASTTest::test_simple_subscript - AssertionError: False is not true : Expected but was The ast module in Python 3.9 has some API changes. Quoting [1]: Simplified AST for subscription. Simple indices will be represented by their value, extended slices will be represented as tuples. Index(value) will return a value itself, ExtSlice(slices) will return Tuple(slices, Load()). (Contributed by Serhiy Storchaka in bpo-34822.) [1] https://docs.python.org/3/whatsnew/3.9.html#changes-in-the-python-api --- ropetest/refactor/patchedasttest.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ropetest/refactor/patchedasttest.py b/ropetest/refactor/patchedasttest.py index 04df3752..74a9d9a6 100644 --- a/ropetest/refactor/patchedasttest.py +++ b/ropetest/refactor/patchedasttest.py @@ -838,8 +838,12 @@ class PatchedASTTest(unittest.TestCase): source = 'x = xs[0,:]\n' ast_frag = patchedast.get_patched_ast(source, True) checker = _ResultChecker(self, ast_frag) - checker.check_region('ExtSlice', 7, len(source) - 2) - checker.check_children('ExtSlice', ['Index', '', ',', '', 'Slice']) + if sys.version_info >= (3, 9): + checker.check_region('Tuple', 7, len(source) - 2) + checker.check_children('Tuple', ['Num', '', ',', '', 'Slice']) + else: + checker.check_region('ExtSlice', 7, len(source) - 2) + checker.check_children('ExtSlice', ['Index', '', ',', '', 'Slice']) def test_simple_module_node(self): source = 'pass\n' @@ -933,9 +937,13 @@ class PatchedASTTest(unittest.TestCase): source = 'a[1]\n' ast_frag = patchedast.get_patched_ast(source, True) checker = _ResultChecker(self, ast_frag) - checker.check_children( - 'Subscript', ['Name', '', '[', '', 'Index', '', ']']) - checker.check_children('Index', ['Num']) + if sys.version_info >= (3, 9): + checker.check_children( + 'Subscript', ['Name', '', '[', '', 'Num', '', ']']) + else: + checker.check_children( + 'Subscript', ['Name', '', '[', '', 'Index', '', ']']) + checker.check_children('Index', ['Num']) def test_tuple_node(self): source = '(1, 2)\n' -- 2.26.2 From 02284e4151c2b1d549a64175ef0e3212b7737c56 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Sun, 14 Mar 2021 10:54:48 -0400 Subject: [PATCH 2/3] Handle AST.expr in _Subscript() The ast module in Python 3.9 has some API changes. Quoting [1]: Simplified AST for subscription. Simple indices will be represented by their value, extended slices will be represented as tuples. Index(value) will return a value itself, ExtSlice(slices) will return Tuple(slices, Load()). (Contributed by Serhiy Storchaka in bpo-34822.) [1] https://docs.python.org/3/whatsnew/3.9.html#changes-in-the-python-api isinstance(thing, ast.Index) always return false in Python >= 3.9, so we need to handle... whatever the value is now. ast.expr catches 20 of the remaining 24 failures. The remaining 4 are resolved in the next patch. Fixes: #299 --- rope/base/evaluate.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rope/base/evaluate.py b/rope/base/evaluate.py index 610d34e0..4634981a 100644 --- a/rope/base/evaluate.py +++ b/rope/base/evaluate.py @@ -307,6 +307,9 @@ class StatementEvaluator(object): elif isinstance(node.slice, ast.Slice): self._call_function(node.value, '__getitem__', [node.slice]) + elif isinstance(node.slice, ast.expr): + self._call_function(node.value, '__getitem__', + [node.value]) def _Slice(self, node): self.result = self._get_builtin_name('slice') -- 2.26.2 From 46a3403a06aaadf9d17f87b38300c4e3febe47c5 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Fri, 19 Mar 2021 18:41:53 -0400 Subject: [PATCH 3/3] Handle AST.expr in static object analysis The ast module in Python 3.9 has some API changes. Quoting [1]: Simplified AST for subscription. Simple indices will be represented by their value, extended slices will be represented as tuples. Index(value) will return a value itself, ExtSlice(slices) will return Tuple(slices, Load()). (Contributed by Serhiy Storchaka in bpo-34822.) [1] https://docs.python.org/3/whatsnew/3.9.html#changes-in-the-python-api This fixes the remaining 4 failures under Python 3.9. FAILED ropetest/advanced_oi_test.py::NewStaticOITest::test_static_oi_for_dicts_depending_on_append_function FAILED ropetest/advanced_oi_test.py::NewStaticOITest::test_static_oi_for_dicts_depending_on_for_loops FAILED ropetest/advanced_oi_test.py::NewStaticOITest::test_static_oi_for_dicts_depending_on_update FAILED ropetest/advanced_oi_test.py::NewStaticOITest::test_static_oi_for_lists_per_object_for_set_item Fixes: #299 --- rope/base/oi/soa.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rope/base/oi/soa.py b/rope/base/oi/soa.py index 8ef17aee..20ab567e 100644 --- a/rope/base/oi/soa.py +++ b/rope/base/oi/soa.py @@ -126,7 +126,7 @@ class SOAVisitor(object): for subscript, levels in nodes: instance = evaluate.eval_node(self.scope, subscript.value) args_pynames = [evaluate.eval_node(self.scope, - subscript.slice.value)] + subscript.slice)] value = rope.base.oi.soi._infer_assignment( rope.base.pynames.AssignmentValue(node.value, levels, type_hint=type_hint), @@ -149,5 +149,5 @@ class _SOAAssignVisitor(astutils._NodeNameCollector): def _added(self, node, levels): if isinstance(node, rope.base.ast.Subscript) and \ - isinstance(node.slice, rope.base.ast.Index): + isinstance(node.slice, (rope.base.ast.Index, rope.base.ast.expr)): self.nodes.append((node, levels)) -- 2.26.2