From 2d48c7234084137ed516e512bb4cf96e935d0348 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Thu, 8 May 2014 13:22:41 +0200 Subject: [PATCH 1/2] introduce a NestedImportModule class --- jedi/evaluate/imports.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/jedi/evaluate/imports.py b/jedi/evaluate/imports.py index 7c10e5bc..b03591d8 100644 --- a/jedi/evaluate/imports.py +++ b/jedi/evaluate/imports.py @@ -190,7 +190,11 @@ class ImportWrapper(pr.Base): debug.warning('Module not found: %s', self.import_stmt) return [] - scopes = [scope] + if self._is_nested_import(): + scopes = [NestedImportModule(scope, self._get_nested_import(scope))] + else: + scopes = [scope] + scopes += remove_star_imports(self._evaluator, scope) # follow the rest of the import (not FS -> classes, functions) @@ -212,9 +216,6 @@ class ImportWrapper(pr.Base): scopes = list(chain.from_iterable( self._evaluator.follow_path(iter(rest), [s], s) for s in scopes)) - - if self._is_nested_import(): - scopes.append(self._get_nested_import(scope)) else: scopes = [ImportWrapper.GlobalNamespace] debug.dbg('after import: %s', scopes) @@ -222,6 +223,24 @@ class ImportWrapper(pr.Base): return scopes +class NestedImportModule(pr.Module): + def __init__(self, module, nested_import): + self._module = module + self._nested_import = nested_import + + def get_defined_names(self): + nested = self._nested_import.namespace + print(nested) + return self._module.get_defined_names() + [nested] + + def __getattr__(self, name): + return getattr(self._module, name) + + def __repr__(self): + return "<%s: %s>" % (self.__class__.__name__, + self._module) + + def get_importer(evaluator, import_path, module, level=0): """ Checks the evaluator caches first, which resembles the ``sys.modules`` From d0b2a2ce4f3ccd2b8699f9bb22d3674b439dc316 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Fri, 9 May 2014 11:52:10 +0200 Subject: [PATCH 2/2] fixed NestedImportModule --- jedi/evaluate/helpers.py | 8 ++++++-- jedi/evaluate/imports.py | 38 ++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/jedi/evaluate/helpers.py b/jedi/evaluate/helpers.py index 8930f763..a8e2d1f5 100644 --- a/jedi/evaluate/helpers.py +++ b/jedi/evaluate/helpers.py @@ -184,6 +184,10 @@ class FakeStatement(pr.Statement): class FakeName(pr.Name): - def __init__(self, name, parent=None): + def __init__(self, name_or_names, parent=None): p = 0, 0 - super(FakeName, self).__init__(FakeSubModule, [(name, p)], p, p, parent) + if isinstance(name_or_names, list): + names = [(n, p) for n in name_or_names] + else: + names = [(name_or_names, p)] + super(FakeName, self).__init__(FakeSubModule, names, p, p, parent) diff --git a/jedi/evaluate/imports.py b/jedi/evaluate/imports.py index b03591d8..43388e20 100644 --- a/jedi/evaluate/imports.py +++ b/jedi/evaluate/imports.py @@ -158,23 +158,6 @@ class ImportWrapper(pr.Base): and len(self.import_stmt.namespace.names) > 1 \ and not self.direct_resolve - def _get_nested_import(self, parent): - """ - See documentation of `self._is_nested_import`. - Generates an Import statement, that can be used to fake nested imports. - """ - i = self.import_stmt - # This is not an existing Import statement. Therefore, set position to - # 0 (0 is not a valid line number). - zero = (0, 0) - names = [(unicode(name_part), name_part.start_pos) - for name_part in i.namespace.names[1:]] - n = pr.Name(i._sub_module, names, zero, zero, self.import_stmt) - new = pr.Import(i._sub_module, zero, zero, n) - new.parent = parent - debug.dbg('Generated a nested import: %s', new) - return new - def _is_relative_import(self): return bool(self.import_stmt.relative_count) @@ -191,7 +174,7 @@ class ImportWrapper(pr.Base): return [] if self._is_nested_import(): - scopes = [NestedImportModule(scope, self._get_nested_import(scope))] + scopes = [NestedImportModule(scope, self.import_stmt)] else: scopes = [scope] @@ -228,9 +211,24 @@ class NestedImportModule(pr.Module): self._module = module self._nested_import = nested_import + def _get_nested_import_name(self): + """ + See documentation of `self._is_nested_import`. + Generates an Import statement, that can be used to fake nested imports. + """ + i = self._nested_import + # This is not an existing Import statement. Therefore, set position to + # 0 (0 is not a valid line number). + zero = (0, 0) + names = [unicode(name_part) for name_part in i.namespace.names[1:]] + name = helpers.FakeName(names, self._nested_import) + new = pr.Import(i._sub_module, zero, zero, name) + new.parent = self._module + debug.dbg('Generated a nested import: %s', new) + return helpers.FakeName(str(i.namespace.names[1]), new) + def get_defined_names(self): - nested = self._nested_import.namespace - print(nested) + nested = self._get_nested_import_name() return self._module.get_defined_names() + [nested] def __getattr__(self, name):