Apply upstream changesets: https://bitbucket.org/agr/rope/changeset/1c100ebabc16 https://bitbucket.org/agr/rope/changeset/f5eb880e0be2 to fix issues with python 2.7 https://bugs.gentoo.org/show_bug.cgi?id=326401 https://bitbucket.org/agr/rope/issue/8/ --- a/rope/base/ast.py +++ b/rope/base/ast.py @@ -27,6 +27,10 @@ method_name = '_' + node.__class__.__name__ method = getattr(walker, method_name, None) if method is not None: + if isinstance(node, _ast.ImportFrom) and node.module is None: + # In python < 2.7 ``node.module == ''`` for relative imports + # but for python 2.7 it is None. Generalizing it to ''. + node.module = '' return method(node) for child in get_child_nodes(node): walk(child, walker) --- a/rope/base/oi/runmod.py +++ b/rope/base/oi/runmod.py @@ -187,6 +187,7 @@ def close(self): self.sender.close() + sys.settrace(None) def _realpath(path): return os.path.realpath(os.path.abspath(os.path.expanduser(path))) --- a/rope/refactor/importutils/module_imports.py +++ b/rope/refactor/importutils/module_imports.py @@ -428,7 +428,8 @@ if node.level: level = node.level import_info = importinfo.FromImport( - node.module, level, self._get_names(node.names)) + node.module or '', # see comment at rope.base.ast.walk + level, self._get_names(node.names)) start_line = node.lineno self.imports.append(importinfo.ImportStatement( import_info, node.lineno, end_line, --- a/rope/refactor/patchedast.py +++ b/rope/refactor/patchedast.py @@ -350,7 +350,8 @@ children = ['from'] if node.level: children.append('.' * node.level) - children.extend([node.module, 'import']) + children.extend([node.module or '', # see comment at rope.base.ast.walk + 'import']) children.extend(self._child_nodes(node.names, ',')) self._handle(node, children) --- a/ropetest/refactor/patchedasttest.py +++ b/ropetest/refactor/patchedasttest.py @@ -441,6 +441,17 @@ 'import', ' ', 'alias']) checker.check_children('alias', ['y', ' ', 'as', ' ', 'z']) + @testutils.run_only_for_25 + def test_from_node_relative_import(self): + source = 'from . import y as z\n' + ast = patchedast.get_patched_ast(source, True) + checker = _ResultChecker(self, ast) + checker.check_region('ImportFrom', 0, len(source) - 1) + checker.check_children( + 'ImportFrom', ['from', ' ', '.', '', '', ' ', + 'import', ' ', 'alias']) + checker.check_children('alias', ['y', ' ', 'as', ' ', 'z']) + def test_simple_gen_expr_node(self): source = 'zip(i for i in x)\n' ast = patchedast.get_patched_ast(source, True)