forked from VimPlug/jedi
significant speedup due to compiled caching
This commit is contained in:
@@ -80,7 +80,7 @@ class LazyName(helpers.FakeName):
|
||||
mod)
|
||||
|
||||
module = compiled.CompiledObject(raw_module)
|
||||
return compiled.create(self._value, module, module)
|
||||
return compiled.create(self._evaluator, self._value, module, module)
|
||||
|
||||
@parent.setter
|
||||
def parent(self, value):
|
||||
|
||||
@@ -89,6 +89,7 @@ class Evaluator(object):
|
||||
def __init__(self):
|
||||
self.memoize_cache = {} # for memoize decorators
|
||||
self.import_cache = {} # like `sys.modules`.
|
||||
self.compiled_cache = {} # see `compiled.create()`
|
||||
self.recursion_detector = recursion.RecursionDetector()
|
||||
self.execution_recursion_detector = recursion.ExecutionRecursionDetector()
|
||||
|
||||
@@ -137,10 +138,10 @@ class Evaluator(object):
|
||||
# only in for loops without clutter, because they are
|
||||
# predictable.
|
||||
for r in result:
|
||||
left = precedence.calculate(left, operator, [r])
|
||||
left = precedence.calculate(self, left, operator, [r])
|
||||
result = left
|
||||
else:
|
||||
result = precedence.calculate(left, operator, result)
|
||||
result = precedence.calculate(self, left, operator, result)
|
||||
elif len(stmt.get_set_vars()) > 1 and seek_name and ass_details:
|
||||
# Assignment checking is only important if the statement defines
|
||||
# multiple variables.
|
||||
@@ -173,7 +174,7 @@ class Evaluator(object):
|
||||
def _eval_precedence(self, _precedence):
|
||||
left = self.process_precedence_element(_precedence.left)
|
||||
right = self.process_precedence_element(_precedence.right)
|
||||
return precedence.calculate(left, _precedence.operator, right)
|
||||
return precedence.calculate(self, left, _precedence.operator, right)
|
||||
|
||||
def _eval_statement_element(self, element):
|
||||
if pr.Array.is_type(element, pr.Array.NOARRAY):
|
||||
@@ -227,7 +228,7 @@ class Evaluator(object):
|
||||
search_global=True)
|
||||
else:
|
||||
# for pr.Literal
|
||||
types = [compiled.create(current.value)]
|
||||
types = [compiled.create(self, current.value)]
|
||||
types = imports.strip_imports(self, types)
|
||||
|
||||
return self.follow_path(path, types, scope)
|
||||
|
||||
@@ -337,11 +337,18 @@ def _create_from_name(module, parent, name):
|
||||
return CompiledObject(obj, parent)
|
||||
|
||||
|
||||
def create(obj, parent=builtin, module=None):
|
||||
def create(evaluator, obj, parent=builtin, module=None):
|
||||
"""
|
||||
A very weird interface class to this module. The more options provided the
|
||||
more acurate loading compiled objects is.
|
||||
"""
|
||||
# Do a very cheap form of caching here.
|
||||
key = id(obj), id(parent), id(module)
|
||||
try:
|
||||
return evaluator.compiled_cache[key]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if not inspect.ismodule(obj):
|
||||
faked = fake.get_faked(module and module.obj, obj)
|
||||
if faked is not None:
|
||||
|
||||
@@ -102,7 +102,7 @@ class NameFinder(object):
|
||||
"""Checks for both __getattr__ and __getattribute__ methods"""
|
||||
result = []
|
||||
# str is important to lose the NamePart!
|
||||
name = compiled.create(str(self.name_str))
|
||||
name = compiled.create(self._evaluator, str(self.name_str))
|
||||
with common.ignored(KeyError):
|
||||
result = inst.execute_subscope_by_name('__getattr__', [name])
|
||||
if not result:
|
||||
|
||||
@@ -174,12 +174,12 @@ def _check_operator(iterator, priority=PythonGrammar.LOWEST_PRIORITY):
|
||||
return left
|
||||
|
||||
|
||||
def calculate(left_result, operator, right_result):
|
||||
def calculate(evaluator, left_result, operator, right_result):
|
||||
result = []
|
||||
if left_result is None and right_result:
|
||||
# cases like `-1` or `1 + ~1`
|
||||
for right in right_result:
|
||||
result.append(_factor_calculate(operator, right))
|
||||
result.append(_factor_calculate(evaluator, operator, right))
|
||||
return result
|
||||
else:
|
||||
if not left_result or not right_result:
|
||||
@@ -187,14 +187,14 @@ def calculate(left_result, operator, right_result):
|
||||
|
||||
for left in left_result:
|
||||
for right in right_result:
|
||||
result += _element_calculate(left, operator, right)
|
||||
result += _element_calculate(evaluator, left, operator, right)
|
||||
return result
|
||||
|
||||
|
||||
def _factor_calculate(operator, right):
|
||||
def _factor_calculate(evaluator, operator, right):
|
||||
if _is_number(right):
|
||||
if operator == '-':
|
||||
return create(-right.obj)
|
||||
return create(evaluator, -right.obj)
|
||||
return right
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ def _is_number(obj):
|
||||
and isinstance(obj.obj, (int, float))
|
||||
|
||||
|
||||
def _element_calculate(left, operator, right):
|
||||
def _element_calculate(evaluator, left, operator, right):
|
||||
def is_string(obj):
|
||||
return isinstance(obj, CompiledObject) \
|
||||
and isinstance(obj.obj, (str, unicode))
|
||||
@@ -215,8 +215,8 @@ def _element_calculate(left, operator, right):
|
||||
return [left]
|
||||
elif operator == '+':
|
||||
if _is_number(left) and _is_number(right) or is_string(left) and is_string(right):
|
||||
return [create(left.obj + right.obj)]
|
||||
return [create(evaluator, left.obj + right.obj)]
|
||||
elif operator == '-':
|
||||
if _is_number(left) and _is_number(right):
|
||||
return [create(left.obj - right.obj)]
|
||||
return [create(evaluator, left.obj - right.obj)]
|
||||
return [left, right]
|
||||
|
||||
@@ -16,7 +16,7 @@ def test_simple():
|
||||
|
||||
|
||||
def test_fake_loading():
|
||||
assert isinstance(compiled.create(next), Function)
|
||||
assert isinstance(compiled.create(Evaluator(), next), Function)
|
||||
|
||||
string = compiled.builtin.get_subscope_by_name('str')
|
||||
from_name = compiled._create_from_name(
|
||||
@@ -28,7 +28,7 @@ def test_fake_loading():
|
||||
|
||||
|
||||
def test_fake_docstr():
|
||||
assert compiled.create(next).raw_doc == next.__doc__
|
||||
assert compiled.create(Evaluator(), next).raw_doc == next.__doc__
|
||||
|
||||
|
||||
def test_parse_function_doc_illegal_docstr():
|
||||
|
||||
Reference in New Issue
Block a user