summaryrefslogtreecommitdiff
blob: edb5304841db031dad11d7201ec13dd9b9b0f923 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
https://github.com/python-rope/rope/pull/333

From a63ae26035c5493dc8b7c3bf6a70fc05dba2be98 Mon Sep 17 00:00:00 2001
From: Matt Turner <mattst88@gmail.com>
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 <ExtSlice> cannot be found
FAILED ropetest/refactor/patchedasttest.py::PatchedASTTest::test_simple_subscript - AssertionError: False is not true : Expected <Index> but was <Constant>

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 <mattst88@gmail.com>
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 <mattst88@gmail.com>
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