diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 2be17f30..040b1742 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -178,6 +178,8 @@ class Evaluator(object): if isinstance(context, CompForContext): return eval_node(context, element) + #import traceback, sys; traceback.print_stack(file=sys.stdout) + #print(element, id(context), context) if_stmt = element while if_stmt is not None: if_stmt = if_stmt.parent diff --git a/jedi/evaluate/pep0484.py b/jedi/evaluate/pep0484.py index 09605e9d..a85e9d9d 100644 --- a/jedi/evaluate/pep0484.py +++ b/jedi/evaluate/pep0484.py @@ -33,13 +33,27 @@ from jedi import debug from jedi import parser_utils -def evaluate_for_annotation(context, annotation, index=None): +def eval_annotation(context, annotation): """ - Evaluates a string-node, looking for an annotation - If index is not None, the annotation is expected to be a tuple - and we're interested in that index + Evaluates an annotation node. This means that it evaluates the part of + `int` here: + + foo: int = 3 + + Also checks for forward references (strings) """ - return context.eval_node(_fix_forward_reference(context, annotation)) + context_set = context.eval_node(annotation) + if len(context_set) != 1: + debug.warning("Eval'ed typing index %s should lead to 1 object, " + " not %s" % (annotation, context_set)) + return context_set + + evaled_context = list(context_set)[0] + if is_string(evaled_context): + result = _get_forward_reference_node(context, evaled_context.get_safe_value()) + if result is not None: + return context.eval_node(result) + return context_set def _evaluate_annotation_string(context, string, index=None): @@ -56,22 +70,6 @@ def _evaluate_annotation_string(context, string, index=None): return context_set -def _fix_forward_reference(context, node): - evaled_nodes = context.eval_node(node) - if len(evaled_nodes) != 1: - debug.warning("Eval'ed typing index %s should lead to 1 object, " - " not %s" % (node, evaled_nodes)) - return node - - evaled_context = list(evaled_nodes)[0] - if is_string(evaled_context): - result = _get_forward_reference_node(context, evaled_context.get_safe_value()) - if result is not None: - return result - - return node - - def _get_forward_reference_node(context, string): try: new_node = context.evaluator.grammar.parse( @@ -169,7 +167,7 @@ def infer_param(execution_context, param): ) # Annotations are like default params and resolve in the same way. context = execution_context.function_context.get_default_param_context() - return evaluate_for_annotation(context, annotation) + return eval_annotation(context, annotation) def py__annotations__(funcdef): @@ -213,9 +211,7 @@ def infer_return_types(function_execution_context): context = function_execution_context.function_context.get_default_param_context() unknown_type_vars = list(find_unknown_type_vars(context, annotation)) - # TODO this function should return the annotation context. - annotation = _fix_forward_reference(context, annotation) - annotation_contexts = context.eval_node(annotation) + annotation_contexts = eval_annotation(context, annotation) if not unknown_type_vars: return annotation_contexts.execute_annotation() diff --git a/jedi/evaluate/syntax_tree.py b/jedi/evaluate/syntax_tree.py index a53d22f6..508b58d9 100644 --- a/jedi/evaluate/syntax_tree.py +++ b/jedi/evaluate/syntax_tree.py @@ -130,7 +130,7 @@ def eval_node(context, element): elif typ == 'eval_input': return eval_node(context, element.children[0]) elif typ == 'annassign': - return pep0484.evaluate_for_annotation(context, element.children[1]) \ + return pep0484.eval_annotation(context, element.children[1]) \ .execute_annotation() elif typ == 'yield_expr': if len(element.children) and element.children[1].type == 'yield_arg': @@ -552,7 +552,7 @@ def tree_name_to_contexts(evaluator, context, tree_name): if expr_stmt.type == "expr_stmt" and expr_stmt.children[1].type == "annassign": correct_scope = parser_utils.get_parent_scope(name) == context.tree_node if correct_scope: - context_set |= pep0484.evaluate_for_annotation( + context_set |= pep0484.eval_annotation( context, expr_stmt.children[1].children[1] ).execute_annotation() if context_set: