1
0
forked from VimPlug/jedi

generalize import optimizations and make them behave more like sys.modules

This commit is contained in:
Dave Halter
2014-04-10 15:21:23 +02:00
parent 4bc89d638c
commit 840a806246
3 changed files with 20 additions and 7 deletions

View File

@@ -494,7 +494,7 @@ class Completion(BaseDefinition):
if self._definition.isinstance(pr.Import) and self._definition.alias is None: if self._definition.isinstance(pr.Import) and self._definition.alias is None:
i = imports.ImportPath(self._evaluator, self._definition, True) i = imports.ImportPath(self._evaluator, self._definition, True)
import_path = tuple(i.import_path + [unicode(self._name)]) import_path = tuple(i.import_path + [unicode(self._name)])
return imports.Importer(self._evaluator, import_path, return imports.get_importer(self._evaluator, import_path,
i._importer.module).follow(self._evaluator) i._importer.module).follow(self._evaluator)
return super(Completion, self)._follow_statements_imports() return super(Completion, self)._follow_statements_imports()

View File

@@ -88,6 +88,7 @@ from jedi.evaluate import precedence
class Evaluator(object): class Evaluator(object):
def __init__(self): def __init__(self):
self.memoize_cache = {} # for memoize decorators self.memoize_cache = {} # for memoize decorators
self.import_cache = {} # like `sys.modules`.
self.recursion_detector = recursion.RecursionDetector() self.recursion_detector = recursion.RecursionDetector()
self.execution_recursion_detector = recursion.ExecutionRecursionDetector() self.execution_recursion_detector = recursion.ExecutionRecursionDetector()

View File

@@ -70,7 +70,7 @@ class ImportPath(pr.Base):
import_path.pop() import_path.pop()
module = import_stmt.get_parent_until() module = import_stmt.get_parent_until()
self._importer = Importer(self._evaluator, tuple(import_path), module, self._importer = get_importer(self._evaluator, tuple(import_path), module,
import_stmt.relative_count) import_stmt.relative_count)
def __repr__(self): def __repr__(self):
@@ -221,7 +221,20 @@ class ImportPath(pr.Base):
return scopes return scopes
class Importer(use_metaclass(CachedMetaClass)): def get_importer(evaluator, import_path, module, level=0):
"""
Checks the evaluator caches first, which resembles the ``sys.modules``
cache and speeds up libraries like ``numpy``.
"""
try:
return evaluator.import_cache[import_path]
except KeyError:
importer = _Importer(evaluator, import_path, module, level)
evaluator.import_cache[import_path] = importer
return importer
class _Importer(object):
def __init__(self, evaluator, import_path, module, level=0): def __init__(self, evaluator, import_path, module, level=0):
""" """
An implementation similar to ``__import__``. Use `follow_file_system` An implementation similar to ``__import__``. Use `follow_file_system`
@@ -235,13 +248,12 @@ class Importer(use_metaclass(CachedMetaClass)):
:param import_path: List of namespaces (strings). :param import_path: List of namespaces (strings).
""" """
debug.speed('imp') debug.speed('import %s' % (import_path,))
self._evaluator = evaluator self._evaluator = evaluator
self.import_path = import_path self.import_path = import_path
self.level = level self.level = level
self.module = module self.module = module
path = module.path path = module.path
print(self.import_path)
# TODO abspath # TODO abspath
self.file_path = os.path.dirname(path) if path is not None else None self.file_path = os.path.dirname(path) if path is not None else None