diff --git a/jedi/api/completion.py b/jedi/api/completion.py index 617fdc17..4ff935f7 100644 --- a/jedi/api/completion.py +++ b/jedi/api/completion.py @@ -151,19 +151,13 @@ class Completion: # Also true for defining names as a class or function. return list(self._get_class_context_completions(is_function=True)) elif "import_stmt" in symbol_names: - level = 0 - only_modules = True - level, names = self._parse_dotted_names(nodes) - if "import_from" in symbol_names: - if 'import' in nodes: - only_modules = False - else: - assert "import_name" in symbol_names + level, names = self._parse_dotted_names(nodes, "import_from" in symbol_names) + only_modules = not ("import_from" in symbol_names and 'import' in nodes) completion_names += self._get_importer_names( names, level, - only_modules + only_modules=only_modules, ) elif symbol_names[-1] in ('trailer', 'dotted_name') and nodes[-1] == '.': dot = self._module_node.get_leaf_for_position(self._position) @@ -211,7 +205,7 @@ class Completion: completion_names += filter.values() return completion_names - def _parse_dotted_names(self, nodes): + def _parse_dotted_names(self, nodes, is_import_from): level = 0 names = [] for node in nodes[1:]: @@ -222,7 +216,12 @@ class Completion: names += node.children[::2] elif node.type == 'name': names.append(node) + elif node == ',': + if not is_import_from: + names = [] else: + # Here if the keyword `import` comes along it stops checking + # for names. break return level, names diff --git a/test/test_evaluate/test_imports.py b/test/test_evaluate/test_imports.py index 32026a1e..a41d4f0d 100644 --- a/test/test_evaluate/test_imports.py +++ b/test/test_evaluate/test_imports.py @@ -197,7 +197,7 @@ def test_goto_following_on_imports(): assert (g[0].line, g[0].column) != (0, 0) -def test_after_from(): +def test_os_after_from(): def check(source, result, column=None): completions = Script(source, column=column).completions() assert [c.name for c in completions] == result @@ -211,6 +211,24 @@ def test_after_from(): check('from os \\\n', ['import']) +def test_os_issues(): + def import_names(*args, **kwargs): + return [d.name for d in jedi.Script(*args, **kwargs).completions()] + + # Github issue #759 + s = 'import os, s' + assert 'sys' in import_names(s) + assert 'path' not in import_names(s, column=len(s) - 1) + assert 'os' in import_names(s, column=len(s) - 3) + + # Some more checks + s = 'from os import path, e' + assert 'environ' in import_names(s) + assert 'json' not in import_names(s, column=len(s) - 1) + assert 'environ' in import_names(s, column=len(s) - 1) + assert 'path' in import_names(s, column=len(s) - 3) + + def test_path_issues(): """ See pull request #684 for details.