Reputation: 525
Given a folder myproj
with a file myclass.py
myproj
-- __init__.py
-- myclass.py
where myclass.py
contains the following class definition
class MyClass:
pass
I want to rename the class from MyClass
to MyClass2
with rope.
If I know that the offset of the class name is 6
, then I could rename the class as follows
import rope.base.project
import rope.refactor.rename
proj = rope.base.project.Project('myproj')
res = proj.get_module('myclass').get_resource()
change = rope.refactor.rename.Rename(proj, res, 6).get_changes('MyClass2')
print(change.get_description())
Question: How do I rename a class with rope knowing only the name of the class MyClass
(but not knowing the offset of MyClass
)?
Edit:
Here is one way to do it
offset = res.read().index('MyClass')
Upvotes: 2
Views: 315
Reputation: 64827
Rope is primarily intended for use in an IDE, where the user is refactoring interactively with text editor cursor pointed to the object that the user wants to refactor, not for programmatic refactoring.
With that said, if you want to do something like this, you can use the get_definition_location()
method to get the closest line number:
mod = proj.get_module('myclass')
name = mod.get_attribute('MyClass')
pymod, lineno = name.get_definition_location()
lineno_start, lineno_end = pymod.logical_lines.logical_line_in(lineno)
offset = pymod.resource.read().index(name.pyobject.get_name(), pymod.lines.get_line_start(lineno))
change = rope.refactor.rename.Rename(proj, pymod.get_resource(), offset).get_changes('MyClass2')
It's going to be slightly more reliable than trying to get the global offset using index()
, which can be easily fooled by matching text in docstrings/comments.
Disclosure: I am the primary maintainer of Rope
Upvotes: 1