forked from VimPlug/jedi
Fix the recursion detection.
This commit is contained in:
@@ -219,7 +219,7 @@ class Evaluator(object):
|
|||||||
str_element_names = [str(e) for e in element_names]
|
str_element_names = [str(e) for e in element_names]
|
||||||
if any(str(i) in str_element_names for i in if_names):
|
if any(str(i) in str_element_names for i in if_names):
|
||||||
for if_name in if_names:
|
for if_name in if_names:
|
||||||
definitions = self.goto_definitions(if_name)
|
definitions = self.goto_definitions(context, if_name)
|
||||||
# Every name that has multiple different definitions
|
# Every name that has multiple different definitions
|
||||||
# causes the complexity to rise. The complexity should
|
# causes the complexity to rise. The complexity should
|
||||||
# never fall below 1.
|
# never fall below 1.
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ count the function calls.
|
|||||||
"""
|
"""
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi import settings
|
from jedi import settings
|
||||||
from jedi.evaluate import iterable
|
|
||||||
|
|
||||||
|
|
||||||
def recursion_decorator(func):
|
def recursion_decorator(func):
|
||||||
@@ -92,7 +91,6 @@ class _RecursionNode(object):
|
|||||||
|
|
||||||
|
|
||||||
def execution_recursion_decorator(func):
|
def execution_recursion_decorator(func):
|
||||||
return func # TODO remove
|
|
||||||
def run(execution, **kwargs):
|
def run(execution, **kwargs):
|
||||||
detector = execution._evaluator.execution_recursion_detector
|
detector = execution._evaluator.execution_recursion_detector
|
||||||
if detector.push_execution(execution):
|
if detector.push_execution(execution):
|
||||||
@@ -131,19 +129,17 @@ class ExecutionRecursionDetector(object):
|
|||||||
self.recursion_level -= 1
|
self.recursion_level -= 1
|
||||||
|
|
||||||
def push_execution(self, execution):
|
def push_execution(self, execution):
|
||||||
in_par_execution_funcs = execution.base in self.parent_execution_funcs
|
in_par_execution_funcs = execution.funcdef in self.parent_execution_funcs
|
||||||
in_execution_funcs = execution.base in self.execution_funcs
|
in_execution_funcs = execution.funcdef in self.execution_funcs
|
||||||
self.recursion_level += 1
|
self.recursion_level += 1
|
||||||
self.execution_count += 1
|
self.execution_count += 1
|
||||||
self.execution_funcs.add(execution.base)
|
self.execution_funcs.add(execution.funcdef)
|
||||||
self.parent_execution_funcs.append(execution.base)
|
self.parent_execution_funcs.append(execution.funcdef)
|
||||||
|
|
||||||
if self.execution_count > settings.max_executions:
|
if self.execution_count > settings.max_executions:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if isinstance(execution.base, (iterable.Array, iterable.Generator)):
|
module = execution.get_root_context()
|
||||||
return False
|
|
||||||
module = execution.get_parent_until()
|
|
||||||
if module == self._evaluator.BUILTINS:
|
if module == self._evaluator.BUILTINS:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
@@ -643,11 +643,9 @@ class FunctionExecutionContext(Executed):
|
|||||||
multiple calls to functions and recursion has to be avoided. But this is
|
multiple calls to functions and recursion has to be avoided. But this is
|
||||||
responsibility of the decorators.
|
responsibility of the decorators.
|
||||||
"""
|
"""
|
||||||
type = 'funcdef'
|
|
||||||
|
|
||||||
def __init__(self, evaluator, parent_context, funcdef, var_args):
|
def __init__(self, evaluator, parent_context, funcdef, var_args):
|
||||||
super(FunctionExecutionContext, self).__init__(evaluator, parent_context, var_args)
|
super(FunctionExecutionContext, self).__init__(evaluator, parent_context, var_args)
|
||||||
self._funcdef = funcdef
|
self.funcdef = funcdef
|
||||||
if isinstance(funcdef, mixed.MixedObject):
|
if isinstance(funcdef, mixed.MixedObject):
|
||||||
# The extra information in mixed is not needed anymore. We can just
|
# The extra information in mixed is not needed anymore. We can just
|
||||||
# unpack it and give it the tree object.
|
# unpack it and give it the tree object.
|
||||||
@@ -666,7 +664,7 @@ class FunctionExecutionContext(Executed):
|
|||||||
@memoize_default(default=set())
|
@memoize_default(default=set())
|
||||||
@recursion.execution_recursion_decorator
|
@recursion.execution_recursion_decorator
|
||||||
def get_return_types(self, check_yields=False):
|
def get_return_types(self, check_yields=False):
|
||||||
funcdef = self._funcdef
|
funcdef = self.funcdef
|
||||||
if funcdef.type in ('lambdef', 'lambdef_nocond'):
|
if funcdef.type in ('lambdef', 'lambdef_nocond'):
|
||||||
return self._evaluator.eval_element(self.children[-1])
|
return self._evaluator.eval_element(self.children[-1])
|
||||||
|
|
||||||
@@ -763,16 +761,16 @@ class FunctionExecutionContext(Executed):
|
|||||||
del evaluator.predefined_if_name_dict_dict[for_stmt]
|
del evaluator.predefined_if_name_dict_dict[for_stmt]
|
||||||
|
|
||||||
def get_filters(self, search_global, until_position=None, origin_scope=None):
|
def get_filters(self, search_global, until_position=None, origin_scope=None):
|
||||||
yield FunctionExecutionFilter(self._evaluator, self, self._funcdef,
|
yield FunctionExecutionFilter(self._evaluator, self, self.funcdef,
|
||||||
until_position,
|
until_position,
|
||||||
origin_scope=origin_scope)
|
origin_scope=origin_scope)
|
||||||
|
|
||||||
@memoize_default(default=NO_DEFAULT)
|
@memoize_default(default=NO_DEFAULT)
|
||||||
def get_params(self):
|
def get_params(self):
|
||||||
return param.get_params(self._evaluator, self._funcdef, self.var_args)
|
return param.get_params(self._evaluator, self.funcdef, self.var_args)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<%s of %s>" % (type(self).__name__, self._funcdef)
|
return "<%s of %s>" % (type(self).__name__, self.funcdef)
|
||||||
|
|
||||||
|
|
||||||
class GlobalName(helpers.FakeName):
|
class GlobalName(helpers.FakeName):
|
||||||
|
|||||||
Reference in New Issue
Block a user