diff --git a/rope/base/arguments.py b/rope/base/arguments.py index 12a626816..7bfe691b8 100644 --- a/rope/base/arguments.py +++ b/rope/base/arguments.py @@ -1,5 +1,6 @@ +import ast + import rope.base.evaluate -from rope.base import ast class Arguments: diff --git a/rope/base/builtins.py b/rope/base/builtins.py index 11390fa29..caa9c1ba7 100644 --- a/rope/base/builtins.py +++ b/rope/base/builtins.py @@ -1,11 +1,11 @@ """This module tries to support builtin types and functions.""" +import ast import inspect import io import rope.base.evaluate from rope.base import ( arguments, - ast, pynames, pyobjects, utils, diff --git a/rope/base/evaluate.py b/rope/base/evaluate.py index f079bac7f..906a6343c 100644 --- a/rope/base/evaluate.py +++ b/rope/base/evaluate.py @@ -1,3 +1,4 @@ +import ast from operator import itemgetter from typing import Optional, Tuple @@ -6,11 +7,11 @@ import rope.base.pyobjects from rope.base import ( arguments, - ast, nameanalyze, exceptions, pyobjects, pyobjectsdef, + rast, worder, ) @@ -50,7 +51,7 @@ def eval_str(holding_scope, name): def eval_str2(holding_scope, name): try: # parenthesizing for handling cases like 'a_var.\nattr' - node = ast.parse("(%s)" % name) + node = rast.parse("(%s)" % name) except SyntaxError: raise BadIdentifierError("Not a resolvable python identifier selected.") return eval_node2(holding_scope, node) @@ -158,7 +159,7 @@ def _find_module(self, module_name): ) -class StatementEvaluator(ast.RopeNodeVisitor): +class StatementEvaluator(rast.RopeNodeVisitor): def __init__(self, scope): self.scope = scope self.result = None diff --git a/rope/base/nameanalyze.py b/rope/base/nameanalyze.py index fd7f1d2ea..a84d4af6d 100644 --- a/rope/base/nameanalyze.py +++ b/rope/base/nameanalyze.py @@ -1,4 +1,6 @@ -from rope.base import ast +import ast + +from rope.base import rast def get_name_levels(node): @@ -18,7 +20,7 @@ def get_name_levels(node): return visitor.names -class _NodeNameCollector(ast.RopeNodeVisitor): +class _NodeNameCollector(rast.RopeNodeVisitor): def __init__(self, levels=None): self.names = [] self.levels = levels diff --git a/rope/base/oi/soa.py b/rope/base/oi/soa.py index df14b27b4..e3884d3ce 100644 --- a/rope/base/oi/soa.py +++ b/rope/base/oi/soa.py @@ -1,7 +1,8 @@ -import rope.base.ast +import ast + import rope.base.oi.soi import rope.base.pynames -from rope.base import pyobjects, evaluate, nameanalyze, arguments +from rope.base import arguments, pyobjects, evaluate, nameanalyze, rast def analyze_module(pycore, pymodule, should_analyze, search_subscopes, followed_calls): @@ -33,11 +34,11 @@ def _follow(pyfunction): if not followed_calls: _follow = None visitor = SOAVisitor(pycore, pydefined, _follow) - for child in rope.base.ast.iter_child_nodes(pydefined.get_ast()): + for child in ast.iter_child_nodes(pydefined.get_ast()): visitor.visit(child) -class SOAVisitor(rope.base.ast.RopeNodeVisitor): +class SOAVisitor(rast.RopeNodeVisitor): def __init__(self, pycore, pydefined, follow_callback=None): self.pycore = pycore self.pymodule = pydefined.get_module() @@ -51,7 +52,7 @@ def _ClassDef(self, node): pass def _Call(self, node): - for child in rope.base.ast.iter_child_nodes(node): + for child in ast.iter_child_nodes(node): self.visit(child) primary, pyname = evaluate.eval_node2(self.scope, node.func) if pyname is None: @@ -99,7 +100,7 @@ def _parameter_objects(self, pyfunction): ] def _AnnAssign(self, node): - for child in rope.base.ast.iter_child_nodes(node): + for child in ast.iter_child_nodes(node): self.visit(child) visitor = _SOAAssignVisitor() nodes = [] @@ -110,7 +111,7 @@ def _AnnAssign(self, node): self._evaluate_assign_value(node, nodes, type_hint=node.annotation) def _Assign(self, node): - for child in rope.base.ast.iter_child_nodes(node): + for child in ast.iter_child_nodes(node): self.visit(child) visitor = _SOAAssignVisitor() nodes = [] @@ -145,7 +146,7 @@ def __init__(self): self.nodes = [] def _added(self, node, levels): - if isinstance(node, rope.base.ast.Subscript) and isinstance( - node.slice, (rope.base.ast.Index, rope.base.ast.expr) + if isinstance(node, ast.Subscript) and isinstance( + node.slice, (ast.Index, ast.expr) ): self.nodes.append((node, levels)) diff --git a/rope/base/oi/type_hinting/providers/numpydocstrings.py b/rope/base/oi/type_hinting/providers/numpydocstrings.py index 5305a0d11..474829533 100644 --- a/rope/base/oi/type_hinting/providers/numpydocstrings.py +++ b/rope/base/oi/type_hinting/providers/numpydocstrings.py @@ -3,8 +3,9 @@ https://github.com/davidhalter/jedi/blob/b489019f5bd5750051122b94cc767df47751ecb7/jedi/evaluate/docstrings.py Thanks to @davidhalter for this utils under MIT License. """ +import ast import re -from rope.base.ast import literal_eval + from rope.base.oi.type_hinting.providers import docstrings try: @@ -26,7 +27,7 @@ def __call__(self, docstring, param_name): p_type = m.group(1) if p_type.startswith("{"): - types = {type(x).__name__ for x in literal_eval(p_type)} + types = {type(x).__name__ for x in ast.literal_eval(p_type)} return list(types) else: return [p_type] diff --git a/rope/base/prefs.py b/rope/base/prefs.py index 03d793f21..89c45ed7d 100644 --- a/rope/base/prefs.py +++ b/rope/base/prefs.py @@ -215,7 +215,7 @@ def add(self, key: str, value: Any): self[key] = [] getattr(self, key).append(value) - def get(self, key: str, default: Any = None): + def get(self, key: str, default: Any=None): """Get the value of the key preference""" return getattr(self, key, default) diff --git a/rope/base/pynamesdef.py b/rope/base/pynamesdef.py index ffbfb8e3c..2f78a7ffd 100644 --- a/rope/base/pynamesdef.py +++ b/rope/base/pynamesdef.py @@ -1,6 +1,5 @@ import rope.base.oi.soi -from rope.base import pynames -from rope.base.pynames import * +from rope.base import pynames, utils class AssignedName(pynames.AssignedName): diff --git a/rope/base/pyobjects.py b/rope/base/pyobjects.py index 62702e7a3..ebb92ca9b 100644 --- a/rope/base/pyobjects.py +++ b/rope/base/pyobjects.py @@ -1,6 +1,7 @@ +import ast from typing import Optional -from rope.base import ast, exceptions, utils +from rope.base import exceptions, utils class PyObject: diff --git a/rope/base/pyobjectsdef.py b/rope/base/pyobjectsdef.py index b87d2462a..1e505d01b 100644 --- a/rope/base/pyobjectsdef.py +++ b/rope/base/pyobjectsdef.py @@ -1,3 +1,5 @@ +import ast + import rope.base.builtins import rope.base.codeanalyze import rope.base.evaluate @@ -5,9 +7,10 @@ import rope.base.oi.soi import rope.base.pyscopes from rope.base import ( + pynames, pynamesdef, exceptions, - ast, + rast, nameanalyze, pyobjects, fscommands, @@ -177,7 +180,7 @@ def __init__(self, pycore, source=None, resource=None, force_errors=False): raise else: source = "\n" - node = ast.parse("\n") + node = rast.parse("\n") self.source_code = source self.star_imports = [] self.visitor_class = _GlobalVisitor @@ -197,7 +200,7 @@ def _init_source(self, pycore, source_code, resource): source_bytes = fscommands.unicode_to_file_data(source_code) else: source_bytes = source_code - ast_node = ast.parse(source_bytes, filename=filename) + ast_node = rast.parse(source_bytes, filename=filename) except SyntaxError as e: raise exceptions.ModuleSyntaxError(filename, e.lineno, e.msg) except UnicodeDecodeError as e: @@ -239,7 +242,7 @@ def __init__(self, pycore, resource=None, force_errors=False): init_dot_py, force_errors=force_errors ).get_ast() else: - ast_node = ast.parse("\n") + ast_node = rast.parse("\n") super().__init__(pycore, ast_node, resource) def _create_structural_attributes(self): @@ -251,7 +254,7 @@ def _create_structural_attributes(self): if self.resource is None: return result for name, resource in self._get_child_resources().items(): - result[name] = pynamesdef.ImportedModule(self, resource=resource) + result[name] = pynames.ImportedModule(self, resource=resource) return result def _create_concluded_attributes(self): @@ -291,7 +294,7 @@ def get_name(self): return rope.base.libutils.modname(self.resource) if self.resource else "" -class _AnnAssignVisitor(ast.RopeNodeVisitor): +class _AnnAssignVisitor(rast.RopeNodeVisitor): def __init__(self, scope_visitor): self.scope_visitor = scope_visitor self.assigned_ast = None @@ -307,7 +310,7 @@ def _assigned(self, name, assignment=None): self.scope_visitor._assigned(name, assignment) def _Name(self, node): - assignment = pynamesdef.AssignmentValue( + assignment = pynames.AssignmentValue( self.assigned_ast, assign_type=True, type_hint=self.type_hint ) self._assigned(node.id, assignment) @@ -317,7 +320,7 @@ def _Tuple(self, node): for name, levels in names: assignment = None if self.assigned_ast is not None: - assignment = pynamesdef.AssignmentValue(self.assigned_ast, levels) + assignment = pynames.AssignmentValue(self.assigned_ast, levels) self._assigned(name, assignment) def _Annotation(self, node): @@ -333,7 +336,7 @@ def _Slice(self, node): pass -class _ExpressionVisitor(ast.RopeNodeVisitor): +class _ExpressionVisitor(rast.RopeNodeVisitor): def __init__(self, scope_visitor): self.scope_visitor = scope_visitor @@ -360,7 +363,7 @@ def _NamedExpr(self, node): self.visit(node.value) -class _AssignVisitor(ast.RopeNodeVisitor): +class _AssignVisitor(rast.RopeNodeVisitor): def __init__(self, scope_visitor): self.scope_visitor = scope_visitor self.assigned_ast = None @@ -377,7 +380,8 @@ def _assigned(self, name, assignment=None): def _Name(self, node): assignment = None if self.assigned_ast is not None: - assignment = pynamesdef.AssignmentValue(self.assigned_ast) + assignment = pynames.AssignmentValue(self.assigned_ast) + self._assigned(node.id, assignment) def _Tuple(self, node): @@ -385,7 +389,7 @@ def _Tuple(self, node): for name, levels in names: assignment = None if self.assigned_ast is not None: - assignment = pynamesdef.AssignmentValue(self.assigned_ast, levels) + assignment = pynames.AssignmentValue(self.assigned_ast, levels) self._assigned(name, assignment) def _Attribute(self, node): @@ -414,7 +418,7 @@ def get_module(self): def _ClassDef(self, node): pyclass = PyClass(self.pycore, node, self.owner_object) - self.names[node.name] = pynamesdef.DefinedName(pyclass) + self.names[node.name] = pynames.DefinedName(pyclass) self.defineds.append(pyclass) def _FunctionDef(self, node): @@ -423,7 +427,7 @@ def _FunctionDef(self, node): if isinstance(decorator, ast.Name) and decorator.id == "property": if isinstance(self, _ClassVisitor): type_ = rope.base.builtins.Property(pyfunction) - arg = pynamesdef.UnboundName( + arg = pynames.UnboundName( rope.base.pyobjects.PyObject(self.owner_object) ) @@ -434,12 +438,12 @@ def _eval(type_=type_, arg=arg): lineno = utils.guess_def_lineno(self.get_module(), node) - self.names[node.name] = pynamesdef.EvaluatedName( + self.names[node.name] = pynames.EvaluatedName( _eval, module=self.get_module(), lineno=lineno ) break else: - self.names[node.name] = pynamesdef.DefinedName(pyfunction) + self.names[node.name] = pynames.DefinedName(pyfunction) self.defineds.append(pyfunction) def _AsyncFunctionDef(self, node): @@ -476,12 +480,12 @@ def _update_evaluated( ): result = {} if isinstance(targets, str): - assignment = pynamesdef.AssignmentValue(assigned, [], evaluation, eval_type) + assignment = pynames.AssignmentValue(assigned, [], evaluation, eval_type) self._assigned(targets, assignment) else: names = nameanalyze.get_name_levels(targets) for name, levels in names: - assignment = pynamesdef.AssignmentValue( + assignment = pynames.AssignmentValue( assigned, levels, evaluation, eval_type ) self._assigned(name, assignment) @@ -519,11 +523,11 @@ def _Import(self, node): alias = import_pair.asname first_package = module_name.split(".")[0] if alias is not None: - imported = pynamesdef.ImportedModule(self.get_module(), module_name) + imported = pynames.ImportedModule(self.get_module(), module_name) if not self._is_ignored_import(imported): self.names[alias] = imported else: - imported = pynamesdef.ImportedModule(self.get_module(), first_package) + imported = pynames.ImportedModule(self.get_module(), first_package) if not self._is_ignored_import(imported): self.names[first_package] = imported @@ -531,7 +535,7 @@ def _ImportFrom(self, node): level = 0 if node.level: level = node.level - imported_module = pynamesdef.ImportedModule( + imported_module = pynames.ImportedModule( self.get_module(), node.module or "", level, @@ -547,7 +551,7 @@ def _ImportFrom(self, node): alias = imported_name.asname if alias is not None: imported = alias - self.names[imported] = pynamesdef.ImportedName( + self.names[imported] = pynames.ImportedName( imported_module, imported_name.name ) @@ -636,7 +640,7 @@ def _Attribute(self, node): pyname = self.scope_visitor.names[node.attr] if isinstance(pyname, pynamesdef.AssignedName): pyname.assignments.append( - pynamesdef.AssignmentValue(self.assigned_ast) + pynames.AssignmentValue(self.assigned_ast) ) def _Tuple(self, node): @@ -670,5 +674,5 @@ def get_names(self): imported = self.imported_module.get_object() for name in imported: if not name.startswith("_"): - result[name] = pynamesdef.ImportedName(self.imported_module, name) + result[name] = pynames.ImportedName(self.imported_module, name) return result diff --git a/rope/base/pyscopes.py b/rope/base/pyscopes.py index f3c093d1a..2fdbddf24 100644 --- a/rope/base/pyscopes.py +++ b/rope/base/pyscopes.py @@ -1,6 +1,7 @@ +import ast + import rope.base.builtins # Use full qualification for clarity. from rope.base import ( - ast, codeanalyze, exceptions, pynames, diff --git a/rope/base/ast.py b/rope/base/rast.py similarity index 97% rename from rope/base/ast.py rename to rope/base/rast.py index 9f719f436..40f3acf50 100644 --- a/rope/base/ast.py +++ b/rope/base/rast.py @@ -1,5 +1,4 @@ import ast -from ast import * # noqa: F401,F403 from rope.base import fscommands diff --git a/rope/contrib/autoimport/parse.py b/rope/contrib/autoimport/parse.py index 1e4cb6bde..04f26a582 100644 --- a/rope/contrib/autoimport/parse.py +++ b/rope/contrib/autoimport/parse.py @@ -4,6 +4,7 @@ Can extract names from source code of a python file, .so object, or builtin module. """ +import ast import inspect import logging import pathlib @@ -20,7 +21,6 @@ PartialName, Source, ) -from rope.base import ast logger = logging.getLogger(__name__) diff --git a/rope/contrib/finderrors.py b/rope/contrib/finderrors.py index 335e6d84a..c5f6b8a26 100644 --- a/rope/contrib/finderrors.py +++ b/rope/contrib/finderrors.py @@ -23,7 +23,9 @@ * ... ;-) """ -from rope.base import ast, evaluate, pyobjects +import ast + +from rope.base import evaluate, pyobjects, rast def find_errors(project, resource): @@ -37,7 +39,7 @@ def find_errors(project, resource): return finder.errors -class _BadAccessFinder(ast.RopeNodeVisitor): +class _BadAccessFinder(rast.RopeNodeVisitor): def __init__(self, pymodule): self.pymodule = pymodule self.scope = pymodule.get_scope() diff --git a/rope/refactor/extract.py b/rope/refactor/extract.py index 3221b1a16..55e4847fc 100644 --- a/rope/refactor/extract.py +++ b/rope/refactor/extract.py @@ -1,8 +1,9 @@ +import ast import re from contextlib import contextmanager from itertools import chain -from rope.base import ast, codeanalyze +from rope.base import codeanalyze, rast from rope.base.change import ChangeSet, ChangeContents from rope.base.exceptions import RefactoringError from rope.base.utils.datastructures import OrderedSet @@ -514,7 +515,7 @@ def _is_on_a_word(self, info, offset): return next.isalnum() or next == "_" -class _ExtractMethodParts(ast.RopeNodeVisitor): +class _ExtractMethodParts(rast.RopeNodeVisitor): def __init__(self, info): self.info = info self.info_collector = self._create_info_collector() @@ -777,7 +778,7 @@ def get_checks(self): return {} -class _FunctionInformationCollector(ast.RopeNodeVisitor): +class _FunctionInformationCollector(rast.RopeNodeVisitor): def __init__(self, start, end, is_global): self.start = start self.end = end @@ -958,7 +959,7 @@ def _get_argnames(arguments): return result -class _VariableReadsAndWritesFinder(ast.RopeNodeVisitor): +class _VariableReadsAndWritesFinder(rast.RopeNodeVisitor): def __init__(self): self.written = set() self.read = set() @@ -998,7 +999,7 @@ def find_reads_for_one_liners(code): return visitor.read -class _BaseErrorFinder(ast.RopeNodeVisitor): +class _BaseErrorFinder(rast.RopeNodeVisitor): @classmethod def has_errors(cls, code): if code.strip() == "": @@ -1066,7 +1067,7 @@ def _ClassDef(self, node): pass -class _GlobalFinder(ast.RopeNodeVisitor): +class _GlobalFinder(rast.RopeNodeVisitor): def __init__(self): self.globals_ = OrderedSet() diff --git a/rope/refactor/importutils/module_imports.py b/rope/refactor/importutils/module_imports.py index cfeb26dc7..f07ddce27 100644 --- a/rope/refactor/importutils/module_imports.py +++ b/rope/refactor/importutils/module_imports.py @@ -1,10 +1,11 @@ +import ast from typing import Union, List from rope.base import ( - ast, exceptions, pynames, pynamesdef, + rast, utils, ) from rope.refactor.importutils import actions, importinfo @@ -421,7 +422,7 @@ def _can_name_be_added(self, imported_primary): return False -class _UnboundNameFinder(ast.RopeNodeVisitor): +class _UnboundNameFinder(rast.RopeNodeVisitor): def __init__(self, pyobject): self.pyobject = pyobject @@ -560,7 +561,7 @@ def visit_from(self, node, end_line): if node.level: level = node.level import_info = importinfo.FromImport( - node.module or "", # see comment at rope.base.ast.walk + node.module or "", ### Huh? see comment at rope.base.ast.walk level, self._get_names(node.names), ) diff --git a/rope/refactor/occurrences.py b/rope/refactor/occurrences.py index 53705e93f..5eac259f0 100644 --- a/rope/refactor/occurrences.py +++ b/rope/refactor/occurrences.py @@ -35,9 +35,9 @@ arguments """ +import ast import re -from rope.base import ast from rope.base import codeanalyze from rope.base import evaluate from rope.base import exceptions diff --git a/rope/refactor/patchedast.py b/rope/refactor/patchedast.py index 74bb6024b..9865d7b82 100644 --- a/rope/refactor/patchedast.py +++ b/rope/refactor/patchedast.py @@ -1,10 +1,11 @@ +import ast import collections import numbers import re import warnings from itertools import chain -from rope.base import ast, codeanalyze, exceptions +from rope.base import codeanalyze, exceptions, rast COMMA_IN_WITH_PATTERN = re.compile(r"\(.*?\)|(,)") @@ -35,7 +36,7 @@ def patch_ast(node, source, sorted_children=False): if hasattr(node, "region"): return node walker = _PatchingASTWalker(source, children=sorted_children) - ast.call_for_nodes(node, walker) + rast.call_for_nodes(node, walker) return node @@ -115,7 +116,7 @@ def _handle(self, node, base_children, eat_parens=False, eat_spaces=False): continue offset = self.source.offset if isinstance(child, ast.AST): - ast.call_for_nodes(child, self) + rast.call_for_nodes(child, self) token_start = child.region[0] else: if child is self.String: diff --git a/rope/refactor/restructure.py b/rope/refactor/restructure.py index 68694cdbf..047161ead 100644 --- a/rope/refactor/restructure.py +++ b/rope/refactor/restructure.py @@ -1,6 +1,7 @@ +import ast import warnings -from rope.base import change, taskhandle, builtins, ast, codeanalyze +from rope.base import change, taskhandle, builtins, codeanalyze from rope.base import libutils from rope.refactor import patchedast, similarfinder, sourceutils from rope.refactor.importutils import module_imports diff --git a/rope/refactor/similarfinder.py b/rope/refactor/similarfinder.py index c9254a578..ba73fb4b3 100644 --- a/rope/refactor/similarfinder.py +++ b/rope/refactor/similarfinder.py @@ -1,13 +1,14 @@ """This module can be used for finding similar code""" +import ast import re import rope.base.builtins # Use full qualification for clarity. import rope.refactor.wildcards # Use full qualification for clarity. from rope.base import ( - ast, codeanalyze, exceptions, libutils, + rast, ) from rope.refactor import patchedast from rope.refactor.patchedast import MismatchedTokenError @@ -158,7 +159,7 @@ def __init__(self, body, pattern, does_match): def find_matches(self): if self.matches is None: self.matches = [] - ast.call_for_nodes(self.body, self._check_node, recursive=True) + rast.call_for_nodes(self.body, self._check_node, recursive=True) return self.matches def _check_node(self, node): diff --git a/rope/refactor/suites.py b/rope/refactor/suites.py index 133652b20..b76ecb0af 100644 --- a/rope/refactor/suites.py +++ b/rope/refactor/suites.py @@ -1,6 +1,7 @@ +import ast from itertools import chain -from rope.base import ast +from rope.base import rast def find_visible(node, lines): @@ -98,7 +99,7 @@ def _get_level(self): return self.parent._get_level() + 1 -class _SuiteWalker(ast.RopeNodeVisitor): +class _SuiteWalker(rast.RopeNodeVisitor): def __init__(self, suite): self.suite = suite self.suites = [] diff --git a/rope/refactor/usefunction.py b/rope/refactor/usefunction.py index 255e33fe8..75d79d730 100644 --- a/rope/refactor/usefunction.py +++ b/rope/refactor/usefunction.py @@ -1,11 +1,13 @@ +import ast + from rope.base import ( - ast, change, evaluate, exceptions, libutils, pynames, pyobjects, + rast, taskhandle, ) from rope.refactor import restructure, sourceutils, similarfinder @@ -181,7 +183,7 @@ def _named_expr_count(node): return visitor.named_expression -class _ReturnOrYieldFinder(ast.RopeNodeVisitor): +class _ReturnOrYieldFinder(rast.RopeNodeVisitor): def __init__(self): self.returns = 0 self.named_expression = 0 diff --git a/rope/refactor/wildcards.py b/rope/refactor/wildcards.py index 5d7260dfc..b5fade7e4 100644 --- a/rope/refactor/wildcards.py +++ b/rope/refactor/wildcards.py @@ -1,4 +1,5 @@ -from rope.base import ast, evaluate, builtins, pyobjects +import ast +from rope.base import builtins, evaluate, pyobjects from rope.refactor import patchedast, occurrences diff --git a/ropetest/refactor/patchedasttest.py b/ropetest/refactor/patchedasttest.py index 7a2bc8fc2..4113f81ee 100644 --- a/ropetest/refactor/patchedasttest.py +++ b/ropetest/refactor/patchedasttest.py @@ -1,8 +1,9 @@ -import unittest +import ast import sys from textwrap import dedent +import unittest -from rope.base import ast +from rope.base import rast from rope.refactor import patchedast from ropetest import testutils @@ -1632,7 +1633,7 @@ def __call__(self, node): return self.result is not None search = Search() - ast.call_for_nodes(self.ast, search, recursive=True) + rast.call_for_nodes(self.ast, search, recursive=True) return search.result def check_children(self, text, children): diff --git a/ropetest/refactor/suitestest.py b/ropetest/refactor/suitestest.py index 5c5fa1fbd..99f7f9408 100644 --- a/ropetest/refactor/suitestest.py +++ b/ropetest/refactor/suitestest.py @@ -1,8 +1,7 @@ +import ast from textwrap import dedent - import unittest -from rope.base import ast from rope.refactor import suites from ropetest import testutils