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 diff --git a/rope/refactor/extract.py b/rope/refactor/extract.py index 47628c75c..3221b1a16 100644 --- a/rope/refactor/extract.py +++ b/rope/refactor/extract.py @@ -947,11 +947,14 @@ def _handle_loop_context(self, node): def _get_argnames(arguments): - result = [node.arg for node in arguments.args if isinstance(node, ast.arg)] + result = [] + result.extend(node.arg for node in getattr(arguments, "posonlyargs", [])) + result.extend(node.arg for node in arguments.args) if arguments.vararg: result.append(arguments.vararg.arg) if arguments.kwarg: result.append(arguments.kwarg.arg) + 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..c03691da2 100644 --- a/ropetest/refactor/extracttest.py +++ b/ropetest/refactor/extracttest.py @@ -204,6 +204,43 @@ 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) + + @testutils.only_for_versions_higher("3.8") + 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():