Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix for detecting pynames in aliased import statements #230

Merged
merged 1 commit into from Jan 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions rope/base/evaluate.py
Expand Up @@ -101,8 +101,9 @@ def get_primary_and_pyname_at(self, offset):
offset, lineno):
name = self.worder.get_primary_at(offset).strip()
return (None, holding_scope.parent[name])
# from statement module
if self.worder.is_from_statement_module(offset):
# module in a from statement or an imported name that is aliased
if (self.worder.is_from_statement_module(offset) or
self.worder.is_import_statement_aliased_module(offset)):
module = self.worder.get_primary_at(offset)
module_pyname = self._find_module(module)
return (None, module_pyname)
Expand Down
31 changes: 28 additions & 3 deletions rope/base/worder.py
Expand Up @@ -65,6 +65,9 @@ def is_from_statement_module(self, offset):
def is_from_aliased(self, offset):
return self.code_finder.is_from_aliased(offset)

def is_import_statement_aliased_module(self, offset):
return self.code_finder.is_import_statement_aliased_module(offset)

def find_parens_start_from_inside(self, offset):
return self.code_finder.find_parens_start_from_inside(offset)

Expand Down Expand Up @@ -317,7 +320,9 @@ def is_import_statement(self, offset):
last_import = self.code.rindex('import ', 0, offset)
except ValueError:
return False
return self._find_import_end(last_import + 7) >= offset
line_start = self._get_line_start(last_import)
return (self._find_import_end(last_import + 7) >= offset and
self._find_word_start(line_start) == last_import)

def is_from_statement(self, offset):
try:
Expand All @@ -337,6 +342,27 @@ def is_from_statement_module(self, offset):
prev_word = self.code[line_start:stmt_start].strip()
return prev_word == 'from'

def is_import_statement_aliased_module(self, offset):
if not self.is_import_statement(offset):
return False
try:
line_start = self._get_line_start(offset)
import_idx = self.code.rindex('import', line_start, offset)
imported_names = import_idx + 7
except ValueError:
return False
# Check if the offset is within the imported names
if (imported_names - 1 > offset or
self._find_import_end(imported_names) < offset):
return False
try:
end = self._find_word_end(offset)
as_end = min(self._find_word_end(end + 1), len(self.code))
as_start = self._find_word_start(as_end)
return self.code[as_start:as_end + 1] == 'as'
except ValueError:
return False

def is_a_name_after_from_import(self, offset):
try:
if len(self.code) > offset and self.code[offset] == '\n':
Expand Down Expand Up @@ -368,8 +394,7 @@ def is_from_aliased(self, offset):
end = self._find_word_end(offset)
as_end = min(self._find_word_end(end + 1), len(self.code))
as_start = self._find_word_start(as_end)
if self.code[as_start:as_end + 1] == 'as':
return True
return self.code[as_start:as_end + 1] == 'as'
except ValueError:
return False

Expand Down
10 changes: 10 additions & 0 deletions ropetest/refactor/renametest.py
Expand Up @@ -223,6 +223,16 @@ def test_renaming_modules(self):
self.project.find_module('newmod') is not None)
self.assertEquals('from newmod import a_func\n', mod2.read())

def test_renaming_modules_aliased(self):
mod1 = testutils.create_module(self.project, 'mod1')
mod1.write('def a_func():\n pass\n')
mod2 = testutils.create_module(self.project, 'mod2')
mod2.write('import mod1 as m\nm.a_func()\n')
self._rename(mod1, None, 'newmod')
self.assertTrue(not mod1.exists() and
self.project.find_module('newmod') is not None)
self.assertEquals('import newmod as m\nm.a_func()\n', mod2.read())

def test_renaming_packages(self):
pkg = testutils.create_package(self.project, 'pkg')
mod1 = testutils.create_module(self.project, 'mod1', pkg)
Expand Down