From 371adc07f579966a50c4834aee136534efd5f27d Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Thu, 8 Dec 2022 10:03:26 -0600 Subject: [PATCH 01/13] All tests pass --- rope/base/arguments.py | 21 +++--- rope/base/ast.py | 68 ------------------- rope/base/astutils.py | 72 +++++++++++++++------ rope/base/astwrapper.py | 35 ++++++++++ rope/base/builtins.py | 5 +- rope/base/evaluate.py | 7 +- rope/base/oi/soa.py | 35 +++++----- rope/base/pyobjects.py | 8 ++- rope/base/pyobjectsdef.py | 62 +++++++++--------- rope/base/pyscopes.py | 11 ++-- rope/contrib/autoimport/parse.py | 4 +- rope/contrib/finderrors.py | 9 ++- rope/refactor/extract.py | 60 ++++++++--------- rope/refactor/importutils/module_imports.py | 14 ++-- rope/refactor/inline.py | 1 - rope/refactor/patchedast.py | 12 ++-- rope/refactor/restructure.py | 14 ++-- rope/refactor/similarfinder.py | 16 +++-- rope/refactor/suites.py | 5 +- rope/refactor/usefunction.py | 16 ++++- rope/refactor/wildcards.py | 3 +- ropetest/contrib/autoimport/conftest.py | 4 +- ropetest/refactor/patchedasttest.py | 9 +-- ropetest/refactor/suitestest.py | 8 +-- 24 files changed, 267 insertions(+), 232 deletions(-) delete mode 100644 rope/base/ast.py create mode 100644 rope/base/astwrapper.py diff --git a/rope/base/arguments.py b/rope/base/arguments.py index 12a626816..381391647 100644 --- a/rope/base/arguments.py +++ b/rope/base/arguments.py @@ -1,5 +1,6 @@ -import rope.base.evaluate -from rope.base import ast +import ast + +from rope.base import builtins, evaluate, pyobjects class Arguments: @@ -36,9 +37,10 @@ def get_pynames(self, parameters): def get_instance_pyname(self): if self.args: return self._evaluate(self.args[0]) + return None def _evaluate(self, ast_node): - return rope.base.evaluate.eval_node(self.scope, ast_node) + return evaluate.eval_node(self.scope, ast_node) def create_arguments(primary, pyfunction, call_node, scope): @@ -99,13 +101,14 @@ def _is_method_call(primary, pyfunction): return False pyobject = primary.get_object() if ( - isinstance(pyobject.get_type(), rope.base.pyobjects.PyClass) - and isinstance(pyfunction, rope.base.pyobjects.PyFunction) - and isinstance(pyfunction.parent, rope.base.pyobjects.PyClass) + isinstance(pyobject.get_type(), pyobjects.PyClass) + and isinstance(pyfunction, pyobjects.PyFunction) + and isinstance(pyfunction.parent, pyobjects.PyClass) ): return True - if isinstance( - pyobject.get_type(), rope.base.pyobjects.AbstractClass - ) and isinstance(pyfunction, rope.base.builtins.BuiltinFunction): + if ( + isinstance(pyobject.get_type(), pyobjects.AbstractClass) + and isinstance(pyfunction, builtins.BuiltinFunction) # pylint: disable=no-member + ): return True return False diff --git a/rope/base/ast.py b/rope/base/ast.py deleted file mode 100644 index efe95fcbc..000000000 --- a/rope/base/ast.py +++ /dev/null @@ -1,68 +0,0 @@ -import ast -from ast import * - -from rope.base import fscommands - - -def parse(source, filename=""): - # NOTE: the raw string should be given to `compile` function - if isinstance(source, str): - source = fscommands.unicode_to_file_data(source) - if b"\r" in source: - source = source.replace(b"\r\n", b"\n").replace(b"\r", b"\n") - if not source.endswith(b"\n"): - source += b"\n" - try: - return ast.parse(source, filename="") - except (TypeError, ValueError) as e: - error = SyntaxError() - error.lineno = 1 - error.filename = filename - error.msg = str(e) - raise error - - -def walk(node, walker) -> None: - """Walk the syntax tree""" - method_name = "_" + node.__class__.__name__ - method = getattr(walker, method_name, None) - if method is not None: - method(node) - return - for child in get_child_nodes(node): - walk(child, walker) - - -def get_child_nodes(node): - if isinstance(node, ast.Module): - return node.body - result = [] - if node._fields is not None: - for name in node._fields: - child = getattr(node, name) - if isinstance(child, list): - for entry in child: - if isinstance(entry, ast.AST): - result.append(entry) - if isinstance(child, ast.AST): - result.append(child) - return result - - -def call_for_nodes(node, callback, recursive=False): - """If callback returns `True` the child nodes are skipped""" - result = callback(node) - if recursive and not result: - for child in get_child_nodes(node): - call_for_nodes(child, callback, recursive) - - -def get_children(node): - result = [] - if node._fields is not None: - for name in node._fields: - if name in ["lineno", "col_offset"]: - continue - child = getattr(node, name) - result.append(child) - return result diff --git a/rope/base/astutils.py b/rope/base/astutils.py index 3eef2ebb6..d47c89021 100644 --- a/rope/base/astutils.py +++ b/rope/base/astutils.py @@ -1,22 +1,6 @@ -from rope.base import ast - - -def get_name_levels(node): - """Return a list of ``(name, level)`` tuples for assigned names - - The `level` is `None` for simple assignments and is a list of - numbers for tuple assignments for example in:: - - a, (b, c) = x - - The levels for for `a` is ``[0]``, for `b` is ``[1, 0]`` and for - `c` is ``[1, 1]``. - - """ - visitor = _NodeNameCollector() - ast.walk(node, visitor) - return visitor.names +import ast +from rope.base.astwrapper import walk class _NodeNameCollector: def __init__(self, levels=None): @@ -49,8 +33,8 @@ def _Tuple(self, node): new_levels.append(self.index) self.index += 1 visitor = _NodeNameCollector(new_levels) - for child in ast.get_child_nodes(node): - ast.walk(child, visitor) + for child in get_child_nodes(node): + walk(child, visitor) self.names.extend(visitor.names) def _Subscript(self, node): @@ -61,3 +45,51 @@ def _Attribute(self, node): def _Slice(self, node): self._add_node(node) +def get_child_nodes(node): + if isinstance(node, ast.Module): + return node.body + result = [] + if node._fields is not None: + for name in node._fields: + child = getattr(node, name) + if isinstance(child, list): + for entry in child: + if isinstance(entry, ast.AST): + result.append(entry) + if isinstance(child, ast.AST): + result.append(child) + return result + + +def get_name_levels(node): + """Return a list of ``(name, level)`` tuples for assigned names + + The `level` is `None` for simple assignments and is a list of + numbers for tuple assignments for example in:: + + a, (b, c) = x + + The levels for for `a` is ``[0]``, for `b` is ``[1, 0]`` and for + `c` is ``[1, 1]``. + + """ + visitor = _NodeNameCollector() + walk(node, visitor) + return visitor.names +def call_for_nodes(node, callback, recursive=False): + """If callback returns `True` the child nodes are skipped""" + result = callback(node) + if recursive and not result: + for child in get_child_nodes(node): + call_for_nodes(child, callback, recursive) + + +def get_children(node): + result = [] + if node._fields is not None: + for name in node._fields: + if name in ["lineno", "col_offset"]: + continue + child = getattr(node, name) + result.append(child) + return result diff --git a/rope/base/astwrapper.py b/rope/base/astwrapper.py new file mode 100644 index 000000000..b83d85541 --- /dev/null +++ b/rope/base/astwrapper.py @@ -0,0 +1,35 @@ +"""Wrappers for stdlib.ast.parse and stdlib.ast.walk.""" +import ast + +from rope.base import astutils, fscommands + + +def parse(source, filename=""): + # NOTE: the raw string should be given to `compile` function + if isinstance(source, str): + source = fscommands.unicode_to_file_data(source) + if b"\r" in source: + source = source.replace(b"\r\n", b"\n").replace(b"\r", b"\n") + if not source.endswith(b"\n"): + source += b"\n" + try: + return ast.parse(source, filename="") + except (TypeError, ValueError) as e: + error = SyntaxError() + error.lineno = 1 + error.filename = filename + error.msg = str(e) + raise error + + +def walk(node, walker) -> None: + """Walk the syntax tree""" + method_name = "_" + node.__class__.__name__ + method = getattr(walker, method_name, None) + if method is not None: + method(node) + return + for child in astutils.get_child_nodes(node): + walk(child, walker) + + diff --git a/rope/base/builtins.py b/rope/base/builtins.py index 9982b69ec..93582b77e 100644 --- a/rope/base/builtins.py +++ b/rope/base/builtins.py @@ -1,9 +1,10 @@ """This module tries to support builtin types and functions.""" +import ast import inspect import io import rope.base.evaluate -from rope.base import ast, pynames, pyobjects, arguments, utils +from rope.base import arguments, pynames, pyobjects, utils try: @@ -39,7 +40,7 @@ def attributes(self): if self.pycore is not None: submodules = self.pycore._builtin_submodules(self.name) for name, module in submodules.items(): - result[name] = rope.base.builtins.BuiltinName(module) + result[name] = BuiltinName(module) # pylint: disable=no-member return result @property diff --git a/rope/base/evaluate.py b/rope/base/evaluate.py index 4aa9fdbe0..62c71479d 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 @@ -5,7 +6,6 @@ import rope.base.pynames import rope.base.pyobjects from rope.base import ( - ast, astutils, exceptions, pyobjects, @@ -13,6 +13,7 @@ arguments, worder, ) +from rope.base.astwrapper import parse, walk BadIdentifierError = exceptions.BadIdentifierError @@ -39,7 +40,7 @@ def eval_node(scope, node): def eval_node2(scope, node): evaluator = StatementEvaluator(scope) - ast.walk(node, evaluator) + walk(node, evaluator) return evaluator.old_result, evaluator.result @@ -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 = parse("(%s)" % name) except SyntaxError: raise BadIdentifierError("Not a resolvable python identifier selected.") return eval_node2(holding_scope, node) diff --git a/rope/base/oi/soa.py b/rope/base/oi/soa.py index 4e8cab4a8..947b7b43f 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, astutils, arguments +from rope.base.astwrapper import walk +from rope.base import arguments, astutils, evaluate, pyobjects def analyze_module(pycore, pymodule, should_analyze, search_subscopes, followed_calls): @@ -30,11 +31,9 @@ def _follow(pyfunction): pycore, pyfunction, return_true, return_false, new_followed_calls ) - if not followed_calls: - _follow = None - visitor = SOAVisitor(pycore, pydefined, _follow) - for child in rope.base.ast.get_child_nodes(pydefined.get_ast()): - rope.base.ast.walk(child, visitor) + visitor = SOAVisitor(pycore, pydefined, _follow if followed_calls else None) + for child in astutils.get_child_nodes(pydefined.get_ast()): + walk(child, visitor) class SOAVisitor: @@ -51,8 +50,8 @@ def _ClassDef(self, node): pass def _Call(self, node): - for child in rope.base.ast.get_child_nodes(node): - rope.base.ast.walk(child, self) + for child in astutils.get_child_nodes(node): + walk(child, self) primary, pyname = evaluate.eval_node2(self.scope, node.func) if pyname is None: return @@ -89,7 +88,7 @@ def _call(self, pyfunction, args): if after != before: self.follow(pyfunction) # XXX: Maybe we should not call every builtin function - if isinstance(pyfunction, rope.base.builtins.BuiltinFunction): + if isinstance(pyfunction, rope.base.builtins.BuiltinFunction): # pylint: disable=no-member pyfunction.get_returned_object(args) def _parameter_objects(self, pyfunction): @@ -99,23 +98,23 @@ def _parameter_objects(self, pyfunction): ] def _AnnAssign(self, node): - for child in rope.base.ast.get_child_nodes(node): - rope.base.ast.walk(child, self) + for child in astutils.get_child_nodes(node): + walk(child, self) visitor = _SOAAssignVisitor() nodes = [] - rope.base.ast.walk(node.target, visitor) + walk(node.target, visitor) nodes.extend(visitor.nodes) self._evaluate_assign_value(node, nodes, type_hint=node.annotation) def _Assign(self, node): - for child in rope.base.ast.get_child_nodes(node): - rope.base.ast.walk(child, self) + for child in astutils.get_child_nodes(node): + walk(child, self) visitor = _SOAAssignVisitor() nodes = [] for child in node.targets: - rope.base.ast.walk(child, visitor) + walk(child, visitor) nodes.extend(visitor.nodes) self._evaluate_assign_value(node, nodes) @@ -145,7 +144,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/pyobjects.py b/rope/base/pyobjects.py index 820fc2d1b..a91e705ff 100644 --- a/rope/base/pyobjects.py +++ b/rope/base/pyobjects.py @@ -1,6 +1,8 @@ +import ast from typing import Optional -from rope.base import ast, exceptions, utils +from rope.base import astutils, exceptions, utils +from rope.base.astwrapper import walk class PyObject: @@ -243,8 +245,8 @@ def _create_structural_attributes(self): if self.visitor_class is None: return {} new_visitor = self.visitor_class(self.pycore, self) - for child in ast.get_child_nodes(self.ast_node): - ast.walk(child, new_visitor) + for child in astutils.get_child_nodes(self.ast_node): + walk(child, new_visitor) self.defineds = new_visitor.defineds return new_visitor.names diff --git a/rope/base/pyobjectsdef.py b/rope/base/pyobjectsdef.py index e0f0efa75..dd56b4eb1 100644 --- a/rope/base/pyobjectsdef.py +++ b/rope/base/pyobjectsdef.py @@ -1,3 +1,4 @@ +import ast import rope.base.builtins import rope.base.codeanalyze import rope.base.evaluate @@ -5,15 +6,16 @@ import rope.base.oi.soi import rope.base.pyscopes from rope.base import ( - pynamesdef, - exceptions, - ast, + arguments, astutils, - pyobjects, + builtins, + exceptions, fscommands, - arguments, + pynamesdef, + pyobjects, utils, ) +from rope.base.astwrapper import parse, walk class PyFunction(pyobjects.PyFunction): @@ -47,9 +49,9 @@ def _infer_returned(self, args=None): def _handle_special_args(self, pyobjects): if len(pyobjects) == len(self.arguments.args): if self.arguments.vararg: - pyobjects.append(rope.base.builtins.get_list()) + pyobjects.append(builtins.get_list()) if self.arguments.kwarg: - pyobjects.append(rope.base.builtins.get_dict()) + pyobjects.append(builtins.get_dict()) def _set_parameter_pyobjects(self, pyobjects): if pyobjects is not None: @@ -96,9 +98,9 @@ def get_kind(self): if isinstance(self.parent, PyClass): for decorator in self.decorators: pyname = rope.base.evaluate.eval_node(scope, decorator) - if pyname == rope.base.builtins.builtins["staticmethod"]: + if pyname == builtins.builtins["staticmethod"]: return "staticmethod" - if pyname == rope.base.builtins.builtins["classmethod"]: + if pyname == builtins.builtins["classmethod"]: return "classmethod" return "method" return "function" @@ -177,7 +179,7 @@ def __init__(self, pycore, source=None, resource=None, force_errors=False): raise else: source = "\n" - node = ast.parse("\n") + node = parse("\n") self.source_code = source self.star_imports = [] self.visitor_class = _GlobalVisitor @@ -197,7 +199,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 = parse(source_bytes, filename=filename) except SyntaxError as e: raise exceptions.ModuleSyntaxError(filename, e.lineno, e.msg) except UnicodeDecodeError as e: @@ -239,7 +241,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 = parse("\n") super().__init__(pycore, ast_node, resource) def _create_structural_attributes(self): @@ -247,7 +249,7 @@ def _create_structural_attributes(self): modname = rope.base.libutils.modname(self.resource) extension_submodules = self.pycore._builtin_submodules(modname) for name, module in extension_submodules.items(): - result[name] = rope.base.builtins.BuiltinName(module) + result[name] = builtins.BuiltinName(module) if self.resource is None: return result for name, resource in self._get_child_resources().items(): @@ -301,7 +303,7 @@ def _AnnAssign(self, node): self.assigned_ast = node.value self.type_hint = node.annotation - ast.walk(node.target, self) + walk(node.target, self) def _assigned(self, name, assignment=None): self.scope_visitor._assigned(name, assignment) @@ -356,8 +358,8 @@ def _DictComp(self, node): self._GeneratorExp(node) def _NamedExpr(self, node): - ast.walk(node.target, _AssignVisitor(self)) - ast.walk(node.value, self) + walk(node.target, _AssignVisitor(self)) + walk(node.value, self) class _AssignVisitor: @@ -368,8 +370,8 @@ def __init__(self, scope_visitor): def _Assign(self, node): self.assigned_ast = node.value for child_node in node.targets: - ast.walk(child_node, self) - ast.walk(node.value, _ExpressionVisitor(self.scope_visitor)) + walk(child_node, self) + walk(node.value, _ExpressionVisitor(self.scope_visitor)) def _assigned(self, name, assignment=None): self.scope_visitor._assigned(name, assignment) @@ -422,7 +424,7 @@ def _FunctionDef(self, node): for decorator in pyfunction.decorators: if isinstance(decorator, ast.Name) and decorator.id == "property": if isinstance(self, _ClassVisitor): - type_ = rope.base.builtins.Property(pyfunction) + type_ = builtins.Property(pyfunction) arg = pynamesdef.UnboundName( rope.base.pyobjects.PyObject(self.owner_object) ) @@ -446,10 +448,10 @@ def _AsyncFunctionDef(self, node): return self._FunctionDef(node) def _Assign(self, node): - ast.walk(node, _AssignVisitor(self)) + walk(node, _AssignVisitor(self)) def _AnnAssign(self, node): - ast.walk(node, _AnnAssignVisitor(self)) + walk(node, _AnnAssignVisitor(self)) def _AugAssign(self, node): pass @@ -457,7 +459,7 @@ def _AugAssign(self, node): def _For(self, node): self._update_evaluated(node.target, node.iter, ".__iter__().next()") for child in node.body + node.orelse: - ast.walk(child, self) + walk(child, self) def _AsyncFor(self, node): return self._For(node) @@ -494,7 +496,7 @@ def _With(self, node): item.optional_vars, item.context_expr, ".__enter__()" ) for child in node.body: - ast.walk(child, self) + walk(child, self) def _AsyncWith(self, node): return self._With(node) @@ -508,7 +510,7 @@ def _excepthandler(self, node): self._update_evaluated(node.name, type_node, eval_type=True) for child in node.body: - ast.walk(child, self) + walk(child, self) def _ExceptHandler(self, node): self._excepthandler(node) @@ -571,8 +573,8 @@ def _Global(self, node): class _ComprehensionVisitor(_ScopeVisitor): def _comprehension(self, node): - ast.walk(node.target, self) - ast.walk(node.iter, self) + walk(node.target, self) + walk(node.iter, self) def _Name(self, node): if isinstance(node.ctx, ast.Store): @@ -599,8 +601,8 @@ def _FunctionDef(self, node): if isinstance(first, ast.arg): new_visitor = _ClassInitVisitor(self, first.arg) if new_visitor is not None: - for child in ast.get_child_nodes(node): - ast.walk(child, new_visitor) + for child in astutils.get_child_nodes(node): + walk(child, new_visitor) class _FunctionVisitor(_ScopeVisitor): @@ -642,8 +644,8 @@ def _Attribute(self, node): def _Tuple(self, node): if not isinstance(node.ctx, ast.Store): return - for child in ast.get_child_nodes(node): - ast.walk(child, self) + for child in astutils.get_child_nodes(node): + walk(child, self) def _Name(self, node): pass diff --git a/rope/base/pyscopes.py b/rope/base/pyscopes.py index 74e16b415..099e87111 100644 --- a/rope/base/pyscopes.py +++ b/rope/base/pyscopes.py @@ -1,7 +1,8 @@ import rope.base.builtins import rope.base.codeanalyze import rope.base.pynames -from rope.base import ast, exceptions, utils +from rope.base import astutils, exceptions, utils +from rope.base.astwrapper import walk from rope.refactor import patchedast @@ -186,8 +187,8 @@ def get_names(self): def _visit_comprehension(self): if self.names is None: new_visitor = self.visitor(self.pycore, self.pyobject) - for node in ast.get_child_nodes(self.pyobject.get_ast()): - ast.walk(node, new_visitor) + for node in astutils.get_child_nodes(self.pyobject.get_ast()): + walk(node, new_visitor) self.names = dict(self.parent.get_names()) self.names.update(new_visitor.names) self.defineds = new_visitor.defineds @@ -218,8 +219,8 @@ def _get_names(self): def _visit_function(self): if self.names is None: new_visitor = self.visitor(self.pycore, self.pyobject) - for n in ast.get_child_nodes(self.pyobject.get_ast()): - ast.walk(n, new_visitor) + for n in astutils.get_child_nodes(self.pyobject.get_ast()): + walk(n, new_visitor) self.names = new_visitor.names self.names.update(self.pyobject.get_parameters()) self.returned_asts = new_visitor.returned_asts diff --git a/rope/contrib/autoimport/parse.py b/rope/contrib/autoimport/parse.py index 1e4cb6bde..b4ad6d2f5 100644 --- a/rope/contrib/autoimport/parse.py +++ b/rope/contrib/autoimport/parse.py @@ -3,7 +3,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,8 +20,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 9d533195b..e91440d93 100644 --- a/rope/contrib/finderrors.py +++ b/rope/contrib/finderrors.py @@ -23,7 +23,10 @@ * ... ;-) """ -from rope.base import ast, evaluate, pyobjects +import ast + +from rope.base import evaluate, pyobjects +from rope.base.astwrapper import walk def find_errors(project, resource): @@ -33,7 +36,7 @@ def find_errors(project, resource): """ pymodule = project.get_pymodule(resource) finder = _BadAccessFinder(pymodule) - ast.walk(pymodule.get_ast(), finder) + walk(pymodule.get_ast(), finder) return finder.errors @@ -60,7 +63,7 @@ def _Attribute(self, node): if pyname is not None and pyname.get_object() != pyobjects.get_unknown(): if node.attr not in pyname.get_object(): self._add_error(node, "Unresolved attribute") - ast.walk(node.value, self) + walk(node.value, self) def _add_error(self, node, msg): if isinstance(node, ast.Attribute): diff --git a/rope/refactor/extract.py b/rope/refactor/extract.py index 7c9edda64..5a0d40133 100644 --- a/rope/refactor/extract.py +++ b/rope/refactor/extract.py @@ -1,8 +1,10 @@ +import ast import re from contextlib import contextmanager from itertools import chain -from rope.base import ast, codeanalyze +from rope.base import astutils, codeanalyze +from rope.base.astwrapper import parse, walk from rope.base.change import ChangeSet, ChangeContents from rope.base.exceptions import RefactoringError from rope.base.utils.datastructures import OrderedSet @@ -589,7 +591,7 @@ def _create_info_collector(self): ) body = self.info.source[self.info.scope_region[0] : self.info.scope_region[1]] node = _parse_text(body) - ast.walk(node, info_collector) + walk(node, info_collector) return info_collector def _get_function_definition(self): @@ -755,7 +757,7 @@ def _insert_globals(self, unindented_body): def _get_globals_in_body(unindented_body): node = _parse_text(unindented_body) visitor = _GlobalFinder() - ast.walk(node, visitor) + walk(node, visitor) return visitor.globals_ @@ -822,12 +824,12 @@ def _FunctionDef(self, node): for name in _get_argnames(node.args): self._written_variable(name, node.lineno) for child in node.body: - ast.walk(child, self) + walk(child, self) else: self._written_variable(node.name, node.lineno) visitor = _VariableReadsAndWritesFinder() for child in node.body: - ast.walk(child, visitor) + walk(child, visitor) for name in visitor.read - visitor.written: self._read_variable(name, node.lineno) @@ -846,21 +848,21 @@ def _Name(self, node): def _MatchAs(self, node): self._written_variable(node.name, node.lineno) if node.pattern: - ast.walk(node.pattern, self) + walk(node.pattern, self) def _Assign(self, node): - ast.walk(node.value, self) + walk(node.value, self) for child in node.targets: - ast.walk(child, self) + walk(child, self) def _AugAssign(self, node): - ast.walk(node.value, self) + walk(node.value, self) if isinstance(node.target, ast.Name): target_id = node.target.id self._read_variable(target_id, node.target.lineno) self._written_variable(target_id, node.target.lineno) else: - ast.walk(node.target, self) + walk(node.target, self) def _ClassDef(self, node): self._written_variable(node.name, node.lineno) @@ -882,8 +884,8 @@ def _comp_exp(self, node): written = OrderedSet(self.written) maybe_written = OrderedSet(self.maybe_written) - for child in ast.get_child_nodes(node): - ast.walk(child, self) + for child in astutils.get_child_nodes(node): + walk(child, self) comp_names = list( chain.from_iterable( @@ -914,18 +916,18 @@ def _While(self, node): def _For(self, node): with self._handle_loop_context(node), self._handle_conditional_context(node): # iter has to be checked before the target variables - ast.walk(node.iter, self) - ast.walk(node.target, self) + walk(node.iter, self) + walk(node.target, self) for child in node.body: - ast.walk(child, self) + walk(child, self) for child in node.orelse: - ast.walk(child, self) + walk(child, self) def _handle_conditional_node(self, node): with self._handle_conditional_context(node): - for child in ast.get_child_nodes(node): - ast.walk(child, self) + for child in astutils.get_child_nodes(node): + walk(child, self) @contextmanager def _handle_conditional_context(self, node): @@ -969,8 +971,8 @@ def _Name(self, node): def _FunctionDef(self, node): self.written.add(node.name) visitor = _VariableReadsAndWritesFinder() - for child in ast.get_child_nodes(node): - ast.walk(child, visitor) + for child in astutils.get_child_nodes(node): + walk(child, visitor) self.read.update(visitor.read - visitor.written) def _Class(self, node): @@ -982,7 +984,7 @@ def find_reads_and_writes(code): return set(), set() node = _parse_text(code) visitor = _VariableReadsAndWritesFinder() - ast.walk(node, visitor) + walk(node, visitor) return visitor.read, visitor.written @staticmethod @@ -991,7 +993,7 @@ def find_reads_for_one_liners(code): return set(), set() node = _parse_text(code) visitor = _VariableReadsAndWritesFinder() - ast.walk(node, visitor) + walk(node, visitor) return visitor.read @@ -1002,7 +1004,7 @@ def has_errors(cls, code): return False node = _parse_text(code) visitor = cls() - ast.walk(node, visitor) + walk(node, visitor) return visitor.error @@ -1020,14 +1022,14 @@ def _While(self, node): def loop_encountered(self, node): self.loop_count += 1 for child in node.body: - ast.walk(child, self) + walk(child, self) self.loop_count -= 1 if node.orelse: if isinstance(node.orelse, (list, tuple)): for node_ in node.orelse: - ast.walk(node_, self) + walk(node_, self) else: - ast.walk(node.orelse, self) + walk(node.orelse, self) def _Break(self, node): self.check_loop() @@ -1078,13 +1080,13 @@ def _get_function_kind(scope): def _parse_text(body): body = sourceutils.fix_indentation(body, 0) try: - node = ast.parse(body) + node = parse(body) except SyntaxError: # needed to parse expression containing := operator try: - node = ast.parse("(" + body + ")") + node = parse("(" + body + ")") except SyntaxError: - node = ast.parse( + node = parse( "async def __rope_placeholder__():\n" + sourceutils.fix_indentation(body, 4) ) diff --git a/rope/refactor/importutils/module_imports.py b/rope/refactor/importutils/module_imports.py index 39cb718f6..78ad95683 100644 --- a/rope/refactor/importutils/module_imports.py +++ b/rope/refactor/importutils/module_imports.py @@ -1,6 +1,8 @@ +import ast from typing import Union, List -from rope.base import ast, exceptions, pynames, pynamesdef, utils +from rope.base import astutils, exceptions, pynames, pynamesdef, utils +from rope.base.astwrapper import walk from rope.refactor.importutils import actions, importinfo @@ -26,7 +28,7 @@ def imports(self): def _get_unbound_names(self, defined_pyobject): visitor = _GlobalUnboundNameFinder(self.pymodule, defined_pyobject) - ast.walk(self.pymodule.get_ast(), visitor) + walk(self.pymodule.get_ast(), visitor) return visitor.unbound def _get_all_star_list(self, pymodule): @@ -427,8 +429,8 @@ def _visit_child_scope(self, node): .pyobject ) visitor = _LocalUnboundNameFinder(pyobject, self) - for child in ast.get_child_nodes(node): - ast.walk(child, visitor) + for child in astutils.get_child_nodes(node): + walk(child, visitor) def _FunctionDef(self, node): self._visit_child_scope(node) @@ -453,7 +455,7 @@ def _Attribute(self, node): ): self.add_unbound(primary) else: - ast.walk(node, self) + walk(node, self) def _get_root(self): pass @@ -554,7 +556,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 "", # see comment at rope.base.astwrapper.walk level, self._get_names(node.names), ) diff --git a/rope/refactor/inline.py b/rope/refactor/inline.py index f7fbe3bfe..47512d32a 100644 --- a/rope/refactor/inline.py +++ b/rope/refactor/inline.py @@ -22,7 +22,6 @@ import rope.base.exceptions import rope.refactor.functionutils from rope.base import ( - ast, pynames, pyobjects, codeanalyze, diff --git a/rope/refactor/patchedast.py b/rope/refactor/patchedast.py index c545f1a6f..d79b55711 100644 --- a/rope/refactor/patchedast.py +++ b/rope/refactor/patchedast.py @@ -1,10 +1,12 @@ +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 astutils, codeanalyze, exceptions +from rope.base.astwrapper import parse COMMA_IN_WITH_PATTERN = re.compile(r"\(.*?\)|(,)") @@ -16,7 +18,7 @@ def get_patched_ast(source, sorted_children=False): Adds ``sorted_children`` field only if `sorted_children` is True. """ - return patch_ast(ast.parse(source), source, sorted_children) + return patch_ast(parse(source), source, sorted_children) def patch_ast(node, source, sorted_children=False): @@ -35,7 +37,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) + astutils.call_for_nodes(node, walker) return node @@ -90,7 +92,7 @@ def __call__(self, node): ) node.region = (self.source.offset, self.source.offset) if self.children: - node.sorted_children = ast.get_children(node) + node.sorted_children = astutils.get_children(node) def _handle(self, node, base_children, eat_parens=False, eat_spaces=False): if hasattr(node, "region"): @@ -115,7 +117,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) + astutils.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 ac46223f8..409e3d025 100644 --- a/rope/refactor/restructure.py +++ b/rope/refactor/restructure.py @@ -1,7 +1,13 @@ import warnings -from rope.base import change, taskhandle, builtins, ast, codeanalyze -from rope.base import libutils +from rope.base import ( + astutils, + builtins, + change, + codeanalyze, + libutils, + taskhandle, +) from rope.refactor import patchedast, similarfinder, sourceutils from rope.refactor.importutils import module_imports @@ -206,7 +212,7 @@ def _evaluate(self, code, is_pyname=True): class _BuiltinsStub: def get_attribute(self, name): - return builtins.builtins[name] + return builtins.builtins[name] # pylint: disable=no-member pyobject = _BuiltinsStub() else: @@ -310,7 +316,7 @@ def _auto_indent(self, offset, text): def _get_nearest_roots(self, node): if node not in self._nearest_roots: result = [] - for child in ast.get_child_nodes(node): + for child in astutils.get_child_nodes(node): if child in self.matched_asts: result.append(child) else: diff --git a/rope/refactor/similarfinder.py b/rope/refactor/similarfinder.py index 5bc042587..2c73a3a50 100644 --- a/rope/refactor/similarfinder.py +++ b/rope/refactor/similarfinder.py @@ -1,9 +1,11 @@ """This module can be used for finding similar code""" +import ast import re import rope.refactor.wildcards from rope.base import libutils -from rope.base import codeanalyze, exceptions, ast, builtins +from rope.base import astutils, builtins, codeanalyze, exceptions +from rope.base.astwrapper import parse from rope.refactor import patchedast, wildcards from rope.refactor.patchedast import MismatchedTokenError @@ -72,10 +74,10 @@ class RawSimilarFinder: def __init__(self, source, node=None, does_match=None): if node is None: try: - node = ast.parse(source) + node = parse(source) except SyntaxError: # needed to parse expression containing := operator - node = ast.parse("(" + source + ")") + node = parse("(" + source + ")") if does_match is None: self.does_match = self._simple_does_match else: @@ -119,7 +121,7 @@ def _get_matched_asts(self, code): def _create_pattern(self, expression): expression = self._replace_wildcards(expression) - node = ast.parse(expression) + node = parse(expression) # Getting Module.Stmt.nodes nodes = node.body if len(nodes) == 1 and isinstance(nodes[0], ast.Expr): @@ -154,7 +156,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) + astutils.call_for_nodes(self.body, self._check_node, recursive=True) return self.matches def _check_node(self, node): @@ -169,7 +171,7 @@ def _check_expression(self, node): self.matches.append(ExpressionMatch(node, mapping)) def _check_statements(self, node): - for child in ast.get_children(node): + for child in astutils.get_children(node): if isinstance(child, (list, tuple)): self.__check_stmt_list(child) @@ -211,7 +213,7 @@ def _match_nodes(self, expected, node, mapping): def _get_children(self, node): """Return not `ast.expr_context` children of `node`""" - children = ast.get_children(node) + children = astutils.get_children(node) return [child for child in children if not isinstance(child, ast.expr_context)] def _match_stmts(self, current_stmts, mapping): diff --git a/rope/refactor/suites.py b/rope/refactor/suites.py index 6e7eb454e..3f03cbd00 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.astwrapper import walk def find_visible(node, lines): @@ -71,7 +72,7 @@ def get_children(self): if self._children is None: walker = _SuiteWalker(self) for child in self.child_nodes: - ast.walk(child, walker) + walk(child, walker) self._children = walker.suites return self._children diff --git a/rope/refactor/usefunction.py b/rope/refactor/usefunction.py index 6a9fdd200..b9f0b751e 100644 --- a/rope/refactor/usefunction.py +++ b/rope/refactor/usefunction.py @@ -1,5 +1,15 @@ -from rope.base import change, taskhandle, evaluate, exceptions, pyobjects, pynames, ast +import ast +from rope.base import ( + astutils, + change, + evaluate, + exceptions, + pynames, + pyobjects, + taskhandle, +) from rope.base import libutils +from rope.base.astwrapper import walk from rope.refactor import restructure, sourceutils, similarfinder @@ -197,6 +207,6 @@ def _ClassDef(self, node): def start_walking(self, node): nodes = [node] if isinstance(node, ast.FunctionDef): - nodes = ast.get_child_nodes(node) + nodes = astutils.get_child_nodes(node) for child in nodes: - ast.walk(child, self) + walk(child, self) diff --git a/rope/refactor/wildcards.py b/rope/refactor/wildcards.py index 5d7260dfc..4a57a8aba 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 evaluate, builtins, pyobjects from rope.refactor import patchedast, occurrences diff --git a/ropetest/contrib/autoimport/conftest.py b/ropetest/contrib/autoimport/conftest.py index b0aaa6d0d..f50a4f6c9 100644 --- a/ropetest/contrib/autoimport/conftest.py +++ b/ropetest/contrib/autoimport/conftest.py @@ -1,9 +1,9 @@ import pathlib -import pytest - from ropetest import testutils +import pytest + @pytest.fixture def project(): diff --git a/ropetest/refactor/patchedasttest.py b/ropetest/refactor/patchedasttest.py index d24f2c5aa..af0ac684b 100644 --- a/ropetest/refactor/patchedasttest.py +++ b/ropetest/refactor/patchedasttest.py @@ -1,8 +1,9 @@ +import ast import unittest import sys from textwrap import dedent -from rope.base import ast +from rope.base import astutils from rope.refactor import patchedast from ropetest import testutils @@ -12,10 +13,10 @@ class PatchedASTTest(unittest.TestCase): - def setUp(self): + def setUp(self): # pylint: disable=useless-super-delegation super().setUp() - def tearDown(self): + def tearDown(self): # pylint: disable=useless-super-delegation super().tearDown() def assert_single_case_match_block(self, checker, match_type): @@ -1651,7 +1652,7 @@ def __call__(self, node): return self.result is not None search = Search() - ast.call_for_nodes(self.ast, search, recursive=True) + astutils.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..83d5263ba 100644 --- a/ropetest/refactor/suitestest.py +++ b/ropetest/refactor/suitestest.py @@ -2,16 +2,16 @@ import unittest -from rope.base import ast +from rope.base import astwrapper from rope.refactor import suites from ropetest import testutils class SuiteTest(unittest.TestCase): - def setUp(self): + def setUp(self): # pylint: disable=useless-super-delegation super().setUp() - def tearDown(self): + def tearDown(self): # pylint: disable=useless-super-delegation super().tearDown() def test_trivial_case(self): @@ -218,4 +218,4 @@ def test_match_case(self): def source_suite_tree(source): - return suites.ast_suite_tree(ast.parse(source)) + return suites.ast_suite_tree(astwrapper.parse(source)) From da456d3462ff1c2865b8a2c2c4198c718e3b543f Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Thu, 8 Dec 2022 13:04:27 -0600 Subject: [PATCH 02/13] Blacken and fix pylint complaints --- rope/base/arguments.py | 7 ++- rope/base/astutils.py | 5 ++ rope/base/astwrapper.py | 2 - rope/base/evaluate.py | 1 - rope/base/oi/soa.py | 4 +- rope/base/pyobjectsdef.py | 62 +++++++++++-------------- ropetest/contrib/autoimport/conftest.py | 3 +- 7 files changed, 39 insertions(+), 45 deletions(-) diff --git a/rope/base/arguments.py b/rope/base/arguments.py index 381391647..fa8213d77 100644 --- a/rope/base/arguments.py +++ b/rope/base/arguments.py @@ -106,9 +106,8 @@ def _is_method_call(primary, pyfunction): and isinstance(pyfunction.parent, pyobjects.PyClass) ): return True - if ( - isinstance(pyobject.get_type(), pyobjects.AbstractClass) - and isinstance(pyfunction, builtins.BuiltinFunction) # pylint: disable=no-member - ): + if isinstance(pyobject.get_type(), pyobjects.AbstractClass) and isinstance( + pyfunction, builtins.BuiltinFunction + ): # pylint: disable=no-member return True return False diff --git a/rope/base/astutils.py b/rope/base/astutils.py index d47c89021..c3c6cf0f1 100644 --- a/rope/base/astutils.py +++ b/rope/base/astutils.py @@ -2,6 +2,7 @@ from rope.base.astwrapper import walk + class _NodeNameCollector: def __init__(self, levels=None): self.names = [] @@ -45,6 +46,8 @@ def _Attribute(self, node): def _Slice(self, node): self._add_node(node) + + def get_child_nodes(node): if isinstance(node, ast.Module): return node.body @@ -76,6 +79,8 @@ def get_name_levels(node): visitor = _NodeNameCollector() walk(node, visitor) return visitor.names + + def call_for_nodes(node, callback, recursive=False): """If callback returns `True` the child nodes are skipped""" result = callback(node) diff --git a/rope/base/astwrapper.py b/rope/base/astwrapper.py index b83d85541..950e5fd7d 100644 --- a/rope/base/astwrapper.py +++ b/rope/base/astwrapper.py @@ -31,5 +31,3 @@ def walk(node, walker) -> None: return for child in astutils.get_child_nodes(node): walk(child, walker) - - diff --git a/rope/base/evaluate.py b/rope/base/evaluate.py index 62c71479d..4c1fc2885 100644 --- a/rope/base/evaluate.py +++ b/rope/base/evaluate.py @@ -4,7 +4,6 @@ import rope.base.builtins import rope.base.pynames -import rope.base.pyobjects from rope.base import ( astutils, exceptions, diff --git a/rope/base/oi/soa.py b/rope/base/oi/soa.py index 947b7b43f..fa4005009 100644 --- a/rope/base/oi/soa.py +++ b/rope/base/oi/soa.py @@ -88,7 +88,9 @@ def _call(self, pyfunction, args): if after != before: self.follow(pyfunction) # XXX: Maybe we should not call every builtin function - if isinstance(pyfunction, rope.base.builtins.BuiltinFunction): # pylint: disable=no-member + if isinstance( + pyfunction, rope.base.builtins.BuiltinFunction + ): # pylint: disable=no-member pyfunction.get_returned_object(args) def _parameter_objects(self, pyfunction): diff --git a/rope/base/pyobjectsdef.py b/rope/base/pyobjectsdef.py index dd56b4eb1..f85afe8a9 100644 --- a/rope/base/pyobjectsdef.py +++ b/rope/base/pyobjectsdef.py @@ -1,27 +1,26 @@ import ast -import rope.base.builtins -import rope.base.codeanalyze -import rope.base.evaluate -import rope.base.libutils -import rope.base.oi.soi -import rope.base.pyscopes from rope.base import ( arguments, astutils, builtins, + codeanalyze, + evaluate, exceptions, fscommands, + libutils, pynamesdef, pyobjects, + pyscopes, utils, ) +from rope.base.oi import soi from rope.base.astwrapper import parse, walk class PyFunction(pyobjects.PyFunction): def __init__(self, pycore, ast_node, parent): - rope.base.pyobjects.AbstractFunction.__init__(self) - rope.base.pyobjects.PyDefinedObject.__init__(self, pycore, ast_node, parent) + pyobjects.AbstractFunction.__init__(self) + pyobjects.PyDefinedObject.__init__(self, pycore, ast_node, parent) self.arguments = self.ast_node.args self.parameter_pyobjects = pynamesdef._Inferred( self._infer_parameters, self.get_module()._get_concluded_data() @@ -36,15 +35,15 @@ def _create_concluded_attributes(self): return {} def _create_scope(self): - return rope.base.pyscopes.FunctionScope(self.pycore, self, _FunctionVisitor) + return pyscopes.FunctionScope(self.pycore, self, _FunctionVisitor) def _infer_parameters(self): - pyobjects = rope.base.oi.soi.infer_parameter_objects(self) + pyobjects = soi.infer_parameter_objects(self) self._handle_special_args(pyobjects) return pyobjects def _infer_returned(self, args=None): - return rope.base.oi.soi.infer_returned_object(self, args) + return soi.infer_returned_object(self, args) def _handle_special_args(self, pyobjects): if len(pyobjects) == len(self.arguments.args): @@ -97,7 +96,7 @@ def get_kind(self): scope = self.parent.get_scope() if isinstance(self.parent, PyClass): for decorator in self.decorators: - pyname = rope.base.evaluate.eval_node(scope, decorator) + pyname = evaluate.eval_node(scope, decorator) if pyname == builtins.builtins["staticmethod"]: return "staticmethod" if pyname == builtins.builtins["classmethod"]: @@ -116,13 +115,11 @@ def decorators(self): class PyComprehension(pyobjects.PyComprehension): def __init__(self, pycore, ast_node, parent): self.visitor_class = _ComprehensionVisitor - rope.base.pyobjects.PyObject.__init__(self, type_="Comp") - rope.base.pyobjects.PyDefinedObject.__init__(self, pycore, ast_node, parent) + pyobjects.PyObject.__init__(self, type_="Comp") + pyobjects.PyDefinedObject.__init__(self, pycore, ast_node, parent) def _create_scope(self): - return rope.base.pyscopes.ComprehensionScope( - self.pycore, self, _ComprehensionVisitor - ) + return pyscopes.ComprehensionScope(self.pycore, self, _ComprehensionVisitor) def get_kind(self): return "Comprehension" @@ -131,8 +128,8 @@ def get_kind(self): class PyClass(pyobjects.PyClass): def __init__(self, pycore, ast_node, parent): self.visitor_class = _ClassVisitor - rope.base.pyobjects.AbstractClass.__init__(self) - rope.base.pyobjects.PyDefinedObject.__init__(self, pycore, ast_node, parent) + pyobjects.AbstractClass.__init__(self) + pyobjects.PyDefinedObject.__init__(self, pycore, ast_node, parent) self.parent = parent self._superclasses = self.get_module()._get_concluded_data() @@ -153,17 +150,16 @@ def _create_concluded_attributes(self): def _get_bases(self): result = [] for base_name in self.ast_node.bases: - base = rope.base.evaluate.eval_node(self.parent.get_scope(), base_name) + base = evaluate.eval_node(self.parent.get_scope(), base_name) if ( base is not None - and base.get_object().get_type() - == rope.base.pyobjects.get_base_type("Type") + and base.get_object().get_type() == pyobjects.get_base_type("Type") ): result.append(base.get_object()) return result def _create_scope(self): - return rope.base.pyscopes.ClassScope(self.pycore, self) + return pyscopes.ClassScope(self.pycore, self) class PyModule(pyobjects.PyModule): @@ -214,22 +210,22 @@ def _create_concluded_attributes(self): return result def _create_scope(self): - return rope.base.pyscopes.GlobalScope(self.pycore, self) + return pyscopes.GlobalScope(self.pycore, self) @property @utils.saveit def lines(self): """A `SourceLinesAdapter`""" - return rope.base.codeanalyze.SourceLinesAdapter(self.source_code) + return codeanalyze.SourceLinesAdapter(self.source_code) @property @utils.saveit def logical_lines(self): """A `LogicalLinesFinder`""" - return rope.base.codeanalyze.CachingLogicalLineFinder(self.lines) + return codeanalyze.CachingLogicalLineFinder(self.lines) def get_name(self): - return rope.base.libutils.modname(self.resource) if self.resource else "" + return libutils.modname(self.resource) if self.resource else "" class PyPackage(pyobjects.PyPackage): @@ -246,7 +242,7 @@ def __init__(self, pycore, resource=None, force_errors=False): def _create_structural_attributes(self): result = {} - modname = rope.base.libutils.modname(self.resource) + modname = libutils.modname(self.resource) extension_submodules = self.pycore._builtin_submodules(modname) for name, module in extension_submodules.items(): result[name] = builtins.BuiltinName(module) @@ -290,7 +286,7 @@ def get_module(self): return self def get_name(self): - return rope.base.libutils.modname(self.resource) if self.resource else "" + return libutils.modname(self.resource) if self.resource else "" class _AnnAssignVisitor: @@ -425,9 +421,7 @@ def _FunctionDef(self, node): if isinstance(decorator, ast.Name) and decorator.id == "property": if isinstance(self, _ClassVisitor): type_ = builtins.Property(pyfunction) - arg = pynamesdef.UnboundName( - rope.base.pyobjects.PyObject(self.owner_object) - ) + arg = pynamesdef.UnboundName(pyobjects.PyObject(self.owner_object)) def _eval(type_=type_, arg=arg): return type_.get_property_object( @@ -556,9 +550,7 @@ def _ImportFrom(self, node): def _is_ignored_import(self, imported_module): if not self.pycore.project.prefs.get("ignore_bad_imports", False): return False - return not isinstance( - imported_module.get_object(), rope.base.pyobjects.AbstractModule - ) + return not isinstance(imported_module.get_object(), pyobjects.AbstractModule) def _Global(self, node): module = self.get_module() diff --git a/ropetest/contrib/autoimport/conftest.py b/ropetest/contrib/autoimport/conftest.py index f50a4f6c9..51ce09fab 100644 --- a/ropetest/contrib/autoimport/conftest.py +++ b/ropetest/contrib/autoimport/conftest.py @@ -1,8 +1,7 @@ import pathlib -from ropetest import testutils - import pytest +from ropetest import testutils @pytest.fixture From da7067cfdd4d087379c8ce54a623d414287739be Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Fri, 9 Dec 2022 06:26:31 -0600 Subject: [PATCH 03/13] Enable pylint useless-super-delegation. Remove four unnecessary test methods --- .pylintrc | 8 +++++--- ropetest/refactor/patchedasttest.py | 6 ------ ropetest/refactor/suitestest.py | 6 ------ 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/.pylintrc b/.pylintrc index c6c315de6..5049d5b42 100644 --- a/.pylintrc +++ b/.pylintrc @@ -70,8 +70,6 @@ disable= superfluous-parens, unused-import, unused-wildcard-import, - useless-super-delegation, - useless-else-on-loop, #Else clause on loop without a break statement, remove the else and de-indent all the code inside it. unidiomatic-typecheck, wildcard-import, @@ -93,7 +91,11 @@ disable= super-init-not-called, unnecessary-lambda, unsupported-assignment-operation, - + + # Rope: recently enabled checks. + + # useless-super-delegation, + # Leo: Standard suppressions. arguments-renamed, # cursesGui2.py diff --git a/ropetest/refactor/patchedasttest.py b/ropetest/refactor/patchedasttest.py index af0ac684b..f9d0d5d32 100644 --- a/ropetest/refactor/patchedasttest.py +++ b/ropetest/refactor/patchedasttest.py @@ -13,12 +13,6 @@ class PatchedASTTest(unittest.TestCase): - def setUp(self): # pylint: disable=useless-super-delegation - super().setUp() - - def tearDown(self): # pylint: disable=useless-super-delegation - super().tearDown() - def assert_single_case_match_block(self, checker, match_type): checker.check_children("Match", [ "match", diff --git a/ropetest/refactor/suitestest.py b/ropetest/refactor/suitestest.py index 83d5263ba..f61dc12e3 100644 --- a/ropetest/refactor/suitestest.py +++ b/ropetest/refactor/suitestest.py @@ -8,12 +8,6 @@ class SuiteTest(unittest.TestCase): - def setUp(self): # pylint: disable=useless-super-delegation - super().setUp() - - def tearDown(self): # pylint: disable=useless-super-delegation - super().tearDown() - def test_trivial_case(self): root = source_suite_tree("") self.assertEqual(1, root.get_start()) From 676611d6f4bf88e3b5f813bfeec8d386591fb878 Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Fri, 9 Dec 2022 06:34:52 -0600 Subject: [PATCH 04/13] Fix pylint complaint --- ropetest/contrib/codeassisttest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ropetest/contrib/codeassisttest.py b/ropetest/contrib/codeassisttest.py index f1eaf3e7b..6fd2e6cef 100644 --- a/ropetest/contrib/codeassisttest.py +++ b/ropetest/contrib/codeassisttest.py @@ -1341,7 +1341,8 @@ def _underlined_func(): def tearDown(self): testutils.remove_project(self.project) - super(self.__class__, self).tearDown() + # super(self.__class__, self).tearDown() + super().tearDown() def _assist(self, code, resource=None, **kwds): return code_assist(self.project, code, len(code), resource, **kwds) From ca47c860a7f403ac466409b2c5f2a543c7de7b7c Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Fri, 9 Dec 2022 06:39:09 -0600 Subject: [PATCH 05/13] Remove commented-out code --- ropetest/contrib/codeassisttest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ropetest/contrib/codeassisttest.py b/ropetest/contrib/codeassisttest.py index 6fd2e6cef..24503d09a 100644 --- a/ropetest/contrib/codeassisttest.py +++ b/ropetest/contrib/codeassisttest.py @@ -1341,7 +1341,6 @@ def _underlined_func(): def tearDown(self): testutils.remove_project(self.project) - # super(self.__class__, self).tearDown() super().tearDown() def _assist(self, code, resource=None, **kwds): From 89995312ea893c9a4e3900cd1935948873e54c48 Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Fri, 9 Dec 2022 06:45:48 -0600 Subject: [PATCH 06/13] Fix/suppress more pylint warnings --- .pylintrc | 1 + ropetest/pycoretest.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.pylintrc b/.pylintrc index 5049d5b42..b250311f7 100644 --- a/.pylintrc +++ b/.pylintrc @@ -60,6 +60,7 @@ disable= modified-iterating-list, used-before-assignment, unsubscriptable-object, + use-sequence-for-iteration, unpacking-non-sequence, # Rope: to be removed. diff --git a/ropetest/pycoretest.py b/ropetest/pycoretest.py index 4ae90c369..7a0a7833b 100644 --- a/ropetest/pycoretest.py +++ b/ropetest/pycoretest.py @@ -776,7 +776,7 @@ def test_pyobject_equality_should_compare_types(self): class PyCoreInProjectsTest(unittest.TestCase): def setUp(self): - super(self.__class__, self).setUp() + super().setUp() self.project = testutils.sample_project() self.pycore = self.project.pycore samplemod = testutils.create_module(self.project, "samplemod") @@ -799,7 +799,7 @@ def _underlined_func(): def tearDown(self): testutils.remove_project(self.project) - super(self.__class__, self).tearDown() + super().tearDown() def test_simple_import(self): code = "import samplemod\n" From 849891c7d74dace6c1601803c8857f65245359d6 Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Fri, 9 Dec 2022 08:55:49 -0600 Subject: [PATCH 07/13] Fix three pylint complaints. All tests still pass. --- ropetest/projecttest.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/ropetest/projecttest.py b/ropetest/projecttest.py index 1a66bfd3d..ff71f0171 100644 --- a/ropetest/projecttest.py +++ b/ropetest/projecttest.py @@ -1,8 +1,7 @@ import os.path import shutil from textwrap import dedent - -import pytest +import unittest from rope.base.exceptions import RopeError, ResourceNotFoundError from rope.base.fscommands import FileSystemCommands @@ -12,9 +11,6 @@ from ropetest import testutils -import unittest - - class ProjectTest(unittest.TestCase): def setUp(self): unittest.TestCase.setUp(self) @@ -1011,7 +1007,7 @@ def test_none_project_rope_folder(self): def test_getting_project_rope_folder(self): self.project = testutils.sample_project(ropefolder=".ropeproject") self.assertTrue(self.project.ropefolder.exists()) - self.assertTrue(".ropeproject", self.project.ropefolder.path) + self.assertEqual(".ropeproject", self.project.ropefolder.path) def test_setting_ignored_resources(self): self.project = testutils.sample_project(ignored_resources=["myfile.txt"]) @@ -1063,7 +1059,7 @@ def test_normal_fscommands(self): self.project = testutils.sample_project(fscommands=fscommands) myfile = self.project.get_file("myfile.txt") myfile.create() - self.assertTrue("create_file ", fscommands.log) + self.assertEqual("create_file ", fscommands.log) def test_fscommands_and_ignored_resources(self): fscommands = _MockFSCommands() @@ -1079,7 +1075,7 @@ def test_deprecated_fscommands(self): self.project = testutils.sample_project(fscommands=fscommands) myfile = self.project.get_file("myfile.txt") myfile.create() - self.assertTrue("create_file ", fscommands.log) + self.assertEqual("create_file ", fscommands.log) def test_ignored_resources_and_prefixes(self): self.project = testutils.sample_project(ignored_resources=[".hg"]) From 68bc9477f4f566be47f01fe6f01318a11c45d6ee Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Fri, 9 Dec 2022 09:09:40 -0600 Subject: [PATCH 08/13] Remove recently-added (unnecessary!) pylint no-member suppressions --- rope/base/arguments.py | 2 +- rope/base/builtins.py | 2 +- rope/base/oi/soa.py | 12 ++++++++---- rope/refactor/restructure.py | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/rope/base/arguments.py b/rope/base/arguments.py index fa8213d77..b92f5cdde 100644 --- a/rope/base/arguments.py +++ b/rope/base/arguments.py @@ -108,6 +108,6 @@ def _is_method_call(primary, pyfunction): return True if isinstance(pyobject.get_type(), pyobjects.AbstractClass) and isinstance( pyfunction, builtins.BuiltinFunction - ): # pylint: disable=no-member + ): return True return False diff --git a/rope/base/builtins.py b/rope/base/builtins.py index 93582b77e..497463d20 100644 --- a/rope/base/builtins.py +++ b/rope/base/builtins.py @@ -40,7 +40,7 @@ def attributes(self): if self.pycore is not None: submodules = self.pycore._builtin_submodules(self.name) for name, module in submodules.items(): - result[name] = BuiltinName(module) # pylint: disable=no-member + result[name] = BuiltinName(module) return result @property diff --git a/rope/base/oi/soa.py b/rope/base/oi/soa.py index fa4005009..9af1c1a72 100644 --- a/rope/base/oi/soa.py +++ b/rope/base/oi/soa.py @@ -2,7 +2,13 @@ import rope.base.oi.soi import rope.base.pynames from rope.base.astwrapper import walk -from rope.base import arguments, astutils, evaluate, pyobjects +from rope.base import ( + arguments, + astutils, + builtins, + evaluate, + pyobjects, +) def analyze_module(pycore, pymodule, should_analyze, search_subscopes, followed_calls): @@ -88,9 +94,7 @@ def _call(self, pyfunction, args): if after != before: self.follow(pyfunction) # XXX: Maybe we should not call every builtin function - if isinstance( - pyfunction, rope.base.builtins.BuiltinFunction - ): # pylint: disable=no-member + if isinstance(pyfunction, builtins.BuiltinFunction): pyfunction.get_returned_object(args) def _parameter_objects(self, pyfunction): diff --git a/rope/refactor/restructure.py b/rope/refactor/restructure.py index 409e3d025..e34bbcae2 100644 --- a/rope/refactor/restructure.py +++ b/rope/refactor/restructure.py @@ -212,7 +212,7 @@ def _evaluate(self, code, is_pyname=True): class _BuiltinsStub: def get_attribute(self, name): - return builtins.builtins[name] # pylint: disable=no-member + return builtins.builtins[name] pyobject = _BuiltinsStub() else: From a75ed271f947df6df2cb83d20b3b2cc01ce06e85 Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Fri, 9 Dec 2022 09:37:24 -0600 Subject: [PATCH 09/13] Clean up/alphabetize imports --- rope/base/evaluate.py | 2 +- rope/base/libutils.py | 4 +--- rope/base/oi/soi.py | 2 +- rope/base/pycore.py | 15 ++++++++------- rope/base/resources.py | 4 +--- rope/base/taskhandle.py | 2 +- rope/contrib/autoimport/pickle.py | 18 ++++++++++-------- rope/contrib/autoimport/sqlite.py | 7 ++++++- rope/contrib/codeassist.py | 20 +++++++++++--------- rope/contrib/findit.py | 2 +- rope/contrib/fixsyntax.py | 10 ++++++---- rope/contrib/generate.py | 11 +++++++++-- rope/refactor/change_signature.py | 14 ++++++++------ rope/refactor/encapsulate_field.py | 16 +++++++++------- rope/refactor/inline.py | 8 ++++---- rope/refactor/introduce_factory.py | 3 +-- rope/refactor/introduce_parameter.py | 7 ++++++- rope/refactor/localtofield.py | 7 ++++++- rope/refactor/method_object.py | 10 ++++++++-- rope/refactor/move.py | 6 +++--- rope/refactor/multiproject.py | 2 +- 21 files changed, 102 insertions(+), 68 deletions(-) diff --git a/rope/base/evaluate.py b/rope/base/evaluate.py index 4c1fc2885..01fb75163 100644 --- a/rope/base/evaluate.py +++ b/rope/base/evaluate.py @@ -5,11 +5,11 @@ import rope.base.builtins import rope.base.pynames from rope.base import ( + arguments, astutils, exceptions, pyobjects, pyobjectsdef, - arguments, worder, ) from rope.base.astwrapper import parse, walk diff --git a/rope/base/libutils.py b/rope/base/libutils.py index 4c966ccae..c2c1d3f77 100644 --- a/rope/base/libutils.py +++ b/rope/base/libutils.py @@ -3,9 +3,7 @@ import rope.base.project import rope.base.pycore -from rope.base import pyobjectsdef -from rope.base import utils -from rope.base import taskhandle +from rope.base import pyobjectsdef, taskhandle, utils def path_to_resource(project, path, type=None): diff --git a/rope/base/oi/soi.py b/rope/base/oi/soi.py index 2cecdf8b1..4886864bd 100644 --- a/rope/base/oi/soi.py +++ b/rope/base/oi/soi.py @@ -7,7 +7,7 @@ import rope.base.builtins import rope.base.pynames import rope.base.pyobjects -from rope.base import evaluate, utils, arguments +from rope.base import arguments, evaluate, utils from rope.base.oi.type_hinting.factory import get_type_hinting_factory diff --git a/rope/base/pycore.py b/rope/base/pycore.py index 7428bc1ee..abab0120e 100644 --- a/rope/base/pycore.py +++ b/rope/base/pycore.py @@ -8,13 +8,14 @@ import rope.base.oi.doa import rope.base.oi.objectinfo import rope.base.oi.soa -from rope.base import builtins -from rope.base import exceptions -from rope.base import pyobjectsdef -from rope.base import stdmods -from rope.base import taskhandle -from rope.base import utils -from rope.base.exceptions import ModuleNotFoundError +from rope.base import ( + builtins, + exceptions, + pyobjectsdef, + stdmods, + taskhandle, + utils, +) class PyCore: diff --git a/rope/base/resources.py b/rope/base/resources.py index 4a518ed75..31204a48c 100644 --- a/rope/base/resources.py +++ b/rope/base/resources.py @@ -30,9 +30,7 @@ import re import warnings -from rope.base import change -from rope.base import exceptions -from rope.base import fscommands +from rope.base import change, exceptions, fscommands from pathlib import Path diff --git a/rope/base/taskhandle.py b/rope/base/taskhandle.py index 8c49ec947..afcb97ed0 100644 --- a/rope/base/taskhandle.py +++ b/rope/base/taskhandle.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod from typing import Optional, Sequence -from rope.base import utils, exceptions +from rope.base import exceptions, utils class BaseJobSet(ABC): diff --git a/rope/contrib/autoimport/pickle.py b/rope/contrib/autoimport/pickle.py index 893900e35..ef733947a 100644 --- a/rope/contrib/autoimport/pickle.py +++ b/rope/contrib/autoimport/pickle.py @@ -12,14 +12,16 @@ import re -from rope.base import builtins -from rope.base import exceptions -from rope.base import libutils -from rope.base import pynames -from rope.base import pyobjects -from rope.base import resources -from rope.base import resourceobserver -from rope.base import taskhandle +from rope.base import ( + builtins, + exceptions, + libutils, + pynames, + pyobjects, + resourceobserver, + resources, + taskhandle, +) from rope.refactor import importutils diff --git a/rope/contrib/autoimport/sqlite.py b/rope/contrib/autoimport/sqlite.py index f778eac0b..381aa99e0 100644 --- a/rope/contrib/autoimport/sqlite.py +++ b/rope/contrib/autoimport/sqlite.py @@ -8,7 +8,12 @@ from pathlib import Path from typing import Generator, Iterable, List, Optional, Set, Tuple, Iterator -from rope.base import exceptions, libutils, resourceobserver, taskhandle +from rope.base import ( + exceptions, + libutils, + resourceobserver, + taskhandle, +) from rope.base.project import Project from rope.base.resources import Resource from rope.contrib.autoimport.defs import ( diff --git a/rope/contrib/codeassist.py b/rope/contrib/codeassist.py index 334c78c4a..1c28e1883 100644 --- a/rope/contrib/codeassist.py +++ b/rope/contrib/codeassist.py @@ -4,15 +4,17 @@ import rope.base.codeanalyze import rope.base.evaluate -from rope.base import builtins -from rope.base import exceptions -from rope.base import libutils -from rope.base import pynames -from rope.base import pynamesdef -from rope.base import pyobjects -from rope.base import pyobjectsdef -from rope.base import pyscopes -from rope.base import worder +from rope.base import ( + builtins, + exceptions, + libutils, + pynames, + pynamesdef, + pyobjects, + pyobjectsdef, + pyscopes, + worder, +) from rope.contrib import fixsyntax from rope.refactor import functionutils diff --git a/rope/contrib/findit.py b/rope/contrib/findit.py index 027248eb0..5952c1ac8 100644 --- a/rope/contrib/findit.py +++ b/rope/contrib/findit.py @@ -1,7 +1,7 @@ import rope.base.codeanalyze import rope.base.evaluate import rope.base.pyobjects -from rope.base import taskhandle, exceptions, worder +from rope.base import exceptions, taskhandle, worder from rope.contrib import fixsyntax from rope.refactor import occurrences diff --git a/rope/contrib/fixsyntax.py b/rope/contrib/fixsyntax.py index b1e96935e..28c91bb4f 100644 --- a/rope/contrib/fixsyntax.py +++ b/rope/contrib/fixsyntax.py @@ -1,9 +1,11 @@ import rope.base.codeanalyze import rope.base.evaluate -from rope.base import exceptions -from rope.base import libutils -from rope.base import utils -from rope.base import worder +from rope.base import ( + exceptions, + libutils, + utils, + worder, +) from rope.base.codeanalyze import ArrayLinesAdapter, LogicalLineFinder diff --git a/rope/contrib/generate.py b/rope/contrib/generate.py index 0d6b91e35..c2c028c72 100644 --- a/rope/contrib/generate.py +++ b/rope/contrib/generate.py @@ -1,6 +1,13 @@ import rope.base.evaluate -from rope.base import libutils -from rope.base import change, pyobjects, exceptions, pynames, worder, codeanalyze +from rope.base import ( + change, + codeanalyze, + exceptions, + libutils, + pynames, + pyobjects, + worder, +) from rope.refactor import sourceutils, importutils, functionutils, suites diff --git a/rope/refactor/change_signature.py b/rope/refactor/change_signature.py index 15c360cdc..42d6082f1 100644 --- a/rope/refactor/change_signature.py +++ b/rope/refactor/change_signature.py @@ -1,12 +1,14 @@ import copy import rope.base.exceptions -from rope.base import codeanalyze -from rope.base import evaluate -from rope.base import pyobjects -from rope.base import taskhandle -from rope.base import utils -from rope.base import worder +from rope.base import ( + codeanalyze, + evaluate, + pyobjects, + taskhandle, + utils, + worder, +) from rope.base.change import ChangeContents, ChangeSet from rope.refactor import occurrences, functionutils diff --git a/rope/refactor/encapsulate_field.py b/rope/refactor/encapsulate_field.py index 1d454d6e2..ba18b2b54 100644 --- a/rope/refactor/encapsulate_field.py +++ b/rope/refactor/encapsulate_field.py @@ -1,10 +1,12 @@ -from rope.base import evaluate -from rope.base import exceptions -from rope.base import libutils -from rope.base import pynames -from rope.base import taskhandle -from rope.base import utils -from rope.base import worder +from rope.base import ( + evaluate, + exceptions, + libutils, + pynames, + taskhandle, + utils, + worder, +) from rope.base.change import ChangeSet, ChangeContents from rope.refactor import sourceutils, occurrences diff --git a/rope/refactor/inline.py b/rope/refactor/inline.py index 47512d32a..001a33a28 100644 --- a/rope/refactor/inline.py +++ b/rope/refactor/inline.py @@ -22,14 +22,14 @@ import rope.base.exceptions import rope.refactor.functionutils from rope.base import ( + codeanalyze, + evaluate, + libutils, pynames, pyobjects, - codeanalyze, taskhandle, - evaluate, - worder, utils, - libutils, + worder, ) from rope.base.change import ChangeSet, ChangeContents from rope.refactor import ( diff --git a/rope/refactor/introduce_factory.py b/rope/refactor/introduce_factory.py index a36935c9e..a528b97d0 100644 --- a/rope/refactor/introduce_factory.py +++ b/rope/refactor/introduce_factory.py @@ -1,7 +1,6 @@ import rope.base.exceptions import rope.base.pyobjects -from rope.base import libutils -from rope.base import taskhandle, evaluate +from rope.base import evaluate, libutils, taskhandle from rope.base.change import ChangeSet, ChangeContents from rope.refactor import rename, occurrences, sourceutils, importutils diff --git a/rope/refactor/introduce_parameter.py b/rope/refactor/introduce_parameter.py index 5f1446c40..df7310969 100644 --- a/rope/refactor/introduce_parameter.py +++ b/rope/refactor/introduce_parameter.py @@ -1,5 +1,10 @@ import rope.base.change -from rope.base import exceptions, evaluate, worder, codeanalyze +from rope.base import ( + codeanalyze, + exceptions, + evaluate, + worder, +) from rope.refactor import functionutils, sourceutils, occurrences diff --git a/rope/refactor/localtofield.py b/rope/refactor/localtofield.py index ea2c125b9..56a383b8d 100644 --- a/rope/refactor/localtofield.py +++ b/rope/refactor/localtofield.py @@ -1,4 +1,9 @@ -from rope.base import pynames, evaluate, exceptions, worder +from rope.base import ( + evaluate, + exceptions, + pynames, + worder, +) from rope.refactor.rename import Rename diff --git a/rope/refactor/method_object.py b/rope/refactor/method_object.py index e0406b6ee..cada6fcc8 100644 --- a/rope/refactor/method_object.py +++ b/rope/refactor/method_object.py @@ -1,7 +1,13 @@ import warnings -from rope.base import libutils -from rope.base import pyobjects, exceptions, change, evaluate, codeanalyze +from rope.base import ( + change, + codeanalyze, + evaluate, + exceptions, + libutils, + pyobjects, +) from rope.refactor import sourceutils, occurrences, rename diff --git a/rope/refactor/move.py b/rope/refactor/move.py index c4ccd8970..7feacb1c8 100644 --- a/rope/refactor/move.py +++ b/rope/refactor/move.py @@ -5,14 +5,14 @@ """ from rope.base import ( - pyobjects, codeanalyze, + evaluate, exceptions, + libutils, pynames, + pyobjects, taskhandle, - evaluate, worder, - libutils, ) from rope.base.change import ChangeSet, ChangeContents, MoveResource from rope.refactor import importutils, rename, occurrences, sourceutils, functionutils diff --git a/rope/refactor/multiproject.py b/rope/refactor/multiproject.py index a13625dfa..f829de31d 100644 --- a/rope/refactor/multiproject.py +++ b/rope/refactor/multiproject.py @@ -5,7 +5,7 @@ """ -from rope.base import resources, libutils +from rope.base import libutils, resources class MultiProjectRefactoring: From d643366597ecd547ca50a3f7e33f3d9608aa74e4 Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Fri, 9 Dec 2022 09:57:05 -0600 Subject: [PATCH 10/13] Add comments about *difficult* imports in pynames.py --- rope/base/pynames.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rope/base/pynames.py b/rope/base/pynames.py index eaac2ce98..e466d07aa 100644 --- a/rope/base/pynames.py +++ b/rope/base/pynames.py @@ -1,3 +1,4 @@ +# These imports are tricky. It's easy to cause circular imports. from __future__ import annotations import typing @@ -7,6 +8,7 @@ if typing.TYPE_CHECKING: + # pyobjectsdef appears only in annotations. from typing import Union from rope.base import pyobjectsdef From e565a5abc7869bdce00430c51335a7f9c1c3d5ec Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Fri, 9 Dec 2022 13:39:23 -0600 Subject: [PATCH 11/13] Remove 'parse' from rope.base.ast. Not sure how it got there --- rope/base/ast.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/rope/base/ast.py b/rope/base/ast.py index f64a5b3f1..c7add2502 100644 --- a/rope/base/ast.py +++ b/rope/base/ast.py @@ -4,24 +4,6 @@ from rope.base import fscommands -def parse(source, filename=""): - # NOTE: the raw string should be given to `compile` function - if isinstance(source, str): - source = fscommands.unicode_to_file_data(source) - if b"\r" in source: - source = source.replace(b"\r\n", b"\n").replace(b"\r", b"\n") - if not source.endswith(b"\n"): - source += b"\n" - try: - return ast.parse(source, filename="") - except (TypeError, ValueError) as e: - error = SyntaxError() - error.lineno = 1 - error.filename = filename - error.msg = str(e) - raise error - - def call_for_nodes(node, callback, recursive=False): """If callback returns `True` the child nodes are skipped""" result = callback(node) From 4242dc9910336853b28288cc7e925e0297a2f020 Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Fri, 9 Dec 2022 14:02:10 -0600 Subject: [PATCH 12/13] Use astwrapper.parse, not ast.parse in PyModule._init_source --- rope/base/pyobjectsdef.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/rope/base/pyobjectsdef.py b/rope/base/pyobjectsdef.py index 92e9e78c6..d62d24b98 100644 --- a/rope/base/pyobjectsdef.py +++ b/rope/base/pyobjectsdef.py @@ -5,15 +5,16 @@ import rope.base.oi.soi import rope.base.pyscopes from rope.base import ( - pynamesdef, - exceptions, + arguments, ast, astutils, - pyobjects, + exceptions, fscommands, - arguments, + pynamesdef, + pyobjects, utils, ) +from rope.base.astwrapper import parse class PyFunction(pyobjects.PyFunction): @@ -197,7 +198,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 = parse(source_bytes, filename=filename) except SyntaxError as e: raise exceptions.ModuleSyntaxError(filename, e.lineno, e.msg) except UnicodeDecodeError as e: From d7926b2930521a2770fdcde4b1ddd5e5bb1b6417 Mon Sep 17 00:00:00 2001 From: "Edward K. Ream" Date: Fri, 9 Dec 2022 16:10:51 -0600 Subject: [PATCH 13/13] Small cleanups --- rope/base/pyobjectsdef.py | 4 ++-- ropetest/refactor/patchedasttest.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/rope/base/pyobjectsdef.py b/rope/base/pyobjectsdef.py index d62d24b98..2bbbf4d2b 100644 --- a/rope/base/pyobjectsdef.py +++ b/rope/base/pyobjectsdef.py @@ -7,6 +7,7 @@ from rope.base import ( arguments, ast, + astwrapper, astutils, exceptions, fscommands, @@ -14,7 +15,6 @@ pyobjects, utils, ) -from rope.base.astwrapper import parse class PyFunction(pyobjects.PyFunction): @@ -198,7 +198,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 = parse(source_bytes, filename=filename) + ast_node = astwrapper.parse(source_bytes, filename=filename) except SyntaxError as e: raise exceptions.ModuleSyntaxError(filename, e.lineno, e.msg) except UnicodeDecodeError as e: diff --git a/ropetest/refactor/patchedasttest.py b/ropetest/refactor/patchedasttest.py index 33639c1a9..6eee8921b 100644 --- a/ropetest/refactor/patchedasttest.py +++ b/ropetest/refactor/patchedasttest.py @@ -1646,7 +1646,6 @@ def __call__(self, node): return self.result is not None search = Search() - ### astutils.call_for_nodes(self.ast, search, recursive=True) call_for_nodes(self.ast, search, recursive=True) return search.result