Skip to content

Commit

Permalink
Merge pull request #230 from soupytwist/aliased-import
Browse files Browse the repository at this point in the history
Bugfix for detecting pynames in aliased import statements
  • Loading branch information
soupytwist committed Jan 4, 2018
2 parents 2e04c02 + da1fa1e commit 5f84456
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
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

0 comments on commit 5f84456

Please sign in to comment.