diff --git a/jedi/_compatibility.py b/jedi/_compatibility.py index 9a704304..454511dd 100644 --- a/jedi/_compatibility.py +++ b/jedi/_compatibility.py @@ -7,11 +7,52 @@ Most of the code here is necessary to support Python 2.5. Once this dependency will be dropped, we'll get rid of most code. """ import sys +import imp +import os +import io +try: + import importlib +except: + pass is_py3k = sys.hexversion >= 0x03000000 - +is_py33 = sys.hexversion >= 0x03030000 is_py25 = sys.hexversion < 0x02060000 +if is_py33: + def find_module(string, path=None): + importing = None + if path is not None: + importing = importlib.find_loader(string, path) + else: + importing = importlib.find_loader(string) + + returning = (None, None, None) + try: + filename = importing.get_filename(string) + if filename and os.path.exists(filename): + returning = (open(filename, 'U'), filename, False) + else: + returning = (None, filename, False) + except AttributeError: + if importing is None: + returning = (None, None, False) + else: + returning = (None, importing.load_module(string).__name__, False) + + return returning +else: + def find_module(string, path=None): + importing = None + if path is None: + importing = imp.find_module(string) + else: + importing = imp.find_module(string, path) + + returning = (importing[0], importing[1], importing[2][2] == imp.PKG_DIRECTORY) + + return returning + # next was defined in python 2.6, in python 3 obj.next won't be possible # anymore try: diff --git a/jedi/imports.py b/jedi/imports.py index 72a3d0f6..a006f3e7 100644 --- a/jedi/imports.py +++ b/jedi/imports.py @@ -21,6 +21,7 @@ import imp import sys import itertools +from jedi._compatibility import find_module from jedi import modules from jedi import debug from jedi import parsing_representation as pr @@ -238,20 +239,22 @@ class ImportPath(pr.Base): global imports_processed imports_processed += 1 + importing = None if path is not None: - return imp.find_module(string, [path]) + importing = find_module(string, [path]) else: debug.dbg('search_module', string, self.file_path) # Override the sys.path. It works only good that way. # Injecting the path directly into `find_module` did not work. sys.path, temp = sys_path_mod, sys.path try: - i = imp.find_module(string) + importing = find_module(string) except ImportError: sys.path = temp raise sys.path = temp - return i + + return importing if self.file_path: sys_path_mod = list(self.sys_path_with_modifications()) @@ -259,6 +262,9 @@ class ImportPath(pr.Base): else: sys_path_mod = list(modules.get_sys_path()) + def module_not_found(): + raise ModuleNotFound('The module you searched has not been found') + current_namespace = (None, None, None) # now execute those paths rest = [] @@ -277,12 +283,14 @@ class ImportPath(pr.Base): if current_namespace[1]: rest = self.import_path[i:] else: - raise ModuleNotFound( - 'The module you searched has not been found') + module_not_found() + + if current_namespace == (None, None, False): + module_not_found() sys_path_mod.pop(0) # TODO why is this here? path = current_namespace[1] - is_package_directory = current_namespace[2][2] == imp.PKG_DIRECTORY + is_package_directory = current_namespace[2] f = None if is_package_directory or current_namespace[0]: