From 806a43d0854e35d542e67b18060511216450ed0b Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Sat, 12 Nov 2016 03:01:07 +0100 Subject: [PATCH] Implement submodule name completion. --- jedi/evaluate/helpers.py | 28 ---------------------------- jedi/evaluate/representation.py | 23 ++++++++++++++++------- 2 files changed, 16 insertions(+), 35 deletions(-) diff --git a/jedi/evaluate/helpers.py b/jedi/evaluate/helpers.py index 01e708b6..2d0f01ec 100644 --- a/jedi/evaluate/helpers.py +++ b/jedi/evaluate/helpers.py @@ -139,34 +139,6 @@ def get_module_names(module, all_scopes): return chain.from_iterable(dct.values()) -class FakeImport(tree.ImportName): - def __init__(self, name, parent, level=0): - super(FakeImport, self).__init__([]) - self.parent = parent - self._level = level - self.name = name - - def get_defined_names(self): - return [self.name] - - def aliases(self): - return {} - - @property - def level(self): - return self._level - - @property - def start_pos(self): - return 0, 0 - - def paths(self): - return [[self.name]] - - def is_definition(self): - return True - - class FakeName(tree.Name): def __init__(self, name_str, parent=None, start_pos=(0, 0), is_definition=None): """ diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 0c33c689..acf623e6 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -56,7 +56,7 @@ from jedi.evaluate import param from jedi.evaluate import flow_analysis from jedi.evaluate import imports from jedi.evaluate.filters import ParserTreeFilter, FunctionExecutionFilter, \ - GlobalNameFilter, DictFilter, ContextName + GlobalNameFilter, DictFilter, ContextName, AbstractNameDefinition from jedi.evaluate.dynamic import search_params from jedi.evaluate import context @@ -748,6 +748,19 @@ class GlobalName(helpers.FakeName): super(GlobalName, self).__init__(name.value, name.parent, name.start_pos, is_definition=True) +class SubModuleName(AbstractNameDefinition): + def __init__(self, parent_module, string_name): + self.parent_context = parent_module + self.string_name = string_name + + def infer(self): + return imports.Importer( + self.parent_context.evaluator, + [self.string_name], + self.parent_context, + level=1 + ).follow() + class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)): parent_context = None @@ -776,7 +789,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper) origin_scope=origin_scope ) yield GlobalNameFilter(self, self.module_node) - #yield DictFilter(self._sub_modules_dict()) + yield DictFilter(self._sub_modules_dict()) yield DictFilter(self._module_attributes_dict()) # TODO ''' @@ -903,12 +916,8 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper) if path is not None and path.endswith(os.path.sep + '__init__.py'): mods = pkgutil.iter_modules([os.path.dirname(path)]) for module_loader, name, is_pkg in mods: - raise NotImplementedError - fake_n = helpers.FakeName(name) # It's obviously a relative import to the current module. - imp = helpers.FakeImport(fake_n, self, level=1) - fake_n.parent = imp - names[name] = fake_n + names[name] = SubModuleName(self, name) # TODO add something like this in the future, its cleaner than the # import hacks.