diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 46838e41..1b844f53 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -124,11 +124,19 @@ class Evaluator(object): result = self.eval_expression_list(expression_list) - # Assignment checking is only important if the statement defines multiple - # variables. - if len(stmt.get_set_vars()) > 1 and seek_name and stmt.assignment_details: + ass_details = stmt.assignment_details + if ass_details and ass_details[0][1] != '=' and False: + expr_list, operator = ass_details[0] + name = str(expr_list[0].name) + start_pos = stmt.start_pos[0] - 1, stmt.start_pos[1] + 30000 + left_result = self.find_types(stmt.parent, name, start_pos) + # `=` is always the last character in aug assignments + result = precedence.calculate(left_result, operator[:-1], result) + elif len(stmt.get_set_vars()) > 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 stmt.assignment_details: + for ass_expression_list, op in ass_details: new_result += finder.find_assignments(ass_expression_list[0], result, seek_name) result = new_result return set(result) @@ -277,7 +285,7 @@ class Evaluator(object): # This is the typical lookup while chaining things. if filter_private_variable(typ, scope, current): return [] - types = self.find_types(typ, current, position=position) + types = self.find_types(typ, current, position=None) result = imports.strip_imports(self, types) return self.follow_path(path, set(result), scope, position=position) diff --git a/jedi/evaluate/compiled/__init__.py b/jedi/evaluate/compiled/__init__.py index ed196ae7..caf34a51 100644 --- a/jedi/evaluate/compiled/__init__.py +++ b/jedi/evaluate/compiled/__init__.py @@ -279,6 +279,8 @@ class Builtin(CompiledObject): # access it. return [d for d in super(Builtin, self).get_defined_names() if d.name != 'None'] + get_set_vars = get_defined_names + def _a_generator(foo): """Used to have an object to return for generators.""" diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index e8e4475a..e8b47b39 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -24,7 +24,7 @@ class NameFinder(object): def find(self, scopes, resolve_decorator=True): names = self.filter_name(scopes) types = self._names_to_types(names, resolve_decorator) - debug.dbg('_names_to_types: %s, old: %s', names, types) + debug.dbg('finder._names_to_types: %s, old: %s', names, types) return self._resolve_descriptors(types) def scopes(self, search_global=False): @@ -34,7 +34,7 @@ class NameFinder(object): if isinstance(self.scope, er.Instance): return self.scope.scope_generator() else: - if isinstance(self.scope, (er.Class, pr.Module)): + if isinstance(self.scope, er.Class): # classes are only available directly via chaining? # strange stuff... names = self.scope.get_defined_names() @@ -78,7 +78,7 @@ class NameFinder(object): new_name.parent = r result.append(new_name) - debug.dbg('sfn filter "%s" in (%s-%s): %s@%s', self.name_str, + debug.dbg('finder.filter_name "%s" in (%s-%s): %s@%s', self.name_str, self.scope, nscope, u(result), self.position) return result @@ -105,12 +105,7 @@ class NameFinder(object): """ par = name.parent if par.isinstance(pr.Statement): - details = par.assignment_details - if details and details[0][1] != '=': - return True - - if isinstance(name, er.InstanceElement) \ - and not name.is_class_var: + if isinstance(name, er.InstanceElement) and not name.is_class_var: return True elif isinstance(par, pr.Import) and len(par.namespace) > 1: # TODO multi-level import non-breakable @@ -351,9 +346,9 @@ def _get_defined_names_for_position(scope, position=None, start_scope=None): names = scope.get_defined_names() # Instances have special rules, always return all the possible completions, # because class variables are always valid and the `self.` variables, too. - if (not position or isinstance(scope, (iterable.Array, er.Instance)) - or start_scope != scope - and isinstance(start_scope, (pr.Function, er.FunctionExecution))): + if not position or isinstance(scope, (iterable.Array, er.Instance, compiled.CompiledObject)) \ + or start_scope != scope \ + and isinstance(start_scope, (pr.Function, er.FunctionExecution)): return names names_new = [] for n in names: