1
0
forked from VimPlug/jedi

param default values.

This commit is contained in:
Dave Halter
2014-10-27 12:03:09 +01:00
parent db2d380441
commit 14ec210891
2 changed files with 43 additions and 54 deletions

View File

@@ -12,25 +12,25 @@ from jedi.evaluate import analysis
from jedi.evaluate import precedence from jedi.evaluate import precedence
class Arguments(object): class Arguments(pr.Base):
def __init__(self, evaluator, argument_node): def __init__(self, evaluator, argument_node):
""" """
The argument_node is either a parser node or a list of evaluated The argument_node is either a parser node or a list of evaluated
objects. objects.
""" """
self._argument_node = argument_node self.argument_node = argument_node
self._evaluator = evaluator self._evaluator = evaluator
def _split(self): def _split(self):
if isinstance(self._argument_node, (tuple, list)): if isinstance(self.argument_node, (tuple, list)):
for el in self._argument_node: for el in self.argument_node:
yield 0, el yield 0, el
else: else:
if not pr.is_node(self._argument_node, 'arglist'): if not pr.is_node(self.argument_node, 'arglist'):
yield 0, self._argument_node yield 0, self.argument_node
return return
iterator = iter(self._argument_node.children) iterator = iter(self.argument_node.children)
for child in iterator: for child in iterator:
if child == ',': if child == ',':
continue continue
@@ -39,6 +39,14 @@ class Arguments(object):
else: else:
yield 0, child yield 0, child
def as_tuple(self):
for stars, argument in self._split():
if pr.is_node(argument, 'argument'):
argument, default = argument.children[::2]
else:
default = None
yield argument, default, stars
def unpack(self): def unpack(self):
named_args = [] named_args = []
for stars, el in self._split(): for stars, el in self._split():
@@ -86,17 +94,11 @@ class Arguments(object):
new_args.append(stmt) new_args.append(stmt)
return new_args return new_args
def kwargs(self):
return []
def args(self):
return []
def eval_args(self): def eval_args(self):
return [self._evaluator.eval_element(el) for stars, el in self._split()] return [self._evaluator.eval_element(el) for stars, el in self._split()]
def __repr__(self): def __repr__(self):
return '<%s: %s>' % (type(self).__name__, self._argument_node) return '<%s: %s>' % (type(self).__name__, self.argument_node)
class ExecutedParam(pr.Param): class ExecutedParam(pr.Param):
@@ -132,26 +134,15 @@ class ExecutedParam(pr.Param):
return types return types
class Container(object):
def __init__(self, values):
self.values = values
def eval(self, evaluator):
return self.values
def _get_calling_var_args(evaluator, var_args): def _get_calling_var_args(evaluator, var_args):
old_var_args = None old_var_args = None
while var_args != old_var_args: while var_args != old_var_args:
old_var_args = var_args old_var_args = var_args
for argument in reversed(var_args): for argument, default, stars in reversed(list(var_args.as_tuple())):
if not isinstance(argument, pr.Statement): if not stars or not isinstance(argument, pr.Name):
continue
exp_list = argument.expression_list()
if len(exp_list) != 2 or exp_list[0] not in ('*', '**'):
continue continue
names = evaluator.goto(argument, [exp_list[1].get_code()]) names = evaluator.goto(argument, [argument.value])
if len(names) != 1: if len(names) != 1:
break break
param = names[0].get_definition() param = names[0].get_definition()
@@ -187,8 +178,8 @@ def get_params(evaluator, func, var_args):
# args / kwargs will just be empty arrays / dicts, respectively. # args / kwargs will just be empty arrays / dicts, respectively.
# Wrong value count is just ignored. If you try to test cases that are # Wrong value count is just ignored. If you try to test cases that are
# not allowed in Python, Jedi will maybe not show any completions. # not allowed in Python, Jedi will maybe not show any completions.
key, va_values = next(var_arg_iterator, (None, ())) key, va_values = next(var_arg_iterator, (None, [param.default]))
while key: while key is not None:
keys_only = True keys_only = True
k = unicode(key) k = unicode(key)
try: try:
@@ -197,7 +188,7 @@ def get_params(evaluator, func, var_args):
non_matching_keys[key] += va_values non_matching_keys[key] += va_values
else: else:
result.append(_gen_param_name_copy(evaluator, func, var_args, result.append(_gen_param_name_copy(evaluator, func, var_args,
key_param, values=[va_values])) key_param, values=va_values))
if k in keys_used: if k in keys_used:
had_multiple_value_error = True had_multiple_value_error = True
@@ -206,15 +197,17 @@ def get_params(evaluator, func, var_args):
calling_va = _get_calling_var_args(evaluator, var_args) calling_va = _get_calling_var_args(evaluator, var_args)
if calling_va is not None: if calling_va is not None:
analysis.add(evaluator, 'type-error-multiple-values', analysis.add(evaluator, 'type-error-multiple-values',
calling_va, message=m) calling_va.argument_node, message=m)
else: else:
keys_used.add(k) keys_used.add(k)
key, va_values = next(var_arg_iterator, (None, ())) key, va_values = next(var_arg_iterator, (None, ()))
if keys_only:
break
keys = [] keys = []
values = [] values = []
array_type = None array_type = None
has_default_value = False
if param.stars == 1: if param.stars == 1:
# *args param # *args param
array_type = pr.Array.TUPLE array_type = pr.Array.TUPLE
@@ -236,24 +229,20 @@ def get_params(evaluator, func, var_args):
non_matching_keys = {} non_matching_keys = {}
else: else:
# normal param # normal param
if va_values is not None: if va_values:
values = va_values values = va_values
else: else:
if param.default is not None: # No value: Return an empty container
# No value: Return the default values. values = []
values = [param.default] if not keys_only and isinstance(var_args, pr.Array):
else: calling_va = _get_calling_var_args(evaluator, var_args)
# No value: Return an empty container if calling_va is not None:
values = [] m = _error_argument_count(func, len(unpacked_va))
if not keys_only and isinstance(var_args, pr.Array): analysis.add(evaluator, 'type-error-too-few-arguments',
calling_va = _get_calling_var_args(evaluator, var_args) calling_va, message=m)
if calling_va is not None:
m = _error_argument_count(func, len(unpacked_va))
analysis.add(evaluator, 'type-error-too-few-arguments',
calling_va, message=m)
# Now add to result if it's not one of the previously covered cases. # Now add to result if it's not one of the previously covered cases.
if not has_default_value and (not keys_only or param.stars == 2): if (not keys_only or param.stars == 2):
keys_used.add(unicode(param.get_name())) keys_used.add(unicode(param.get_name()))
result.append(_gen_param_name_copy(evaluator, func, var_args, param, result.append(_gen_param_name_copy(evaluator, func, var_args, param,
keys=keys, values=values, keys=keys, values=values,
@@ -267,16 +256,16 @@ def get_params(evaluator, func, var_args):
param = param_dict[k] param = param_dict[k]
values = [] if param.default is None else [param.default] values = [] if param.default is None else [param.default]
result.append(_gen_param_name_copy(evaluator, func, var_args, result.append(_gen_param_name_copy(evaluator, func, var_args,
param, values)) param, [], values))
if not (non_matching_keys or had_multiple_value_error if not (non_matching_keys or had_multiple_value_error
or param.stars or param.default): or param.stars or param.default):
# add a warning only if there's not another one. # add a warning only if there's not another one.
calling_va = _get_calling_var_args(evaluator, var_args) calling_va = _get_calling_var_args(evaluator, var_args)
if calling_va is not None: if calling_va.argument_node is not None:
m = _error_argument_count(func, len(unpacked_va)) m = _error_argument_count(func, len(unpacked_va))
analysis.add(evaluator, 'type-error-too-few-arguments', analysis.add(evaluator, 'type-error-too-few-arguments',
calling_va, message=m) calling_va.argument_node, message=m)
for key, va_values in non_matching_keys.items(): for key, va_values in non_matching_keys.items():
m = "TypeError: %s() got an unexpected keyword argument '%s'." \ m = "TypeError: %s() got an unexpected keyword argument '%s'." \
@@ -397,7 +386,9 @@ def _star_star_dict(evaluator, array, expression_list, func):
# make one call without crazy isinstance checks. # make one call without crazy isinstance checks.
return {} return {}
if isinstance(array, iterable.Array) and array.type == pr.Array.DICT: if isinstance(array, iterable.FakeDict):
return array._dct
elif isinstance(array, iterable.Array) and array.type == pr.Array.DICT:
for key_node, values in array._items(): for key_node, values in array._items():
for key in evaluator.eval_element(key_node): for key in evaluator.eval_element(key_node):
if precedence.is_string(key): if precedence.is_string(key):

View File

@@ -365,13 +365,11 @@ nested_kw(b=1)
#? int() #? int()
nested_kw(d=1.0, b=1, list) nested_kw(d=1.0, b=1, list)
#? int() #? int()
nested_kw(b=1)
#? int()
nested_kw(a=3.0, b=1) nested_kw(a=3.0, b=1)
#? int() #? int()
nested_kw(b=1, a=r"") nested_kw(b=1, a=r"")
#? [] #? []
nested_kw('') nested_kw(1, '')
#? [] #? []
nested_kw(a='') nested_kw(a='')