From 48d2e99e551e1c10ed54ddc069439ce41b8071d0 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Thu, 11 Dec 2014 01:49:59 +0100 Subject: [PATCH] os.path handling. --- jedi/api/__init__.py | 4 ++-- jedi/api/helpers.py | 2 +- jedi/evaluate/imports.py | 37 ++++++++++++++++++++----------------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index e37dde1a..b653be35 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -136,7 +136,7 @@ class Script(object): names, level, only_modules = helpers.check_error_statements(module, self._pos) completions = [] #print(importer.completion_names(self._evaluator, True)) - if names: + if names is not None: imp_names = [n for n in names if n.end_pos < self._pos] i = imports.get_importer(self._evaluator, imp_names, module, level) c_names = i.completion_names(self._evaluator, only_modules) @@ -155,7 +155,7 @@ class Script(object): imp = imports.ImportWrapper(self._evaluator, name) completions += [(n, module) for n in imp.completion_names()] - if not names and not isinstance(user_stmt, pr.Import): + if names is None and not isinstance(user_stmt, pr.Import): if not path and not dot: # add keywords completions += ((k, b) for k in keywords.keyword_names(all=True)) diff --git a/jedi/api/helpers.py b/jedi/api/helpers.py index 5b292c4c..04ea09e5 100644 --- a/jedi/api/helpers.py +++ b/jedi/api/helpers.py @@ -39,7 +39,7 @@ def check_error_statements(module, pos): if error_statement.first_type in ('import_from', 'import_name') \ and error_statement.first_pos < pos <= error_statement.next_start_pos: return importer_from_error_statement(error_statement, pos) - return [], 0, False + return None, 0, False def importer_from_error_statement(error_statement, pos): diff --git a/jedi/evaluate/imports.py b/jedi/evaluate/imports.py index fe482fb9..bc45b3c9 100644 --- a/jedi/evaluate/imports.py +++ b/jedi/evaluate/imports.py @@ -94,20 +94,7 @@ class ImportWrapper(pr.Base): scopes = [s.name for s in scopes] # follow the rest of the import (not FS -> classes, functions) - if len(rest) > 1 or rest and self.is_like_search: - if ('os', 'path') == importer.str_import_path[:2] \ - and self._import.level == 0: - # This is a huge exception, we follow a nested import - # ``os.path``, because it's a very important one in Python - # that is being achieved by messing with ``sys.modules`` in - # ``os``. - for r in rest: - scopes = list(chain.from_iterable( - self._evaluator.find_types(s, r) - for s in scopes)) - else: - scopes = [] - elif rest: + if rest: if is_goto: scopes = list(chain.from_iterable( self._evaluator.find_types(s, rest[0], is_goto=True) @@ -471,7 +458,23 @@ class _Importer(object): except ModuleNotFound: self.import_path = ('flaskext',) + orig_path[2:] return self._real_follow_file_system() - return self._real_follow_file_system() + + obj, rest = self._real_follow_file_system() + + # os.path handling + if len(self.str_import_path) < 4 \ + and ('os', 'path') == self.str_import_path[:2] and self.level == 0: + # This is a huge exception, we follow a nested import + # ``os.path``, because it's a very important one in Python + # that is being achieved by messing with ``sys.modules`` in + # ``os``. + scopes = [obj] + for r in rest: + scopes = list(chain.from_iterable( + self._evaluator.find_types(s, r) + for s in scopes)) + return scopes[0], [] + return obj, rest def _real_follow_file_system(self): if self.file_path: @@ -642,7 +645,7 @@ class _Importer(object): if os.path.isdir(flaskext): names += self._get_module_names([flaskext]) - from jedi.evaluate import finder, representation as er + from jedi.evaluate import finder for scope in self.follow(evaluator): # namespace packages if isinstance(scope, pr.Module) and scope.path.endswith('__init__.py'): @@ -650,7 +653,7 @@ class _Importer(object): paths = self.namespace_packages(pkg_path, self.import_path) names += self._get_module_names([pkg_path] + paths) - if only_modules or not isinstance(scope, er.ModuleWrapper): + if only_modules: # In the case of an import like `from x.` we don't need to # add all the variables. if ('os',) == self.str_import_path and not self.level: