From d10fbe396e80660ff24f2f2d3330ec0c9b2bf9ac Mon Sep 17 00:00:00 2001 From: Lie Ryan Date: Mon, 21 Nov 2022 19:38:43 +1100 Subject: [PATCH] Fix read/write analysis of the left-hand side of an augmented assignment --- CHANGELOG.md | 3 +- rope/refactor/extract.py | 10 ++--- ropetest/refactor/extracttest.py | 64 +++++++++++++++++++++++++++++++- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00f94aac4..4741a06c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # **Upcoming release** -- #492, Feat: Global configuration support +- #492 Feat: Global configuration support +- #509 Fix read/write analysis of the left-hand side of an augmented assignment # Release 1.4.0 diff --git a/rope/refactor/extract.py b/rope/refactor/extract.py index ff762d730..fd5762920 100644 --- a/rope/refactor/extract.py +++ b/rope/refactor/extract.py @@ -856,12 +856,12 @@ def _Assign(self, node): def _AugAssign(self, node): ast.walk(node.value, self) - if isinstance(node.target, ast.Subscript): - target_id = node.target.value.id - else: + if isinstance(node.target, ast.Name): target_id = node.target.id - self._read_variable(target_id, node.target.lineno) - self._written_variable(target_id, node.target.lineno) + self._read_variable(target_id, node.target.lineno) + self._written_variable(target_id, node.target.lineno) + else: + ast.walk(node.target, self) def _ClassDef(self, node): self._written_variable(node.name, node.lineno) diff --git a/ropetest/refactor/extracttest.py b/ropetest/refactor/extracttest.py index 69a930bbc..8e825b785 100644 --- a/ropetest/refactor/extracttest.py +++ b/ropetest/refactor/extracttest.py @@ -1762,7 +1762,69 @@ def g(): """) self.assertEqual(expected, refactored) - def test_extract_method_and_augmentedj_assignment_in_try_block(self): + def test_extract_method_and_augmented_assignment_nested_1(self): + code = dedent("""\ + def f(): + my_var = [[0], [1], [2]] + my_var[0][0] += 1 + print(1) + """) + start, end = self._convert_line_range_to_offset(code, 4, 4) + refactored = self.do_extract_method(code, start, end, "g") + expected = dedent("""\ + def f(): + my_var = [[0], [1], [2]] + my_var[0][0] += 1 + g() + + def g(): + print(1) + """) + self.assertEqual(expected, refactored) + + def test_extract_method_and_augmented_assignment_nested_2(self): + code = dedent("""\ + def f(): + my_var = [[0], [1], [2]] + my_var[0][0] += 1 + print(my_var) + """) + start, end = self._convert_line_range_to_offset(code, 3, 3) + refactored = self.do_extract_method(code, start, end, "g") + expected = dedent("""\ + def f(): + my_var = [[0], [1], [2]] + g(my_var) + print(my_var) + + def g(my_var): + my_var[0][0] += 1 + """) + self.assertEqual(expected, refactored) + + def test_extract_method_and_augmented_assignment_var_to_read_in_lhs(self): + code = dedent("""\ + def f(): + var_to_read = 0 + my_var = [0, 1, 2] + my_var[var_to_read] += 1 + print(my_var) + """) + start, end = self._convert_line_range_to_offset(code, 4, 4) + refactored = self.do_extract_method(code, start, end, "g") + expected = dedent("""\ + def f(): + var_to_read = 0 + my_var = [0, 1, 2] + g(my_var, var_to_read) + print(my_var) + + def g(my_var, var_to_read): + my_var[var_to_read] += 1 + """) + self.assertEqual(expected, refactored) + + def test_extract_method_and_augmented_assignment_in_try_block(self): code = dedent("""\ def f(): any_subscriptable = [0]