Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# **Upcoming release**

- #811 Preserve still-used imports when moving globals with filtered import cleanup
- #850 Update and pin black version in pre-commit and Github Actions
- #851 Bump supported python version to up to Python 3.14
- #852 Implement patchedast handlers for TypeAlias
- #852 Implement patchedast handlers for TypeAlias
- #853 Implement patchedast handlers TypeVar
- #847 Avoid printing autoimport syntax errors (@yangfan-yf-yf)
- #623, #819, #863 Support MatchOr, MatchSequence, MatchStar (@jheld, @lieryan)
Expand Down
5 changes: 5 additions & 0 deletions rope/refactor/importutils/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ def visitFromImport(self, import_stmt, import_info):
):
if import_info.is_star_import():
return True
if import_stmt.readonly:
return not self.import_info.is_star_import() and all(
pair in import_info.names_and_aliases
for pair in self.import_info.names_and_aliases
)
if self.import_info.is_star_import():
import_stmt.import_info = self.import_info
return True
Expand Down
33 changes: 31 additions & 2 deletions ropetest/refactor/importutilstest.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import unittest
from textwrap import dedent

from rope.base.prefs import get_preferred_import_style, ImportStyle, Prefs, ImportPrefs
from rope.base.prefs import DEFAULT_IMPORT_STYLE
from rope.base.prefs import (
DEFAULT_IMPORT_STYLE,
ImportPrefs,
ImportStyle,
Prefs,
get_preferred_import_style,
)
from rope.refactor.importutils import ImportTools, add_import, importinfo
from ropetest import testutils

Expand Down Expand Up @@ -1943,6 +1948,30 @@ def import_filter(import_stmt):

return import_filter

def test_filtered_duplicate_removal_preserves_distinct_from_imports(self):
for imported in ("mod3", "mod3 as other", "*"):
with self.subTest(imported=imported):
source = "from pkg2 import mod2\nfrom pkg2 import " + imported + "\n"
self.mod.write(source)
pymod = self.project.get_pymodule(self.mod)
module_imports = self.import_tools.module_imports(
pymod, self._line_filter(2)
)
module_imports.remove_duplicates()
self.assertEqual(source, module_imports.get_changed_source())

def test_filtered_duplicate_removal_still_removes_covered_imports(self):
for imported in ("mod2", "mod2, mod3", "*"):
with self.subTest(imported=imported):
expected = "from pkg2 import " + imported + "\n"
self.mod.write(expected + "from pkg2 import mod2\n")
pymod = self.project.get_pymodule(self.mod)
module_imports = self.import_tools.module_imports(
pymod, self._line_filter(2)
)
module_imports.remove_duplicates()
self.assertEqual(expected, module_imports.get_changed_source())

def test_filtered_expand_stars(self):
self.pkg1.get_child("__init__.py").write("var1 = 1\n")
self.pkg2.get_child("__init__.py").write("var2 = 1\n")
Expand Down
30 changes: 26 additions & 4 deletions ropetest/refactor/movetest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
from rope.refactor import move
from ropetest import testutils


if TYPE_CHECKING:
from rope.base import resources, project
from rope.base import project, resources

class MoveRefactoringTest(unittest.TestCase):
project: project.Project
Expand Down Expand Up @@ -74,6 +73,29 @@ def test_move_constant(self) -> None:
self.assertEqual("", self.origin_module.read())
self.assertEqual("foo = 123\n", self.destination_module.read())

def test_move_constant_preserves_used_module_alias(self) -> None:
self.project.prefs["prefer_module_from_imports"] = True
self.mod4.write("def keep():\n return 1\n\nvalue = 2\n")
self.mod5.write("def existing():\n return 3\n")
self.mod3.write(
"from pkg import mod5\n"
"from pkg import mod4 as utils_module\n"
"\n"
"def run():\n"
" return mod5.existing(), utils_module.keep(), utils_module.value\n"
)
self._move(self.mod4, self.mod4.read().index("value"), self.mod5)
self.assertEqual(
"from pkg import mod5\n"
"from pkg import mod4 as utils_module\n"
"\n"
"def run():\n"
" return mod5.existing(), utils_module.keep(), mod5.value\n",
self.mod3.read(),
)
self.assertEqual("def keep():\n return 1\n\n", self.mod4.read())
self.assertIn("value = 2\n", self.mod5.read())

def test_move_constant_2(self) -> None:
self.origin_module.write("bar = 321\nfoo = 123\n")
self._move(self.origin_module, self.origin_module.read().index("foo") + 1, self.destination_module)
Expand Down Expand Up @@ -603,7 +625,7 @@ def test_moving_modules_and_removing_out_of_date_froms(self) -> None:
dedent("""\
import mod4
print(mod4)"""
),
),
self.origin_module.read(),
)

Expand Down Expand Up @@ -1423,7 +1445,7 @@ def foo():
dedent("""\
def hello(func):
return func
"""),
"""),
self.origin_module.read(),
)
self.assertEqual(
Expand Down
Loading