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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# **Upcoming release**

- ...
- #811 Preserve still-used imports when moving globals with filtered import cleanup

# Release 1.15.0

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
24 changes: 24 additions & 0 deletions ropetest/refactor/importutilstest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1948,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
23 changes: 23 additions & 0 deletions ropetest/refactor/movetest.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,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
Loading