forked from VimPlug/jedi
context -> value
This commit is contained in:
@@ -3,46 +3,46 @@ from collections import defaultdict
|
||||
from jedi import debug
|
||||
from jedi.inference.utils import PushBackIterator
|
||||
from jedi.inference import analysis
|
||||
from jedi.inference.lazy_context import LazyKnownContext, \
|
||||
from jedi.inference.lazy_value import LazyKnownContext, \
|
||||
LazyTreeContext, LazyUnknownContext
|
||||
from jedi.inference import docstrings
|
||||
from jedi.inference.context import iterable
|
||||
from jedi.inference.value import iterable
|
||||
|
||||
|
||||
def _add_argument_issue(error_name, lazy_context, message):
|
||||
if isinstance(lazy_context, LazyTreeContext):
|
||||
node = lazy_context.data
|
||||
def _add_argument_issue(error_name, lazy_value, message):
|
||||
if isinstance(lazy_value, LazyTreeContext):
|
||||
node = lazy_value.data
|
||||
if node.parent.type == 'argument':
|
||||
node = node.parent
|
||||
return analysis.add(lazy_context.context, error_name, node, message)
|
||||
return analysis.add(lazy_value.value, error_name, node, message)
|
||||
|
||||
|
||||
class ExecutedParam(object):
|
||||
"""Fake a param and give it values."""
|
||||
def __init__(self, execution_context, param_node, lazy_context, is_default=False):
|
||||
self._execution_context = execution_context
|
||||
def __init__(self, execution_value, param_node, lazy_value, is_default=False):
|
||||
self._execution_value = execution_value
|
||||
self._param_node = param_node
|
||||
self._lazy_context = lazy_context
|
||||
self._lazy_value = lazy_value
|
||||
self.string_name = param_node.name.value
|
||||
self._is_default = is_default
|
||||
|
||||
def infer_annotations(self):
|
||||
from jedi.inference.gradual.annotation import infer_param
|
||||
return infer_param(self._execution_context, self._param_node)
|
||||
return infer_param(self._execution_value, self._param_node)
|
||||
|
||||
def infer(self, use_hints=True):
|
||||
if use_hints:
|
||||
doc_params = docstrings.infer_param(self._execution_context, self._param_node)
|
||||
doc_params = docstrings.infer_param(self._execution_value, self._param_node)
|
||||
ann = self.infer_annotations().execute_annotation()
|
||||
if ann or doc_params:
|
||||
return ann | doc_params
|
||||
|
||||
return self._lazy_context.infer()
|
||||
return self._lazy_value.infer()
|
||||
|
||||
def matches_signature(self):
|
||||
if self._is_default:
|
||||
return True
|
||||
argument_contexts = self.infer(use_hints=False).py__class__()
|
||||
argument_values = self.infer(use_hints=False).py__class__()
|
||||
if self._param_node.star_count:
|
||||
return True
|
||||
annotations = self.infer_annotations()
|
||||
@@ -51,21 +51,21 @@ class ExecutedParam(object):
|
||||
# that the signature matches.
|
||||
return True
|
||||
matches = any(c1.is_sub_class_of(c2)
|
||||
for c1 in argument_contexts
|
||||
for c1 in argument_values
|
||||
for c2 in annotations.gather_annotation_classes())
|
||||
debug.dbg("signature compare %s: %s <=> %s",
|
||||
matches, argument_contexts, annotations, color='BLUE')
|
||||
matches, argument_values, annotations, color='BLUE')
|
||||
return matches
|
||||
|
||||
@property
|
||||
def var_args(self):
|
||||
return self._execution_context.var_args
|
||||
return self._execution_value.var_args
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s: %s>' % (self.__class__.__name__, self.string_name)
|
||||
|
||||
|
||||
def get_executed_params_and_issues(execution_context, arguments):
|
||||
def get_executed_params_and_issues(execution_value, arguments):
|
||||
def too_many_args(argument):
|
||||
m = _error_argument_count(funcdef, len(unpacked_va))
|
||||
# Just report an error for the first param that is not needed (like
|
||||
@@ -85,11 +85,11 @@ def get_executed_params_and_issues(execution_context, arguments):
|
||||
issues = [] # List[Optional[analysis issue]]
|
||||
result_params = []
|
||||
param_dict = {}
|
||||
funcdef = execution_context.tree_node
|
||||
# Default params are part of the context where the function was defined.
|
||||
funcdef = execution_value.tree_node
|
||||
# Default params are part of the value where the function was defined.
|
||||
# This means that they might have access on class variables that the
|
||||
# function itself doesn't have.
|
||||
default_param_context = execution_context.function_context.get_default_param_context()
|
||||
default_param_value = execution_value.function_value.get_default_param_value()
|
||||
|
||||
for param in funcdef.get_params():
|
||||
param_dict[param.name.value] = param
|
||||
@@ -118,14 +118,14 @@ def get_executed_params_and_issues(execution_context, arguments):
|
||||
had_multiple_value_error = True
|
||||
m = ("TypeError: %s() got multiple values for keyword argument '%s'."
|
||||
% (funcdef.name, key))
|
||||
for contextualized_node in arguments.get_calling_nodes():
|
||||
for valueualized_node in arguments.get_calling_nodes():
|
||||
issues.append(
|
||||
analysis.add(contextualized_node.context,
|
||||
analysis.add(valueualized_node.value,
|
||||
'type-error-multiple-values',
|
||||
contextualized_node.node, message=m)
|
||||
valueualized_node.node, message=m)
|
||||
)
|
||||
else:
|
||||
keys_used[key] = ExecutedParam(execution_context, key_param, argument)
|
||||
keys_used[key] = ExecutedParam(execution_value, key_param, argument)
|
||||
key, argument = next(var_arg_iterator, (None, None))
|
||||
|
||||
try:
|
||||
@@ -136,22 +136,22 @@ def get_executed_params_and_issues(execution_context, arguments):
|
||||
|
||||
if param.star_count == 1:
|
||||
# *args param
|
||||
lazy_context_list = []
|
||||
lazy_value_list = []
|
||||
if argument is not None:
|
||||
lazy_context_list.append(argument)
|
||||
lazy_value_list.append(argument)
|
||||
for key, argument in var_arg_iterator:
|
||||
# Iterate until a key argument is found.
|
||||
if key:
|
||||
var_arg_iterator.push_back((key, argument))
|
||||
break
|
||||
lazy_context_list.append(argument)
|
||||
seq = iterable.FakeSequence(execution_context.infer_state, u'tuple', lazy_context_list)
|
||||
lazy_value_list.append(argument)
|
||||
seq = iterable.FakeSequence(execution_value.infer_state, u'tuple', lazy_value_list)
|
||||
result_arg = LazyKnownContext(seq)
|
||||
elif param.star_count == 2:
|
||||
if argument is not None:
|
||||
too_many_args(argument)
|
||||
# **kwargs param
|
||||
dct = iterable.FakeDict(execution_context.infer_state, dict(non_matching_keys))
|
||||
dct = iterable.FakeDict(execution_value.infer_state, dict(non_matching_keys))
|
||||
result_arg = LazyKnownContext(dct)
|
||||
non_matching_keys = {}
|
||||
else:
|
||||
@@ -161,24 +161,24 @@ def get_executed_params_and_issues(execution_context, arguments):
|
||||
if param.default is None:
|
||||
result_arg = LazyUnknownContext()
|
||||
if not keys_only:
|
||||
for contextualized_node in arguments.get_calling_nodes():
|
||||
for valueualized_node in arguments.get_calling_nodes():
|
||||
m = _error_argument_count(funcdef, len(unpacked_va))
|
||||
issues.append(
|
||||
analysis.add(
|
||||
contextualized_node.context,
|
||||
valueualized_node.value,
|
||||
'type-error-too-few-arguments',
|
||||
contextualized_node.node,
|
||||
valueualized_node.node,
|
||||
message=m,
|
||||
)
|
||||
)
|
||||
else:
|
||||
result_arg = LazyTreeContext(default_param_context, param.default)
|
||||
result_arg = LazyTreeContext(default_param_value, param.default)
|
||||
is_default = True
|
||||
else:
|
||||
result_arg = argument
|
||||
|
||||
result_params.append(ExecutedParam(
|
||||
execution_context, param, result_arg,
|
||||
execution_value, param, result_arg,
|
||||
is_default=is_default
|
||||
))
|
||||
if not isinstance(result_arg, LazyUnknownContext):
|
||||
@@ -194,29 +194,29 @@ def get_executed_params_and_issues(execution_context, arguments):
|
||||
if not (non_matching_keys or had_multiple_value_error or
|
||||
param.star_count or param.default):
|
||||
# add a warning only if there's not another one.
|
||||
for contextualized_node in arguments.get_calling_nodes():
|
||||
for valueualized_node in arguments.get_calling_nodes():
|
||||
m = _error_argument_count(funcdef, len(unpacked_va))
|
||||
issues.append(
|
||||
analysis.add(contextualized_node.context,
|
||||
analysis.add(valueualized_node.value,
|
||||
'type-error-too-few-arguments',
|
||||
contextualized_node.node, message=m)
|
||||
valueualized_node.node, message=m)
|
||||
)
|
||||
|
||||
for key, lazy_context in non_matching_keys.items():
|
||||
for key, lazy_value in non_matching_keys.items():
|
||||
m = "TypeError: %s() got an unexpected keyword argument '%s'." \
|
||||
% (funcdef.name, key)
|
||||
issues.append(
|
||||
_add_argument_issue(
|
||||
'type-error-keyword-argument',
|
||||
lazy_context,
|
||||
lazy_value,
|
||||
message=m
|
||||
)
|
||||
)
|
||||
|
||||
remaining_arguments = list(var_arg_iterator)
|
||||
if remaining_arguments:
|
||||
first_key, lazy_context = remaining_arguments[0]
|
||||
too_many_args(lazy_context)
|
||||
first_key, lazy_value = remaining_arguments[0]
|
||||
too_many_args(lazy_value)
|
||||
return result_params, issues
|
||||
|
||||
|
||||
@@ -232,22 +232,22 @@ def _error_argument_count(funcdef, actual_count):
|
||||
% (funcdef.name, before, len(params), actual_count))
|
||||
|
||||
|
||||
def _create_default_param(execution_context, param):
|
||||
def _create_default_param(execution_value, param):
|
||||
if param.star_count == 1:
|
||||
result_arg = LazyKnownContext(
|
||||
iterable.FakeSequence(execution_context.infer_state, u'tuple', [])
|
||||
iterable.FakeSequence(execution_value.infer_state, u'tuple', [])
|
||||
)
|
||||
elif param.star_count == 2:
|
||||
result_arg = LazyKnownContext(
|
||||
iterable.FakeDict(execution_context.infer_state, {})
|
||||
iterable.FakeDict(execution_value.infer_state, {})
|
||||
)
|
||||
elif param.default is None:
|
||||
result_arg = LazyUnknownContext()
|
||||
else:
|
||||
result_arg = LazyTreeContext(execution_context.parent_context, param.default)
|
||||
return ExecutedParam(execution_context, param, result_arg)
|
||||
result_arg = LazyTreeContext(execution_value.parent_value, param.default)
|
||||
return ExecutedParam(execution_value, param, result_arg)
|
||||
|
||||
|
||||
def create_default_params(execution_context, funcdef):
|
||||
return [_create_default_param(execution_context, p)
|
||||
def create_default_params(execution_value, funcdef):
|
||||
return [_create_default_param(execution_value, p)
|
||||
for p in funcdef.get_params()]
|
||||
|
||||
Reference in New Issue
Block a user