diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 246af06f..4ab5e7b0 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -131,30 +131,33 @@ class Script(object): :rtype: list of :class:`classes.Completion` """ def get_completions(user_stmt, bs): - if user_stmt is None: - module = self._parser.module() - importer, only_modules = helpers.check_error_statements( - self._evaluator, module, self._pos - ) - #print(importer.completion_names(self._evaluator, True)) - if importer is not None: - names = importer.completion_names(self._evaluator, only_modules) - return [(name, module) for name in names] - elif isinstance(user_stmt, pr.Import): + module = self._parser.module() + importer, only_modules = helpers.check_error_statements( + self._evaluator, module, self._pos + ) + completions = [] + #print(importer.completion_names(self._evaluator, True)) + if importer is not None: + names = importer.completion_names(self._evaluator, only_modules) + completions = [(name, module) for name in names] + if isinstance(user_stmt, pr.Import): # TODO this paragraph is necessary, but not sure it works. context = self._user_context.get_context() next(context) # skip the path - if next(context) == 'from': + if False and next(context) == 'from': # completion is just "import" if before stands from .. - return ((k, bs) for k in keywords.keyword_names('import')) + completions += ((k, bs) for k in keywords.keyword_names('import')) module = self._parser.module() name = user_stmt.name_for_position(self._pos) imp = imports.ImportWrapper(self._evaluator, name) - return [(n, module) for n in imp.get_defined_names()] + completions += [(n, module) for n in imp.completions()] + if importer or isinstance(user_stmt, pr.Import): + return completions return self._simple_complete(path, dot, like) + debug.speed('completions start') path = self._user_context.get_path_until_cursor() # dots following an int are not the start of a completion but a float diff --git a/jedi/evaluate/imports.py b/jedi/evaluate/imports.py index 02680d59..96645f0c 100644 --- a/jedi/evaluate/imports.py +++ b/jedi/evaluate/imports.py @@ -47,13 +47,17 @@ class ImportWrapper(pr.Base): self.import_path = self._import.path_for_name(name) self.is_like_search = False # TODO REMOVE - def get_defined_names(self): + def completions(self): # The import path needs to be reduced by one, because we're completing. import_path = self.import_path[:-1] module = self._import.get_parent_until() importer = get_importer(self._evaluator, tuple(import_path), module, self._import.level) - only_modules = isinstance(self._import, pr.ImportName) + if isinstance(self._import, pr.ImportFrom): + c = self._import.children + only_modules = c[c.index('import')].start_pos >= self._name.start_pos + else: + only_modules = True return importer.completion_names(self._evaluator, only_modules) @memoize_default() diff --git a/test/completion/on_import.py b/test/completion/on_import.py index 557bfaaa..76b45fb9 100644 --- a/test/completion/on_import.py +++ b/test/completion/on_import.py @@ -25,6 +25,8 @@ import classes #? ['timedelta'] from datetime import timedel +#? 21 [] +from datetime.timedel import timedel # should not be possible, because names can only be looked up 1 level deep. #? [] @@ -59,7 +61,9 @@ import datetime. #? [] import datetime.date -#? 18 ['import'] +#? 17 ['import'] +from import_tree import pkg +#? 18 ['import', 'pkg'] from import_tree. import pkg #? 17 ['mod1', 'mod2', 'random', 'pkg', 'rename1', 'rename2', 'recurse_class1', 'recurse_class2'] from import_tree. import pkg