forked from VimPlug/jedi
Some import fixes.
This commit is contained in:
@@ -18,7 +18,6 @@ import sys
|
|||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
from jedi._compatibility import find_module, unicode
|
from jedi._compatibility import find_module, unicode
|
||||||
from jedi import common
|
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi.parser import fast
|
from jedi.parser import fast
|
||||||
from jedi.parser import tree
|
from jedi.parser import tree
|
||||||
@@ -26,7 +25,7 @@ from jedi.parser.utils import save_parser, load_parser, parser_cache
|
|||||||
from jedi.evaluate import sys_path
|
from jedi.evaluate import sys_path
|
||||||
from jedi.evaluate import helpers
|
from jedi.evaluate import helpers
|
||||||
from jedi import settings
|
from jedi import settings
|
||||||
from jedi.common import source_to_unicode
|
from jedi.common import source_to_unicode, unite
|
||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
from jedi.evaluate import analysis
|
from jedi.evaluate import analysis
|
||||||
|
|
||||||
@@ -62,16 +61,15 @@ class ImportWrapper(object):
|
|||||||
self._context = context
|
self._context = context
|
||||||
self._name = name
|
self._name = name
|
||||||
|
|
||||||
self._import = name.get_parent_until(tree.Import)
|
|
||||||
self.import_path = self._import.path_for_name(name)
|
|
||||||
|
|
||||||
# TODO move this whole thing to a function
|
# TODO move this whole thing to a function
|
||||||
def follow(self, is_goto=False):
|
def follow(self, is_goto=False):
|
||||||
module = self._import.get_parent_until()
|
module_context = self._context.get_root_context()
|
||||||
import_path = self._import.path_for_name(self._name)
|
import_node = self._name.get_parent_until(tree.Import)
|
||||||
|
import_path = import_node.path_for_name(self._name)
|
||||||
from_import_name = None
|
from_import_name = None
|
||||||
|
evaluator = self._context.evaluator
|
||||||
try:
|
try:
|
||||||
from_names = self._import.get_from_names()
|
from_names = import_node.get_from_names()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Is an import_name
|
# Is an import_name
|
||||||
pass
|
pass
|
||||||
@@ -82,24 +80,26 @@ class ImportWrapper(object):
|
|||||||
from_import_name = import_path[-1]
|
from_import_name = import_path[-1]
|
||||||
import_path = from_names
|
import_path = from_names
|
||||||
|
|
||||||
importer = Importer(self._context.evaluator, tuple(import_path),
|
importer = Importer(evaluator, tuple(import_path),
|
||||||
module, self._import.level)
|
module_context, import_node.level)
|
||||||
|
|
||||||
|
# TODO This is terrible, why different Importer instances?
|
||||||
types = importer.follow()
|
types = importer.follow()
|
||||||
|
|
||||||
#if self._import.is_nested() and not self.nested_resolve:
|
#if import_node.is_nested() and not self.nested_resolve:
|
||||||
# scopes = [NestedImportModule(module, self._import)]
|
# scopes = [NestedImportModule(module, import_node)]
|
||||||
|
|
||||||
if from_import_name is not None:
|
if from_import_name is not None:
|
||||||
types = set(chain.from_iterable(
|
types = unite(
|
||||||
self.evaluator.find_types(t, unicode(from_import_name),
|
evaluator.find_types(t, unicode(from_import_name),
|
||||||
is_goto=is_goto)
|
is_goto=is_goto)
|
||||||
for t in types))
|
for t in types
|
||||||
|
)
|
||||||
|
|
||||||
if not types:
|
if not types:
|
||||||
path = import_path + [from_import_name]
|
path = import_path + [from_import_name]
|
||||||
importer = Importer(self.evaluator, tuple(path),
|
importer = Importer(evaluator, tuple(path),
|
||||||
module, self._import.level)
|
module_context, import_node.level)
|
||||||
types = importer.follow()
|
types = importer.follow()
|
||||||
# goto only accepts `Name`
|
# goto only accepts `Name`
|
||||||
if is_goto:
|
if is_goto:
|
||||||
@@ -164,7 +164,7 @@ def get_init_path(directory_path):
|
|||||||
|
|
||||||
|
|
||||||
class Importer(object):
|
class Importer(object):
|
||||||
def __init__(self, evaluator, import_path, module, level=0):
|
def __init__(self, evaluator, import_path, module_context, level=0):
|
||||||
"""
|
"""
|
||||||
An implementation similar to ``__import__``. Use `follow`
|
An implementation similar to ``__import__``. Use `follow`
|
||||||
to actually follow the imports.
|
to actually follow the imports.
|
||||||
@@ -180,19 +180,19 @@ class Importer(object):
|
|||||||
debug.speed('import %s' % (import_path,))
|
debug.speed('import %s' % (import_path,))
|
||||||
self._evaluator = evaluator
|
self._evaluator = evaluator
|
||||||
self.level = level
|
self.level = level
|
||||||
self.module = module
|
self.module_context = module_context
|
||||||
try:
|
try:
|
||||||
self.file_path = module.py__file__()
|
self.file_path = module_context.py__file__()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Can be None for certain compiled modules like 'builtins'.
|
# Can be None for certain compiled modules like 'builtins'.
|
||||||
self.file_path = None
|
self.file_path = None
|
||||||
|
|
||||||
if level:
|
if level:
|
||||||
base = module.py__package__().split('.')
|
base = module_context.py__package__().split('.')
|
||||||
if base == ['']:
|
if base == ['']:
|
||||||
base = []
|
base = []
|
||||||
if level > len(base):
|
if level > len(base):
|
||||||
path = module.py__file__()
|
path = module_context.py__file__()
|
||||||
if path is not None:
|
if path is not None:
|
||||||
import_path = list(import_path)
|
import_path = list(import_path)
|
||||||
for i in range(level):
|
for i in range(level):
|
||||||
@@ -220,7 +220,10 @@ class Importer(object):
|
|||||||
|
|
||||||
def sys_path_with_modifications(self):
|
def sys_path_with_modifications(self):
|
||||||
in_path = []
|
in_path = []
|
||||||
sys_path_mod = list(sys_path.sys_path_with_modifications(self._evaluator, self.module))
|
sys_path_mod = list(sys_path.sys_path_with_modifications(
|
||||||
|
self._evaluator,
|
||||||
|
self.module_context
|
||||||
|
))
|
||||||
if self.file_path is not None:
|
if self.file_path is not None:
|
||||||
# If you edit e.g. gunicorn, there will be imports like this:
|
# If you edit e.g. gunicorn, there will be imports like this:
|
||||||
# `from gunicorn import something`. But gunicorn is not in the
|
# `from gunicorn import something`. But gunicorn is not in the
|
||||||
@@ -285,12 +288,13 @@ class Importer(object):
|
|||||||
return self._evaluator.find_types(parent_module, 'path')
|
return self._evaluator.find_types(parent_module, 'path')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
paths = parent_module.py__path__()
|
method = parent_module.py__path__
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# The module is not a package.
|
# The module is not a package.
|
||||||
_add_error(self._evaluator, import_path[-1])
|
_add_error(self._evaluator, import_path[-1])
|
||||||
return set()
|
return set()
|
||||||
else:
|
else:
|
||||||
|
paths = method()
|
||||||
debug.dbg('search_module %s in paths %s', module_name, paths)
|
debug.dbg('search_module %s in paths %s', module_name, paths)
|
||||||
for path in paths:
|
for path in paths:
|
||||||
# At the moment we are only using one path. So this is
|
# At the moment we are only using one path. So this is
|
||||||
@@ -349,7 +353,7 @@ class Importer(object):
|
|||||||
def _generate_name(self, name):
|
def _generate_name(self, name):
|
||||||
# Create a pseudo import to be able to follow them.
|
# Create a pseudo import to be able to follow them.
|
||||||
name = helpers.FakeName(name)
|
name = helpers.FakeName(name)
|
||||||
imp = helpers.FakeImport(name, parent=self.module)
|
imp = helpers.FakeImport(name, parent=self.module_context)
|
||||||
name.parent = imp
|
name.parent = imp
|
||||||
return name
|
return name
|
||||||
|
|
||||||
@@ -443,7 +447,7 @@ def _load_module(evaluator, path=None, source=None, sys_path=None, parent_module
|
|||||||
else:
|
else:
|
||||||
return compiled.load_module(evaluator, path)
|
return compiled.load_module(evaluator, path)
|
||||||
p = path
|
p = path
|
||||||
p = fast.FastParser(evaluator.grammar, common.source_to_unicode(source), p)
|
p = fast.FastParser(evaluator.grammar, source_to_unicode(source), p)
|
||||||
save_parser(path, p)
|
save_parser(path, p)
|
||||||
return p.module
|
return p.module
|
||||||
|
|
||||||
|
|||||||
@@ -776,7 +776,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)
|
|||||||
origin_scope=origin_scope
|
origin_scope=origin_scope
|
||||||
)
|
)
|
||||||
yield GlobalNameFilter(self, self.module_node)
|
yield GlobalNameFilter(self, self.module_node)
|
||||||
yield DictFilter(self._sub_modules_dict())
|
#yield DictFilter(self._sub_modules_dict())
|
||||||
yield DictFilter(self._module_attributes_dict())
|
yield DictFilter(self._module_attributes_dict())
|
||||||
# TODO
|
# TODO
|
||||||
'''
|
'''
|
||||||
@@ -853,10 +853,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)
|
|||||||
return self.py__name__()
|
return self.py__name__()
|
||||||
|
|
||||||
def _py__path__(self):
|
def _py__path__(self):
|
||||||
if self._parent_module is None:
|
search_path = self.evaluator.sys_path
|
||||||
search_path = self.evaluator.sys_path
|
|
||||||
else:
|
|
||||||
search_path = self._parent_module.py__path__()
|
|
||||||
init_path = self.py__file__()
|
init_path = self.py__file__()
|
||||||
if os.path.basename(init_path) == '__init__.py':
|
if os.path.basename(init_path) == '__init__.py':
|
||||||
with open(init_path, 'rb') as f:
|
with open(init_path, 'rb') as f:
|
||||||
|
|||||||
Reference in New Issue
Block a user