1
0
forked from VimPlug/jedi

Move the import logic to the subprocess

This commit is contained in:
Dave Halter
2017-12-23 17:59:56 +01:00
parent 473be114f3
commit 87666d72a1
3 changed files with 55 additions and 51 deletions

View File

@@ -35,7 +35,7 @@ class DummyFile(object):
del self.loader del self.loader
def find_module_py34(string, path=None, fullname=None): def find_module_py34(string, path=None, full_name=None):
implicit_namespace_pkg = False implicit_namespace_pkg = False
spec = None spec = None
loader = None loader = None
@@ -47,8 +47,8 @@ def find_module_py34(string, path=None, fullname=None):
# We try to disambiguate implicit namespace pkgs with non implicit namespace pkgs # We try to disambiguate implicit namespace pkgs with non implicit namespace pkgs
if implicit_namespace_pkg: if implicit_namespace_pkg:
fullname = string if not path else fullname full_name = string if not path else full_name
implicit_ns_info = ImplicitNSInfo(fullname, spec.submodule_search_locations._path) implicit_ns_info = ImplicitNSInfo(full_name, spec.submodule_search_locations._path)
return None, implicit_ns_info, False return None, implicit_ns_info, False
# we have found the tail end of the dotted path # we have found the tail end of the dotted path
@@ -56,7 +56,8 @@ def find_module_py34(string, path=None, fullname=None):
loader = spec.loader loader = spec.loader
return find_module_py33(string, path, loader) return find_module_py33(string, path, loader)
def find_module_py33(string, path=None, loader=None, fullname=None):
def find_module_py33(string, path=None, loader=None, full_name=None):
loader = loader or importlib.machinery.PathFinder.find_module(string, path) loader = loader or importlib.machinery.PathFinder.find_module(string, path)
if loader is None and path is None: # Fallback to find builtins if loader is None and path is None: # Fallback to find builtins
@@ -109,7 +110,7 @@ def find_module_py33(string, path=None, loader=None, fullname=None):
return module_file, module_path, is_package return module_file, module_path, is_package
def find_module_pre_py33(string, path=None, fullname=None): def find_module_pre_py33(string, path=None, full_name=None):
try: try:
module_file, module_path, description = imp.find_module(string, path) module_file, module_path, description = imp.find_module(string, path)
module_type = description[2] module_type = description[2]

View File

@@ -1,5 +1,8 @@
import sys import sys
import os
import imp
from jedi.evaluate.compiled import access from jedi.evaluate.compiled import access
from jedi._compatibility import find_module
def get_sys_path(): def get_sys_path():
@@ -23,3 +26,41 @@ def get_special_object(evaluator, identifier):
def create_simple_object(evaluator, obj): def create_simple_object(evaluator, obj):
return access.create_access_path(evaluator, obj) return access.create_access_path(evaluator, obj)
def get_module_info(evaluator, sys_path=None, full_name=None, **kwargs):
if sys_path is not None:
sys.path, temp = sys_path, sys.path
try:
module_file, module_path, is_pkg = find_module(full_name=full_name, **kwargs)
except ImportError:
return None, None, None
finally:
if sys_path is not None:
sys.path = temp
code = None
if is_pkg:
# In this case, we don't have a file yet. Search for the
# __init__ file.
if module_path.endswith(('.zip', '.egg')):
code = module_file.loader.get_source(full_name)
else:
module_path = _get_init_path(module_path)
elif module_file:
code = module_file.read()
module_file.close()
return code, module_path, is_pkg
def _get_init_path(directory_path):
"""
The __init__ file can be searched in a directory. If found return it, else
None.
"""
for suffix, _, _ in imp.get_suffixes():
path = os.path.join(directory_path, '__init__' + suffix)
if os.path.exists(path):
return path
return None

View File

@@ -11,7 +11,6 @@ correct implementation is delegated to _compatibility.
This module also supports import autocompletion, which means to complete This module also supports import autocompletion, which means to complete
statements like ``from datetim`` (curser at the end would return ``datetime``). statements like ``from datetim`` (curser at the end would return ``datetime``).
""" """
import imp
import os import os
import pkgutil import pkgutil
import sys import sys
@@ -21,7 +20,7 @@ from parso.tree import search_ancestor
from parso.cache import parser_cache from parso.cache import parser_cache
from parso import python_bytes_to_unicode from parso import python_bytes_to_unicode
from jedi._compatibility import find_module, unicode, ImplicitNSInfo from jedi._compatibility import unicode, ImplicitNSInfo
from jedi import debug from jedi import debug
from jedi import settings from jedi import settings
from jedi.evaluate import sys_path from jedi.evaluate import sys_path
@@ -139,18 +138,6 @@ def _add_error(context, name, message=None):
debug.warning('ImportError without origin: ' + message) debug.warning('ImportError without origin: ' + message)
def get_init_path(directory_path):
"""
The __init__ file can be searched in a directory. If found return it, else
None.
"""
for suffix, _, _ in imp.get_suffixes():
path = os.path.join(directory_path, '__init__' + suffix)
if os.path.exists(path):
return path
return None
class ImportName(AbstractNameDefinition): class ImportName(AbstractNameDefinition):
start_pos = (1, 0) start_pos = (1, 0)
_level = 0 _level = 0
@@ -308,31 +295,6 @@ class Importer(object):
except KeyError: except KeyError:
pass pass
def _find_module(sys_path=None, **kwargs):
if sys_path is not None:
sys.path, temp = sys_path, sys.path
try:
module_file, module_path, is_pkg = find_module(**kwargs)
except ImportError:
return None, None, None
finally:
if sys_path is not None:
sys.path = temp
code = None
if is_pkg:
# In this case, we don't have a file yet. Search for the
# __init__ file.
if module_path.endswith(('.zip', '.egg')):
code = module_file.loader.get_source(module_name)
else:
module_path = get_init_path(module_path)
elif module_file:
code = module_file.read()
module_file.close()
return code, module_path, is_pkg
if len(import_path) > 1: if len(import_path) > 1:
# This is a recursive way of importing that works great with # This is a recursive way of importing that works great with
# the module cache. # the module cache.
@@ -365,10 +327,10 @@ class Importer(object):
# not important to be correct. # not important to be correct.
if not isinstance(path, list): if not isinstance(path, list):
path = [path] path = [path]
code, module_path, is_pkg = _find_module( code, module_path, is_pkg = self._evaluator.compiled_subprocess.get_module_info(
string=import_parts[-1], string=import_parts[-1],
path=path, path=path,
fullname=module_name full_name=module_name
) )
if module_path is not None: if module_path is not None:
break break
@@ -380,9 +342,9 @@ class Importer(object):
debug.dbg('search_module %s in %s', import_parts[-1], self.file_path) debug.dbg('search_module %s in %s', import_parts[-1], self.file_path)
# Override the sys.path. It works only good that way. # Override the sys.path. It works only good that way.
# Injecting the path directly into `find_module` did not work. # Injecting the path directly into `find_module` did not work.
code, module_path, is_pkg = _find_module( code, module_path, is_pkg = self._evaluator.compiled_subprocess.get_module_info(
string=import_parts[-1], string=import_parts[-1],
fullname=module_name, full_name=module_name,
sys_path=sys_path, sys_path=sys_path,
) )
if module_path is None: if module_path is None: