From 5fb5359ebdfe16faf6c9520b9181c3fc58431053 Mon Sep 17 00:00:00 2001 From: Lie Ryan Date: Wed, 14 Dec 2022 16:22:22 +1100 Subject: [PATCH 1/7] Fix #566. Add kwonlyargs to list of written arguments when extracting --- rope/refactor/extract.py | 2 ++ ropetest/refactor/extracttest.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/rope/refactor/extract.py b/rope/refactor/extract.py index 47628c75c..2771092fe 100644 --- a/rope/refactor/extract.py +++ b/rope/refactor/extract.py @@ -952,6 +952,8 @@ def _get_argnames(arguments): result.append(arguments.vararg.arg) if arguments.kwarg: result.append(arguments.kwarg.arg) + if arguments.kwonlyargs: + result.extend(node.arg for node in arguments.kwonlyargs) return result diff --git a/ropetest/refactor/extracttest.py b/ropetest/refactor/extracttest.py index 6445c75b4..865404d04 100644 --- a/ropetest/refactor/extracttest.py +++ b/ropetest/refactor/extracttest.py @@ -204,6 +204,24 @@ def new_func(): """) self.assertEqual(expected, refactored) + def test_extract_function_with_kwonlyargs(self): + code = dedent("""\ + def a_func(b, *, a_var): + another_var = 20 + third_var = a_var + another_var + """) + start, end = self._convert_line_range_to_offset(code, 3, 3) + refactored = self.do_extract_method(code, start, end, "new_func") + expected = dedent("""\ + def a_func(b, *, a_var): + another_var = 20 + new_func(a_var, another_var) + + def new_func(a_var, another_var): + third_var = a_var + another_var + """) + self.assertEqual(expected, refactored) + def test_extract_function_with_multiple_return_values(self): code = dedent("""\ def a_func(): From fcbd54c22c19c0db7825ba44cab8b71e9ff38398 Mon Sep 17 00:00:00 2001 From: Lie Ryan Date: Wed, 14 Dec 2022 16:27:06 +1100 Subject: [PATCH 2/7] Fix #567. Add posonlyargs to list of written arguments when extracting --- rope/refactor/extract.py | 5 ++++- ropetest/refactor/extracttest.py | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/rope/refactor/extract.py b/rope/refactor/extract.py index 2771092fe..ae2caab88 100644 --- a/rope/refactor/extract.py +++ b/rope/refactor/extract.py @@ -947,7 +947,10 @@ def _handle_loop_context(self, node): def _get_argnames(arguments): - result = [node.arg for node in arguments.args if isinstance(node, ast.arg)] + result = [] + if arguments.posonlyargs: + result.extend(node.arg for node in arguments.posonlyargs) + result.extend(node.arg for node in arguments.args if isinstance(node, ast.arg)) if arguments.vararg: result.append(arguments.vararg.arg) if arguments.kwarg: diff --git a/ropetest/refactor/extracttest.py b/ropetest/refactor/extracttest.py index 865404d04..8a320e028 100644 --- a/ropetest/refactor/extracttest.py +++ b/ropetest/refactor/extracttest.py @@ -222,6 +222,24 @@ def new_func(a_var, another_var): """) self.assertEqual(expected, refactored) + def test_extract_function_with_posonlyargs(self): + code = dedent("""\ + def a_func(a_var, /, b): + another_var = 20 + third_var = a_var + another_var + """) + start, end = self._convert_line_range_to_offset(code, 3, 3) + refactored = self.do_extract_method(code, start, end, "new_func") + expected = dedent("""\ + def a_func(a_var, /, b): + another_var = 20 + new_func(a_var, another_var) + + def new_func(a_var, another_var): + third_var = a_var + another_var + """) + self.assertEqual(expected, refactored) + def test_extract_function_with_multiple_return_values(self): code = dedent("""\ def a_func(): From f1393db9600a23a0d6195192cf3eb389c0f7a2ad Mon Sep 17 00:00:00 2001 From: Lie Ryan Date: Wed, 14 Dec 2022 16:29:45 +1100 Subject: [PATCH 3/7] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80d6f6ee6..0dcf420ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - #559 Improve handling of whitespace in import and from-import statements - #581 Remove functions in rope.base.ast that has functionally identical implementation in stdlib's ast - #589 Fix issue with `sample_project()` creating directories where it shouldn't when running tests +- #566, #567 Fix variables in kwonlyargs and posonlyargs not being correctly passed to extracted methods # Release 1.5.1 From 5f24a11a90c4ab4537add9e6cb92483da88c8d86 Mon Sep 17 00:00:00 2001 From: Lie Ryan Date: Wed, 14 Dec 2022 16:33:01 +1100 Subject: [PATCH 4/7] Simplify _get_argnames() There's no need to check for emptiness; if they're empty, the list comprehension already is no-op anyway. --- rope/refactor/extract.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/rope/refactor/extract.py b/rope/refactor/extract.py index ae2caab88..7d2969389 100644 --- a/rope/refactor/extract.py +++ b/rope/refactor/extract.py @@ -948,15 +948,13 @@ def _handle_loop_context(self, node): def _get_argnames(arguments): result = [] - if arguments.posonlyargs: - result.extend(node.arg for node in arguments.posonlyargs) + result.extend(node.arg for node in arguments.posonlyargs) result.extend(node.arg for node in arguments.args if isinstance(node, ast.arg)) if arguments.vararg: result.append(arguments.vararg.arg) if arguments.kwarg: result.append(arguments.kwarg.arg) - if arguments.kwonlyargs: - result.extend(node.arg for node in arguments.kwonlyargs) + result.extend(node.arg for node in arguments.kwonlyargs) return result From 5819fd26b5f6f1c70ba67827bf449def3bdf9151 Mon Sep 17 00:00:00 2001 From: Lie Ryan Date: Wed, 14 Dec 2022 16:41:04 +1100 Subject: [PATCH 5/7] Fix Python 3.7 doesn't have posonlyargs --- rope/refactor/extract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rope/refactor/extract.py b/rope/refactor/extract.py index 7d2969389..5ab2f4b73 100644 --- a/rope/refactor/extract.py +++ b/rope/refactor/extract.py @@ -948,7 +948,7 @@ def _handle_loop_context(self, node): def _get_argnames(arguments): result = [] - result.extend(node.arg for node in arguments.posonlyargs) + result.extend(node.arg for node in getattr(arguments, "posonlyargs", [])) result.extend(node.arg for node in arguments.args if isinstance(node, ast.arg)) if arguments.vararg: result.append(arguments.vararg.arg) From d3bfca199745a4f15348e08f9e83985fd6cdb5a5 Mon Sep 17 00:00:00 2001 From: Lie Ryan Date: Wed, 14 Dec 2022 16:46:19 +1100 Subject: [PATCH 6/7] Remove unnecessary `if isinstance(node, ast.arg)` check This was a holdover from Python 2, where `arguments` could be a list of `ast.Name` node instead of `ast.arg` nodes. --- rope/refactor/extract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rope/refactor/extract.py b/rope/refactor/extract.py index 5ab2f4b73..3221b1a16 100644 --- a/rope/refactor/extract.py +++ b/rope/refactor/extract.py @@ -949,7 +949,7 @@ def _handle_loop_context(self, node): def _get_argnames(arguments): result = [] result.extend(node.arg for node in getattr(arguments, "posonlyargs", [])) - result.extend(node.arg for node in arguments.args if isinstance(node, ast.arg)) + result.extend(node.arg for node in arguments.args) if arguments.vararg: result.append(arguments.vararg.arg) if arguments.kwarg: From c1b809cde1b1520ebd851e48f9d1d02115c1aa1c Mon Sep 17 00:00:00 2001 From: Lie Ryan Date: Wed, 14 Dec 2022 16:51:35 +1100 Subject: [PATCH 7/7] Mark test_extract_function_with_posonlyargs() for Python 3.8 and higher This is new syntax from Python 3.8. --- ropetest/refactor/extracttest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ropetest/refactor/extracttest.py b/ropetest/refactor/extracttest.py index 8a320e028..c03691da2 100644 --- a/ropetest/refactor/extracttest.py +++ b/ropetest/refactor/extracttest.py @@ -222,6 +222,7 @@ def new_func(a_var, another_var): """) self.assertEqual(expected, refactored) + @testutils.only_for_versions_higher("3.8") def test_extract_function_with_posonlyargs(self): code = dedent("""\ def a_func(a_var, /, b):