From ba0e61d99f50880dea098f11ec534ab76458f8b1 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Wed, 19 Nov 2014 18:09:49 +0100 Subject: [PATCH] Star imports are now part of the ModuleWrapper. --- jedi/evaluate/finder.py | 2 ++ jedi/evaluate/imports.py | 7 ++++--- jedi/evaluate/representation.py | 12 ++++++++++++ jedi/parser/representation.py | 22 ++++++++++++++++++++-- 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index 0677a7b2..cfd4b11e 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -569,9 +569,11 @@ def get_names_of_scope(evaluator, scope, position=None, star_search=True, includ # Add star imports. if star_search: + """ for s in imports.remove_star_imports(evaluator, non_flow.get_parent_until()): for g in get_names_of_scope(evaluator, s, star_search=False): yield g + """ # Add builtins to the global scope. if include_builtin: diff --git a/jedi/evaluate/imports.py b/jedi/evaluate/imports.py index 28fbff59..54fa02a7 100644 --- a/jedi/evaluate/imports.py +++ b/jedi/evaluate/imports.py @@ -77,9 +77,9 @@ class ImportWrapper(pr.Base): else: scopes = [module] - star_imports = remove_star_imports(self._evaluator, module) - if star_imports: - scopes = [StarImportModule(scopes[0], star_imports)] + #star_imports = remove_star_imports(self._evaluator, module) + #if star_imports: + # scopes = [StarImportModule(scopes[0], star_imports)] # goto only accepts `Name` if is_goto and not rest: @@ -616,6 +616,7 @@ def remove_star_imports(evaluator, scope, ignored_modules=()): and follow these modules. """ + raise NotImplementedError if isinstance(scope, StarImportModule): return scope.star_import_modules modules = follow_imports(evaluator, (i for i in scope.get_imports() if i.star)) diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index b5e7bcc0..ae8f7008 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -48,6 +48,7 @@ from jedi.evaluate import docstrings from jedi.evaluate import helpers from jedi.evaluate import param from jedi.evaluate import flow_analysis +from jedi.evaluate import imports def wrap(evaluator, element): @@ -714,11 +715,22 @@ class ModuleWrapper(use_metaclass(CachedMetaClass, pr.Module, Wrapper)): def scope_names_generator(self, position=None): yield self, pr.filter_after_position(self._module.get_defined_names(), position) yield self, self._module_attributes() + for star_module in self.star_imports(): + yield self, star_module.get_defined_names() yield self, self.base.global_names sub_modules = self._sub_modules() if sub_modules: yield self, self._sub_modules() + @underscore_memoization + def star_imports(self): + modules = [] + for i in self.base.imports: + if i.is_star_import(): + name = i.star_import_name() + modules += imports.ImportWrapper(self._evaluator, name).follow() + return modules + @memoize_default() def _module_attributes(self): def parent_callback(): diff --git a/jedi/parser/representation.py b/jedi/parser/representation.py index 95a5072f..0b4d9b64 100644 --- a/jedi/parser/representation.py +++ b/jedi/parser/representation.py @@ -483,11 +483,10 @@ class Scope(Simple, DocstringMixin): :param start_pos: The position (line and column) of the scope. :type start_pos: tuple(int, int) """ - __slots__ = ('imports', '_doc_token', 'asserts', 'names_dict') + __slots__ = ('_doc_token', 'asserts', 'names_dict') def __init__(self, children): super(Scope, self).__init__(children) - self.imports = [] self._doc_token = None self.asserts = [] @@ -505,6 +504,10 @@ class Scope(Simple, DocstringMixin): def flows(self): return self._search_in_scope(Flow) + @property + def imports(self): + return self._search_in_scope(Import) + def _search_in_scope(self, typ): def scan(children): elements = [] @@ -529,6 +532,8 @@ class Scope(Simple, DocstringMixin): def get_imports(self): """ Gets also the imports within flow statements """ + raise NotImplementedError + return [] i = [] + self.imports for s in self.statements: if isinstance(s, Scope): @@ -700,6 +705,10 @@ class SubModule(Scope, Module): is a ``__future__`` import. """ for imp in self.imports: + + + # TODO implement! + continue if not imp.from_names or not imp.namespace_names: continue @@ -1141,6 +1150,12 @@ class ImportFrom(Import): else: yield as_name.children[::2] # yields x, y -> ``x as y`` + def star_import_name(self): + """ + The last name defined in a star import. + """ + return self._paths()[-1][-1] + def _paths(self): for n in self.children[1:]: if n not in ('.', '...'): @@ -1151,6 +1166,9 @@ class ImportFrom(Import): dotted = [] else: # from x import dotted = [n] + + if self.children[-1] == '*': + return [dotted] return [dotted + [name] for name, alias in self._as_name_tuples()]