diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 2210e185..34276ca6 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -226,9 +226,12 @@ class Script(object): def _simple_complete(self, path, dot, like): if not path and not dot: + scope = self._parser.user_scope() + if not scope.is_scope(): # Might be a flow (if/while/etc). + scope = scope.get_parent_scope() names_dicts = global_names_dict_generator( self._evaluator, - er.wrap(self._evaluator, self._parser.user_scope()), + er.wrap(self._evaluator, scope), self._pos ) completions = [] diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index 3f12e725..e43020e0 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -36,7 +36,7 @@ def filter_definition_names(names, origin, position=None): # Just calculate the scope from the first stmt = names[0].get_definition() scope = stmt.get_parent_scope() - if isinstance(stmt, (pr.CompFor, pr.Lambda, pr.GlobalStmt)): + if isinstance(stmt, (pr.CompFor, pr.Lambda)): return names if not (isinstance(scope, er.FunctionExecution) @@ -377,7 +377,13 @@ def _name_to_types(evaluator, name, scope): elif isinstance(typ, pr.Import): types += imports.ImportWrapper(evaluator, name).follow() elif isinstance(typ, pr.GlobalStmt): - types += evaluator.find_types(typ.get_parent_scope(), str(name)) + # TODO theoretically we shouldn't be using search_global here, it + # doesn't make sense, because it's a local search (for that name)! + # However, globals are not that important and resolving them doesn't + # guarantee correctness in any way, because we don't check for when + # something is executed. + types += evaluator.find_types(typ.get_parent_scope(), str(name), + search_global=True) elif isinstance(typ, pr.TryStmt): # TODO an exception can also be a tuple. Check for those. # TODO check for types that are not classes and add it to diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 7480ee73..fe6c08fb 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -824,6 +824,16 @@ class FunctionExecution(Executed): return "<%s of %s>" % (type(self).__name__, self.base) +class GlobalName(helpers.FakeName): + def __init__(self, name): + """ + We need to mark global names somehow. Otherwise they are just normal + names that are not definitions. + """ + super(GlobalName, self).__init__(name.value, name.parent, + name.start_pos, is_definition=True) + + class ModuleWrapper(use_metaclass(CachedMetaClass, pr.Module, Wrapper)): def __init__(self, evaluator, module): self._evaluator = evaluator @@ -847,7 +857,7 @@ class ModuleWrapper(use_metaclass(CachedMetaClass, pr.Module, Wrapper)): for star_module in self.star_imports(): yield star_module.names_dict - yield dict((str(n), [n]) for n in self.base.global_names) + yield dict((str(n), [GlobalName(n)]) for n in self.base.global_names) yield self._sub_modules_dict() @cache_star_import diff --git a/jedi/parser/__init__.py b/jedi/parser/__init__.py index 6c8e7e6b..f361d4a8 100644 --- a/jedi/parser/__init__.py +++ b/jedi/parser/__init__.py @@ -147,7 +147,7 @@ class Parser(object): # We need to check raw_node always, because the same node can be # returned by convert multiple times. if symbol == 'global_stmt': - self.global_names += new_node.get_defined_names() + self.global_names += new_node.get_global_names() elif isinstance(new_node, pt.Lambda): new_node.names_dict = self.scope_names_stack.pop() elif isinstance(new_node, (pt.ClassOrFunc, pt.Module)) \ diff --git a/jedi/parser/tree.py b/jedi/parser/tree.py index 8c3e5e22..4b925925 100644 --- a/jedi/parser/tree.py +++ b/jedi/parser/tree.py @@ -1128,6 +1128,9 @@ class GlobalStmt(KeywordStatement): __slots__ = () def get_defined_names(self): + return [] + + def get_global_names(self): return self.children[1::2]