From 03efbca5866c78b223a41320a83dd96b4c20b6f1 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Mon, 16 Nov 2015 11:30:30 +0100 Subject: [PATCH] Tried to get the recursion issues with if stmts working. --- jedi/evaluate/__init__.py | 16 ++++++++-------- jedi/parser/tree.py | 15 +++++++++++++-- test/completion/flow_analysis.py | 20 ++++++++++++++++++++ test/conftest.py | 1 + 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index bf2d619f..adc1d292 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -189,19 +189,19 @@ class Evaluator(object): elif isinstance(element, iterable.MergedNodes): return set(iterable.unite(self.eval_element(e) for e in element)) - parent = element.get_parent_until((tree.IfStmt, tree.ForStmt, tree.IsScope)) - predefined_if_name_dict = self.predefined_if_name_dict_dict.get(parent) - if not predefined_if_name_dict and isinstance(parent, tree.IfStmt): - if_stmt = parent.children[1] + if_stmt = element.get_parent_until((tree.IfStmt, tree.ForStmt, tree.IsScope)) + predefined_if_name_dict = self.predefined_if_name_dict_dict.get(if_stmt) + if not predefined_if_name_dict and isinstance(if_stmt, tree.IfStmt): + if_stmt_test = if_stmt.children[1] name_dicts = [{}] # If we already did a check, we don't want to do it again -> If # predefined_if_name_dict_dict is filled, we stop. # We don't want to check the if stmt itself, it's just about # the content. - if element.start_pos > if_stmt.end_pos: + if element.start_pos > if_stmt_test.end_pos: # Now we need to check if the names in the if_stmt match the # names in the suite. - if_names = helpers.get_names_of_node(if_stmt) + if_names = helpers.get_names_of_node(if_stmt_test) element_names = helpers.get_names_of_node(element) str_element_names = [str(e) for e in element_names] if any(str(i) in str_element_names for i in if_names): @@ -234,11 +234,11 @@ class Evaluator(object): if len(name_dicts) > 1: result = set() for name_dict in name_dicts: - self.predefined_if_name_dict_dict[parent] = name_dict + self.predefined_if_name_dict_dict[if_stmt] = name_dict try: result |= self._eval_element_not_cached(element) finally: - del self.predefined_if_name_dict_dict[parent] + del self.predefined_if_name_dict_dict[if_stmt] return result else: return self._eval_element_cached(element) diff --git a/jedi/parser/tree.py b/jedi/parser/tree.py index f2692889..e59e4279 100644 --- a/jedi/parser/tree.py +++ b/jedi/parser/tree.py @@ -985,9 +985,20 @@ class IfStmt(Flow): yield self.children[i + 1] def node_in_which_check_node(self, node): + """ + Returns the check node (see function above) that a node is contained + in. However if it the node is in the check node itself and not in the + suite return None. + """ + start_pos = node.start_pos for check_node in reversed(list(self.check_nodes())): - if check_node.start_pos < node.start_pos: - return check_node + if check_node.start_pos < start_pos: + if start_pos < check_node.end_pos: + return None + # In this case the node is within the check_node itself, + # not in the suite + else: + return check_node def node_after_else(self, node): """ diff --git a/test/completion/flow_analysis.py b/test/completion/flow_analysis.py index 933badf5..d8aa6edd 100644 --- a/test/completion/flow_analysis.py +++ b/test/completion/flow_analysis.py @@ -218,3 +218,23 @@ else: a = '' #? int() a + + +# ----------------- +# Recursion issues +# ----------------- + +def possible_recursion_error(filename): + if filename == 'a': + return filename + # It seems like without the brackets there wouldn't be a RecursionError. + elif type(filename) == str: + return filename + + +if NOT_DEFINED: + s = str() +else: + s = str() +#? str() +possible_recursion_error(s) diff --git a/test/conftest.py b/test/conftest.py index 7349279a..cbec5206 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -6,6 +6,7 @@ import pytest from . import helpers from . import run from . import refactor + import jedi from jedi.evaluate.analysis import Warning