mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 22:44:27 +08:00
Also return the issues when retruning the executed params
This commit is contained in:
@@ -86,9 +86,10 @@ def add(node_context, error_name, node, message=None, typ=Error, payload=None):
|
||||
# TODO this path is probably not right
|
||||
module_context = node_context.get_root_context()
|
||||
module_path = module_context.py__file__()
|
||||
instance = typ(error_name, module_path, node.start_pos, message)
|
||||
debug.warning(str(instance), format=False)
|
||||
node_context.evaluator.analysis.append(instance)
|
||||
issue_instance = typ(error_name, module_path, node.start_pos, message)
|
||||
debug.warning(str(issue_instance), format=False)
|
||||
node_context.evaluator.analysis.append(issue_instance)
|
||||
return issue_instance
|
||||
|
||||
|
||||
def _check_for_setattr(instance):
|
||||
|
||||
@@ -11,7 +11,7 @@ from jedi.evaluate.lazy_context import LazyKnownContext, LazyKnownContexts, \
|
||||
from jedi.evaluate.filters import ParamName
|
||||
from jedi.evaluate.base_context import NO_CONTEXTS, ContextSet
|
||||
from jedi.evaluate.context import iterable
|
||||
from jedi.evaluate.param import get_executed_params, ExecutedParam
|
||||
from jedi.evaluate.param import get_executed_params_and_issues, ExecutedParam
|
||||
|
||||
|
||||
def try_iter_content(types, depth=0):
|
||||
@@ -148,12 +148,12 @@ class AbstractArguments(object):
|
||||
def unpack(self, funcdef=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_executed_params(self, execution_context):
|
||||
return get_executed_params(execution_context, self)
|
||||
def get_executed_params_and_issues(self, execution_context):
|
||||
return get_executed_params_and_issues(execution_context, self)
|
||||
|
||||
|
||||
class AnonymousArguments(AbstractArguments):
|
||||
def get_executed_params(self, execution_context):
|
||||
def get_executed_params_and_issues(self, execution_context):
|
||||
from jedi.evaluate.dynamic import search_params
|
||||
return search_params(
|
||||
execution_context.evaluator,
|
||||
|
||||
@@ -106,7 +106,7 @@ class FunctionContext(use_metaclass(CachedMetaClass, AbstractFunction)):
|
||||
if overloaded_funcs:
|
||||
return OverloadedFunctionContext(
|
||||
function,
|
||||
ContextSet.from_iterable(create(f) for f in overloaded_funcs)
|
||||
[create(f) for f in overloaded_funcs]
|
||||
)
|
||||
return function
|
||||
|
||||
@@ -273,12 +273,16 @@ class FunctionExecutionContext(TreeContext):
|
||||
origin_scope=origin_scope)
|
||||
|
||||
@evaluator_method_cache()
|
||||
def get_executed_params(self):
|
||||
return self.var_args.get_executed_params(self)
|
||||
def get_executed_params_and_issues(self):
|
||||
return self.var_args.get_executed_params_and_issues(self)
|
||||
|
||||
def matches_signature(self):
|
||||
executed_params, issues = self.get_executed_params_and_issues()
|
||||
if issues:
|
||||
return False
|
||||
|
||||
matches = all(executed_param.matches_signature()
|
||||
for executed_param in self.get_executed_params())
|
||||
for executed_param in executed_params)
|
||||
if debug.enable_notice:
|
||||
signature = parser_utils.get_call_signature(self.tree_node)
|
||||
if matches:
|
||||
|
||||
@@ -32,11 +32,11 @@ class AnonymousInstanceArguments(AnonymousArguments):
|
||||
def __init__(self, instance):
|
||||
self._instance = instance
|
||||
|
||||
def get_executed_params(self, execution_context):
|
||||
def get_executed_params_and_issues(self, execution_context):
|
||||
from jedi.evaluate.dynamic import search_params
|
||||
tree_params = execution_context.tree_node.get_params()
|
||||
if not tree_params:
|
||||
return []
|
||||
return [], []
|
||||
|
||||
self_param = InstanceExecutedParam(self._instance, tree_params[0])
|
||||
if len(tree_params) == 1:
|
||||
@@ -49,7 +49,7 @@ class AnonymousInstanceArguments(AnonymousArguments):
|
||||
execution_context.tree_node
|
||||
))
|
||||
executed_params[0] = self_param
|
||||
return executed_params
|
||||
return [], executed_params
|
||||
|
||||
|
||||
class AbstractInstanceContext(Context):
|
||||
@@ -273,7 +273,6 @@ class TreeInstance(AbstractInstanceContext):
|
||||
if not execution.matches_signature():
|
||||
# First check if the signature even matches, if not we don't
|
||||
# need to infer anything.
|
||||
print('no m', bound)
|
||||
continue
|
||||
print(bound)
|
||||
context_set = define_type_vars_for_execution(
|
||||
@@ -541,11 +540,11 @@ class InstanceArguments(AbstractArguments):
|
||||
def get_calling_nodes(self):
|
||||
return self._arguments.get_calling_nodes()
|
||||
|
||||
def get_executed_params(self, execution_context):
|
||||
def get_executed_params_and_issues(self, execution_context):
|
||||
if isinstance(self._arguments, AnonymousInstanceArguments):
|
||||
return self._arguments.get_executed_params(execution_context)
|
||||
return self._arguments.get_executed_params_and_issues(execution_context)
|
||||
|
||||
return super(InstanceArguments, self).get_executed_params(execution_context)
|
||||
return super(InstanceArguments, self).get_executed_params_and_issues(execution_context)
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s: %s>' % (self.__class__.__name__, self._arguments)
|
||||
|
||||
@@ -99,7 +99,7 @@ def search_params(evaluator, execution_context, funcdef):
|
||||
)
|
||||
if function_executions:
|
||||
zipped_params = zip(*list(
|
||||
function_execution.get_executed_params()
|
||||
function_execution.get_executed_params_and_issues()[0]
|
||||
for function_execution in function_executions
|
||||
))
|
||||
params = [DynamicExecutedParams(evaluator, executed_params) for executed_params in zipped_params]
|
||||
@@ -208,7 +208,7 @@ def _check_name_for_execution(evaluator, context, compare_node, name, trailer):
|
||||
# Here we're trying to find decorators by checking the first
|
||||
# parameter. It's not very generic though. Should find a better
|
||||
# solution that also applies to nested decorators.
|
||||
params = value.parent_context.get_executed_params()
|
||||
params, _ = value.parent_context.get_executed_params_and_issues()
|
||||
if len(params) != 1:
|
||||
continue
|
||||
values = params[0].infer()
|
||||
|
||||
@@ -136,7 +136,7 @@ class ParamName(AbstractTreeName):
|
||||
return self.get_param().infer()
|
||||
|
||||
def get_param(self):
|
||||
params = self.parent_context.get_executed_params()
|
||||
params, _ = self.parent_context.get_executed_params_and_issues()
|
||||
param_node = search_ancestor(self.tree_name, 'param')
|
||||
return params[param_node.position_index]
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ def _add_argument_issue(parent_context, error_name, lazy_context, message):
|
||||
node = lazy_context.data
|
||||
if node.parent.type == 'argument':
|
||||
node = node.parent
|
||||
analysis.add(parent_context, error_name, node, message)
|
||||
return analysis.add(parent_context, error_name, node, message)
|
||||
|
||||
|
||||
class ExecutedParam(object):
|
||||
@@ -58,7 +58,25 @@ class ExecutedParam(object):
|
||||
return '<%s: %s>' % (self.__class__.__name__, self.string_name)
|
||||
|
||||
|
||||
def get_executed_params(execution_context, var_args):
|
||||
def get_executed_params_and_issues(execution_context, var_args):
|
||||
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
|
||||
# cPython).
|
||||
if var_args.get_calling_nodes():
|
||||
# There might not be a valid calling node so check for that first.
|
||||
issues.append(
|
||||
_add_argument_issue(
|
||||
default_param_context,
|
||||
'type-error-too-many-arguments',
|
||||
lazy_context,
|
||||
message=m
|
||||
)
|
||||
)
|
||||
else:
|
||||
issues.append(None)
|
||||
|
||||
issues = [] # List[Optional[analysis issue]]
|
||||
result_params = []
|
||||
param_dict = {}
|
||||
funcdef = execution_context.tree_node
|
||||
@@ -94,8 +112,10 @@ def get_executed_params(execution_context, var_args):
|
||||
m = ("TypeError: %s() got multiple values for keyword argument '%s'."
|
||||
% (funcdef.name, key))
|
||||
for node in var_args.get_calling_nodes():
|
||||
analysis.add(default_param_context, 'type-error-multiple-values',
|
||||
node, message=m)
|
||||
issues.append(
|
||||
analysis.add(default_param_context, 'type-error-multiple-values',
|
||||
node, message=m)
|
||||
)
|
||||
else:
|
||||
keys_used[key] = ExecutedParam(execution_context, key_param, argument)
|
||||
key, argument = next(var_arg_iterator, (None, None))
|
||||
@@ -120,6 +140,8 @@ def get_executed_params(execution_context, var_args):
|
||||
seq = iterable.FakeSequence(execution_context.evaluator, u'tuple', lazy_context_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.evaluator, dict(non_matching_keys))
|
||||
result_arg = LazyKnownContext(dct)
|
||||
@@ -133,8 +155,14 @@ def get_executed_params(execution_context, var_args):
|
||||
if not keys_only:
|
||||
for node in var_args.get_calling_nodes():
|
||||
m = _error_argument_count(funcdef, len(unpacked_va))
|
||||
analysis.add(default_param_context, 'type-error-too-few-arguments',
|
||||
node, message=m)
|
||||
issues.append(
|
||||
analysis.add(
|
||||
default_param_context,
|
||||
'type-error-too-few-arguments',
|
||||
node,
|
||||
message=m,
|
||||
)
|
||||
)
|
||||
else:
|
||||
result_arg = LazyTreeContext(default_param_context, param.default)
|
||||
else:
|
||||
@@ -156,34 +184,28 @@ def get_executed_params(execution_context, var_args):
|
||||
# add a warning only if there's not another one.
|
||||
for node in var_args.get_calling_nodes():
|
||||
m = _error_argument_count(funcdef, len(unpacked_va))
|
||||
analysis.add(default_param_context, 'type-error-too-few-arguments',
|
||||
node, message=m)
|
||||
issues.append(
|
||||
analysis.add(default_param_context, 'type-error-too-few-arguments',
|
||||
node, message=m)
|
||||
)
|
||||
|
||||
for key, lazy_context in non_matching_keys.items():
|
||||
m = "TypeError: %s() got an unexpected keyword argument '%s'." \
|
||||
% (funcdef.name, key)
|
||||
_add_argument_issue(
|
||||
default_param_context,
|
||||
'type-error-keyword-argument',
|
||||
lazy_context,
|
||||
message=m
|
||||
issues.append(
|
||||
_add_argument_issue(
|
||||
default_param_context,
|
||||
'type-error-keyword-argument',
|
||||
lazy_context,
|
||||
message=m
|
||||
)
|
||||
)
|
||||
|
||||
remaining_arguments = list(var_arg_iterator)
|
||||
if remaining_arguments:
|
||||
m = _error_argument_count(funcdef, len(unpacked_va))
|
||||
# Just report an error for the first param that is not needed (like
|
||||
# cPython).
|
||||
first_key, lazy_context = remaining_arguments[0]
|
||||
if var_args.get_calling_nodes():
|
||||
# There might not be a valid calling node so check for that first.
|
||||
_add_argument_issue(
|
||||
default_param_context,
|
||||
'type-error-too-many-arguments',
|
||||
lazy_context,
|
||||
message=m
|
||||
)
|
||||
return result_params
|
||||
too_many_args(lazy_context)
|
||||
return result_params, issues
|
||||
|
||||
|
||||
def _error_argument_count(funcdef, actual_count):
|
||||
|
||||
@@ -250,7 +250,8 @@ def _infer_type_vars_for_execution(execution_context, annotation_dict):
|
||||
context = execution_context.function_context.get_default_param_context()
|
||||
|
||||
annotation_variable_results = {}
|
||||
for executed_param in execution_context.get_executed_params():
|
||||
executed_params, _ = execution_context.get_executed_params_and_issues()
|
||||
for executed_param in executed_params:
|
||||
try:
|
||||
annotation_node = annotation_dict[executed_param.string_name]
|
||||
except KeyError:
|
||||
|
||||
Reference in New Issue
Block a user