From 7b8d4e86ac12d52d243f3bc0890d46b81c8c560c Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Sun, 13 Dec 2015 17:18:19 +0100 Subject: [PATCH] The evaluator recursion limitations are now reset in static analysis for each node, otherwise it's incredibly unprecise. --- jedi/api/__init__.py | 1 + jedi/evaluate/__init__.py | 8 ++++++-- jedi/evaluate/analysis.py | 4 ++-- jedi/evaluate/iterable.py | 10 ++++------ jedi/evaluate/param.py | 1 - test/static_analysis/iterable.py | 4 ++++ 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 073846f9..4423755d 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -571,6 +571,7 @@ class Script(object): unpack_tuple_to_dict(self._evaluator, types, testlist) else: try_iter_content(self._evaluator.goto_definition(node)) + self._evaluator.reset_recursion_limitations() ana = [a for a in self._evaluator.analysis if self.path == a.path] return sorted(set(ana), key=lambda x: x.line) diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index fa39f26c..8167a5e6 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -86,8 +86,6 @@ class Evaluator(object): # To memorize modules -> equals `sys.modules`. self.modules = {} # like `sys.modules`. self.compiled_cache = {} # see `compiled.create()` - self.recursion_detector = recursion.RecursionDetector(self) - self.execution_recursion_detector = recursion.ExecutionRecursionDetector(self) self.analysis = [] self.predefined_if_name_dict_dict = {} self.is_analysis = False @@ -100,9 +98,15 @@ class Evaluator(object): except ValueError: pass + self.reset_recursion_limitations() + # Constants self.BUILTINS = compiled.get_special_object(self, 'BUILTINS') + def reset_recursion_limitations(self): + self.recursion_detector = recursion.RecursionDetector(self) + self.execution_recursion_detector = recursion.ExecutionRecursionDetector(self) + def wrap(self, element): if isinstance(element, tree.Class): return er.Class(self, element) diff --git a/jedi/evaluate/analysis.py b/jedi/evaluate/analysis.py index d0ed42bf..07e7c69a 100644 --- a/jedi/evaluate/analysis.py +++ b/jedi/evaluate/analysis.py @@ -22,8 +22,8 @@ CODES = { 'type-error-not-iterable': (11, TypeError, None), 'type-error-isinstance': (12, TypeError, None), 'type-error-not-subscriptable': (13, TypeError, None), - 'value-error-too-many-values': (13, ValueError, None), - 'value-error-too-few-values': (13, ValueError, None), + 'value-error-too-many-values': (14, ValueError, None), + 'value-error-too-few-values': (15, ValueError, None), } diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index 48f7058c..d3a18acc 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -263,9 +263,7 @@ class Array(IterableWrapper, ArrayMixin): for _ in types: yield types else: - iterate = self._items() - - for value in iterate: + for value in self._items(): yield self._evaluator.eval_element(value) additions = check_array_additions(self._evaluator, self) @@ -392,8 +390,8 @@ def unpack_tuple_to_dict(evaluator, types, exprlist): 'testlist_star_expr'): dct = {} parts = iter(exprlist.children[::2]) - n = 1 - for iter_types in enumerate(py__iter__(evaluator, types, exprlist)): + n = 0 + for iter_types in py__iter__(evaluator, types, exprlist): n += 1 try: part = next(parts) @@ -403,7 +401,7 @@ def unpack_tuple_to_dict(evaluator, types, exprlist): else: dct.update(unpack_tuple_to_dict(evaluator, iter_types, part)) has_parts = next(parts, None) - if has_parts is not None: + if n > 0 and has_parts is not None: analysis.add(evaluator, 'value-error-too-few-values', has_parts, message="ValueError: need more than %s values to unpack" % n) return dct diff --git a/jedi/evaluate/param.py b/jedi/evaluate/param.py index c6955690..ffcb9475 100644 --- a/jedi/evaluate/param.py +++ b/jedi/evaluate/param.py @@ -372,7 +372,6 @@ def get_params(evaluator, func, var_args): # print('\t\tnonkw', non_kw_param.parent.var_args.argument_node, ) if origin_args not in [f.parent.parent for f in first_values]: continue - print(v) analysis.add(evaluator, 'type-error-too-many-arguments', v, message=m) return param_names diff --git a/test/static_analysis/iterable.py b/test/static_analysis/iterable.py index 0a1f5a65..f6ff9728 100644 --- a/test/static_analysis/iterable.py +++ b/test/static_analysis/iterable.py @@ -12,3 +12,7 @@ for x in dct: #! 4 type-error-not-iterable for x, y in dct: pass + +# Shouldn't cause issues, because if there are no types (or we don't know what +# the types are, we should just ignore it. +a, b = []