rope icon indicating copy to clipboard operation
rope copied to clipboard

refactor.move messing up existing imports

Open srajangarg opened this issue 8 months ago • 0 comments

Describe the bug

Moving a function from one module to another causes a still-in-use import to be removed

To Reproduce

Sample Project

Consider the sample project:

example_src
├── dep_module.py
└── inner_module
    ├── __init__.py
    ├── module1.py
    └── module2.py

module1.py

def module1_function():    
    return 1

module1_global_variable = 1

module2.py

def module2_function():    
    return 2

dep_module.py

from inner_module import module2
from inner_module import module1 as utils_module

def proxy_module2_function():
    return module2.module2_function()

def proxy_module1_function():
    return utils_module.module1_function()

def proxy_module1_global_variable():
    return utils_module.module1_global_variable

Script to refactor

Now, if i run the following script to move module1_global_variable to module2

import rope.base.project
import rope.refactor.move

# Create the project
project = rope.base.project.Project(projectroot=""/Users/srajan/code/example_src", ropefolder=None)
project.prefs.prefer_module_from_imports = True

# create the resources
source_resource = project.get_resource("inner_module/module1.py")
dest_resource = project.get_resource("inner_module/module2.py")

# move `module1_global_variable` to `new_module.py`
# module1_global_variable has an offset of 42 characters in the file
mover = rope.refactor.move.create_move(project, source_resource, 42)
changes = mover.get_changes(dest_resource)
project.do(changes)
project.close()

Problematic diff

The diffs are as follows:

/dep_module.py

 from inner_module import module2
-from inner_module import module1 as utils_module
 
 def proxy_module1_global_variable():
-    return utils_module.module1_global_variable
+    return module2.module1_global_variable


/inner_module/module1.py

 def module1_function():    
     return 1
 
-module1_global_variable = 1


inner_module/module2.py
@@ -1,2 +1,3 @@
+module1_global_variable = 1
 def module2_function():    
     return 2

The module1_global_variable is succesfully moved, but the utils_module is completely removed from dep_module.py! which renders the file incorrect (because utils_module is still being used in proxy_module1_function)

Editor information (please complete the following information):

  • Project Python version: 3.11
  • Rope Python version: 3.11
  • Rope version: 1.13.0

srajangarg avatar Apr 26 '25 19:04 srajangarg