Restructure eval_annotation so that it's more understandable

This commit is contained in:
Dave Halter
2018-12-09 20:46:29 +01:00
parent aa4846bff6
commit 3940fd8eff
3 changed files with 25 additions and 27 deletions

View File

@@ -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

View File

@@ -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()

View File

@@ -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: