Refactor compiled.CompiledObject so it always owns an evaluator instance.

This commit is contained in:
Dave Halter
2015-12-08 02:19:33 +01:00
parent 18a10c436f
commit bef5fca516
13 changed files with 149 additions and 139 deletions

View File

@@ -9,7 +9,6 @@ count the function calls.
"""
from jedi import debug
from jedi import settings
from jedi.evaluate import compiled
from jedi.evaluate import iterable
@@ -31,12 +30,13 @@ class RecursionDetector(object):
A decorator to detect recursions in statements. In a recursion a statement
at the same place, in the same module may not be executed two times.
"""
def __init__(self):
def __init__(self, evaluator):
self.top = None
self.current = None
self._evaluator = evaluator
def push_stmt(self, stmt):
self.current = _RecursionNode(stmt, self.current)
self.current = _RecursionNode(self._evaluator, stmt, self.current)
check = self._check_recursion()
if check:
debug.warning('catched stmt recursion: %s against %s @%s', stmt,
@@ -71,7 +71,8 @@ class RecursionDetector(object):
class _RecursionNode(object):
""" A node of the RecursionDecorator. """
def __init__(self, stmt, parent):
def __init__(self, evaluator, stmt, parent):
self._evaluator = evaluator
self.script = stmt.get_parent_until()
self.position = stmt.start_pos
self.parent = parent
@@ -80,7 +81,7 @@ class _RecursionNode(object):
# Don't check param instances, they are not causing recursions
# The same's true for the builtins, because the builtins are really
# simple.
self.is_ignored = self.script == compiled.builtin
self.is_ignored = self.script == self._evaluator.BUILTINS
def __eq__(self, other):
if not other:
@@ -107,13 +108,13 @@ def execution_recursion_decorator(func):
class ExecutionRecursionDetector(object):
"""
Catches recursions of executions.
It is designed like a Singelton. Only one instance should exist.
"""
def __init__(self):
def __init__(self, evaluator):
self.recursion_level = 0
self.parent_execution_funcs = []
self.execution_funcs = set()
self.execution_count = 0
self._evaluator = evaluator
def __call__(self, execution):
debug.dbg('Execution recursions: %s', execution, self.recursion_level,
@@ -125,33 +126,33 @@ class ExecutionRecursionDetector(object):
self.pop_execution()
return result
def pop_execution(cls):
cls.parent_execution_funcs.pop()
cls.recursion_level -= 1
def pop_execution(self):
self.parent_execution_funcs.pop()
self.recursion_level -= 1
def push_execution(cls, execution):
in_par_execution_funcs = execution.base in cls.parent_execution_funcs
in_execution_funcs = execution.base in cls.execution_funcs
cls.recursion_level += 1
cls.execution_count += 1
cls.execution_funcs.add(execution.base)
cls.parent_execution_funcs.append(execution.base)
def push_execution(self, execution):
in_par_execution_funcs = execution.base in self.parent_execution_funcs
in_execution_funcs = execution.base in self.execution_funcs
self.recursion_level += 1
self.execution_count += 1
self.execution_funcs.add(execution.base)
self.parent_execution_funcs.append(execution.base)
if cls.execution_count > settings.max_executions:
if self.execution_count > settings.max_executions:
return True
if isinstance(execution.base, (iterable.Array, iterable.Generator)):
return False
module = execution.get_parent_until()
if module == compiled.builtin:
if module == self._evaluator.BUILTINS:
return False
if in_par_execution_funcs:
if cls.recursion_level > settings.max_function_recursion_level:
if self.recursion_level > settings.max_function_recursion_level:
return True
if in_execution_funcs and \
len(cls.execution_funcs) > settings.max_until_execution_unique:
len(self.execution_funcs) > settings.max_until_execution_unique:
return True
if cls.execution_count > settings.max_executions_without_builtins:
if self.execution_count > settings.max_executions_without_builtins:
return True
return False