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):
|
if isinstance(context, CompForContext):
|
||||||
return eval_node(context, element)
|
return eval_node(context, element)
|
||||||
|
|
||||||
|
#import traceback, sys; traceback.print_stack(file=sys.stdout)
|
||||||
|
#print(element, id(context), context)
|
||||||
if_stmt = element
|
if_stmt = element
|
||||||
while if_stmt is not None:
|
while if_stmt is not None:
|
||||||
if_stmt = if_stmt.parent
|
if_stmt = if_stmt.parent
|
||||||
|
|||||||
@@ -33,13 +33,27 @@ from jedi import debug
|
|||||||
from jedi import parser_utils
|
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
|
Evaluates an annotation node. This means that it evaluates the part of
|
||||||
If index is not None, the annotation is expected to be a tuple
|
`int` here:
|
||||||
and we're interested in that index
|
|
||||||
|
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):
|
def _evaluate_annotation_string(context, string, index=None):
|
||||||
@@ -56,22 +70,6 @@ def _evaluate_annotation_string(context, string, index=None):
|
|||||||
return context_set
|
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):
|
def _get_forward_reference_node(context, string):
|
||||||
try:
|
try:
|
||||||
new_node = context.evaluator.grammar.parse(
|
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.
|
# Annotations are like default params and resolve in the same way.
|
||||||
context = execution_context.function_context.get_default_param_context()
|
context = execution_context.function_context.get_default_param_context()
|
||||||
return evaluate_for_annotation(context, annotation)
|
return eval_annotation(context, annotation)
|
||||||
|
|
||||||
|
|
||||||
def py__annotations__(funcdef):
|
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()
|
context = function_execution_context.function_context.get_default_param_context()
|
||||||
unknown_type_vars = list(find_unknown_type_vars(context, annotation))
|
unknown_type_vars = list(find_unknown_type_vars(context, annotation))
|
||||||
# TODO this function should return the annotation context.
|
annotation_contexts = eval_annotation(context, annotation)
|
||||||
annotation = _fix_forward_reference(context, annotation)
|
|
||||||
annotation_contexts = context.eval_node(annotation)
|
|
||||||
if not unknown_type_vars:
|
if not unknown_type_vars:
|
||||||
return annotation_contexts.execute_annotation()
|
return annotation_contexts.execute_annotation()
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ def eval_node(context, element):
|
|||||||
elif typ == 'eval_input':
|
elif typ == 'eval_input':
|
||||||
return eval_node(context, element.children[0])
|
return eval_node(context, element.children[0])
|
||||||
elif typ == 'annassign':
|
elif typ == 'annassign':
|
||||||
return pep0484.evaluate_for_annotation(context, element.children[1]) \
|
return pep0484.eval_annotation(context, element.children[1]) \
|
||||||
.execute_annotation()
|
.execute_annotation()
|
||||||
elif typ == 'yield_expr':
|
elif typ == 'yield_expr':
|
||||||
if len(element.children) and element.children[1].type == 'yield_arg':
|
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":
|
if expr_stmt.type == "expr_stmt" and expr_stmt.children[1].type == "annassign":
|
||||||
correct_scope = parser_utils.get_parent_scope(name) == context.tree_node
|
correct_scope = parser_utils.get_parent_scope(name) == context.tree_node
|
||||||
if correct_scope:
|
if correct_scope:
|
||||||
context_set |= pep0484.evaluate_for_annotation(
|
context_set |= pep0484.eval_annotation(
|
||||||
context, expr_stmt.children[1].children[1]
|
context, expr_stmt.children[1].children[1]
|
||||||
).execute_annotation()
|
).execute_annotation()
|
||||||
if context_set:
|
if context_set:
|
||||||
|
|||||||
Reference in New Issue
Block a user