mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 14:04:26 +08:00
Restructure eval_annotation so that it's more understandable
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user