From 9237af239fa2856008f52a65d754c58969c5af18 Mon Sep 17 00:00:00 2001 From: Lie Ryan Date: Wed, 28 Feb 2024 18:11:47 +1100 Subject: [PATCH] add validation to refuse Rename refactoring to a python keyword --- CHANGELOG.md | 1 + rope/refactor/rename.py | 12 ++++++++++++ ropetest/refactor/renametest.py | 5 +++++ 3 files changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b262f24a..8b4124498 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # **Upcoming release** +- #777, #698 add validation to refuse Rename refactoring to a python keyword - #730 Match on module aliases for autoimport suggestions - #755 Remove dependency on `build` package being installed while running tests diff --git a/rope/refactor/rename.py b/rope/refactor/rename.py index cb6348009..fcdd17964 100644 --- a/rope/refactor/rename.py +++ b/rope/refactor/rename.py @@ -1,4 +1,5 @@ import warnings +from keyword import iskeyword from rope.base import ( codeanalyze, @@ -105,6 +106,7 @@ def unsure_func(value=unsure): resources = [self.resource] if resources is None: resources = self.project.get_python_files() + self.validate_changes(new_name) changes = ChangeSet(f"Renaming <{self.old_name}> to <{new_name}>") finder = occurrences.create_finder( self.project, @@ -128,6 +130,16 @@ def unsure_func(value=unsure): self._rename_module(resource, new_name, changes) return changes + def validate_changes( + self, + new_name: str, + **_unused, + ): + if iskeyword(new_name): + raise exceptions.RefactoringError( + f"Invalid refactoring target name. '{new_name}' is a Python keyword." + ) + def _is_allowed_to_move(self, resources, resource): if resource.is_folder(): try: diff --git a/ropetest/refactor/renametest.py b/ropetest/refactor/renametest.py index 8b9b8e1c6..a49e3e742 100644 --- a/ropetest/refactor/renametest.py +++ b/ropetest/refactor/renametest.py @@ -1,6 +1,7 @@ import sys import unittest from textwrap import dedent +from rope.base import exceptions import rope.base.codeanalyze import rope.refactor.occurrences @@ -1390,6 +1391,10 @@ def test_renaming_modules_aliased_many_dots(self): ) self.assertEqual("import new_json.utils.a as stdlib_json_utils\n", mod2.read()) + def test_rename_refuses_renaming_to_python_keyword(self): + with self.assertRaises(exceptions.RefactoringError, msg="Invalid refactoring target name. 'class' is a Python keyword."): + self._local_rename("a_var = 20\n", 2, "class") + class RenameRefactoringWithSuperclassTest(RenameTestMixin, unittest.TestCase): ORIGINAL_CODE = dedent("""\