def wrap(self, element): if isinstance(element, tree.Class): return er.Class(self, element) elif isinstance(element, tree.Function): if isinstance(element, tree.Lambda): return er.LambdaWrapper(self, element) else: return er.Function(self, element) elif isinstance(element, (tree.Module)) \ and not isinstance(element, er.ModuleWrapper): return er.ModuleWrapper(self, element) else: return element
def eval_statement(self, stmt, seek_name=None): """ The starting point of the completion. A statement always owns a call list, which are the calls, that a statement does. In case multiple names are defined in the statement, `seek_name` returns the result for this name. :param stmt: A `pr.Statement`. """ debug.dbg('eval_statement %s (%s)', stmt, seek_name) expression_list = stmt.expression_list() if isinstance(stmt, FakeStatement): return expression_list # Already contains the results. result = self.eval_expression_list(expression_list) ass_details = stmt.assignment_details if ass_details and ass_details[0][1] != '=' and not isinstance( stmt, er.InstanceElement): # TODO don't check for this. expr_list, operator = ass_details[0] # `=` is always the last character in aug assignments -> -1 operator = operator[:-1] name = str(expr_list[0].name) parent = stmt.parent if isinstance(parent, (pr.SubModule, fast.Module)): parent = er.ModuleWrapper(self, parent) left = self.find_types(parent, name, stmt.start_pos) if isinstance(stmt.parent, pr.ForFlow): # iterate through result and add the values, that's possible # only in for loops without clutter, because they are # predictable. for r in result: left = precedence.calculate(self, left, operator, [r]) result = left else: result = precedence.calculate(self, left, operator, result) elif len(stmt.get_defined_names()) > 1 and seek_name and ass_details: # Assignment checking is only important if the statement defines # multiple variables. new_result = [] for ass_expression_list, op in ass_details: new_result += finder.find_assignments(ass_expression_list[0], result, seek_name) result = new_result return result
def wrap(self, element): if isinstance(element, (er.Wrapper, er.InstanceElement, er.ModuleWrapper, er.FunctionExecution, er.Instance, compiled.CompiledObject)) or element is None: # TODO this is so ugly, please refactor. id:211 gh:212 return element if element.type == 'classdef': return er.Class(self, element) elif element.type == 'funcdef': return er.Function(self, element) elif element.type == 'lambda': return er.LambdaWrapper(self, element) elif element.type == 'file_input': return er.ModuleWrapper(self, element) else: return element
def _names_to_types(self, names, resolve_decorator): types = [] # Add isinstance and other if/assert knowledge. flow_scope = self.scope evaluator = self._evaluator while flow_scope: # TODO check if result is in scope -> no evaluation necessary n = check_flow_information(evaluator, flow_scope, self.name_str, self.position) if n: return n flow_scope = flow_scope.parent for name in names: typ = name.parent if typ.isinstance(pr.ForFlow): types += self._handle_for_loops(typ) elif isinstance(typ, pr.Param): types += self._eval_param(typ) elif typ.isinstance(pr.Statement): if typ.is_global(): # global keyword handling. types += evaluator.find_types(typ.parent.parent, str(name)) else: types += self._remove_statements(typ, name) else: if isinstance(typ, pr.Class): typ = er.Class(evaluator, typ) elif isinstance(typ, pr.Function): typ = er.Function(evaluator, typ) elif isinstance(typ, pr.Module): typ = er.ModuleWrapper(evaluator, typ) if typ.isinstance(er.Function) and resolve_decorator: typ = typ.get_decorated_func() types.append(typ) if not names and isinstance(self.scope, er.Instance): # handling __getattr__ / __getattribute__ types = self._check_getattr(self.scope) return types
def get_names_of_scope(evaluator, scope, position=None, star_search=True, include_builtin=True): """ Get all completions (names) possible for the current scope. The star search option is only here to provide an optimization. Otherwise the whole thing would probably start a little recursive madness. This function is used to include names from outer scopes. For example, when the current scope is function: >>> from jedi._compatibility import u >>> from jedi.parser import Parser >>> parser = Parser(u(''' ... x = ['a', 'b', 'c'] ... def func(): ... y = None ... ''')) >>> scope = parser.module.subscopes[0] >>> scope <Function: func@3-5> `get_names_of_scope` is a generator. First it yields names from most inner scope. >>> from jedi.evaluate import Evaluator >>> pairs = list(get_names_of_scope(Evaluator(), scope)) >>> pairs[0] (<Function: func@3-5>, [<Name: y@4,4>]) Then it yield the names from one level outer scope. For this example, this is the most outer scope. >>> pairs[1] (<ModuleWrapper: <SubModule: None@1-5>>, [<Name: x@2,0>, <Name: func@3,4>]) After that we have a few underscore names that have been defined >>> pairs[2] (<ModuleWrapper: <SubModule: None@1-5>>, [<FakeName: __file__@0,0>, ...]) Finally, it yields names from builtin, if `include_builtin` is true (default). >>> pairs[3] #doctest: +ELLIPSIS (<Builtin: ...builtin...>, [<CompiledName: ...>, ...]) :rtype: [(pr.Scope, [pr.Name])] :return: Return an generator that yields a pair of scope and names. """ if isinstance(scope, pr.ListComprehension): position = scope.parent.start_pos in_func_scope = scope non_flow = scope.get_parent_until(pr.Flow, reverse=True) while scope: # We don't want submodules to report if we have modules. # As well as some non-scopes, which are parents of list comprehensions. if isinstance(scope, pr.SubModule) and scope.parent or not scope.is_scope(): scope = scope.parent continue # `pr.Class` is used, because the parent is never `Class`. # Ignore the Flows, because the classes and functions care for that. # InstanceElement of Class is ignored, if it is not the start scope. if not (scope != non_flow and scope.isinstance(pr.Class) or scope.isinstance(pr.Flow) or scope.isinstance(er.Instance) and non_flow.isinstance(er.Function) or isinstance(scope, compiled.CompiledObject) and scope.type() == 'class' and in_func_scope != scope): if isinstance(scope, (pr.SubModule, fast.Module)): scope = er.ModuleWrapper(evaluator, scope) for g in scope.scope_names_generator(position): yield g if scope.isinstance(pr.ListComprehension): # is a list comprehension yield scope, scope.get_defined_names(is_internal_call=True) scope = scope.parent # This is used, because subscopes (Flow scopes) would distort the # results. if scope and scope.isinstance(er.Function, pr.Function, er.FunctionExecution): in_func_scope = scope if in_func_scope != scope \ and isinstance(in_func_scope, (pr.Function, er.FunctionExecution)): position = None # Add star imports. if star_search: for s in imports.remove_star_imports(evaluator, non_flow.get_parent_until()): for g in get_names_of_scope(evaluator, s, star_search=False): yield g # Add builtins to the global scope. if include_builtin: yield compiled.builtin, compiled.builtin.get_defined_names()