diff --git a/jedi/evaluate/analysis.py b/jedi/evaluate/analysis.py index a7c4c441..8273df3e 100644 --- a/jedi/evaluate/analysis.py +++ b/jedi/evaluate/analysis.py @@ -15,6 +15,7 @@ CODES = { 'type-error-too-many-arguments': (5, TypeError, None), 'type-error-too-few-arguments': (6, TypeError, None), 'type-error-keyword-argument': (7, TypeError, None), + 'type-error-multiple-values': (8, TypeError, None), } diff --git a/jedi/evaluate/param.py b/jedi/evaluate/param.py index d12c611e..172a571e 100644 --- a/jedi/evaluate/param.py +++ b/jedi/evaluate/param.py @@ -1,5 +1,6 @@ import copy +from jedi._compatibility import unicode from jedi.parser import representation as pr from jedi.evaluate import iterable from jedi import common @@ -37,13 +38,21 @@ def get_params(evaluator, func, var_args): while key: keys_only = True try: - key_param = param_dict[str(key)] + key_param = param_dict[unicode(key)] except KeyError: non_matching_keys.append((key, value)) else: - keys_used.add(str(key)) - result.append(_gen_param_name_copy(func, var_args, key_param, - values=[value])) + k = unicode(key) + if k in keys_used: + print(keys_used, unicode(key), value) + m = ("TypeError: %s() got multiple values for keyword argument '%s'." + % (func.name, k)) + analysis.add(evaluator, 'type-error-multiple-values', + var_args, message=m) + else: + keys_used.add(k) + result.append(_gen_param_name_copy(func, var_args, key_param, + values=[value])) key, value = next(var_arg_iterator, (None, None)) keys = [] @@ -93,7 +102,7 @@ def get_params(evaluator, func, var_args): # 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): - keys_used.add(str(key)) + keys_used.add(unicode(param.get_name())) result.append(_gen_param_name_copy(func, var_args, param, keys=keys, values=values, array_type=array_type)) diff --git a/test/static_analysis/arguments.py b/test/static_analysis/arguments.py index 07d3f766..bec40ee5 100644 --- a/test/static_analysis/arguments.py +++ b/test/static_analysis/arguments.py @@ -14,7 +14,7 @@ simple(1, 2) def nested(*args): - # TODO: shoult not be her but in line 17 + # TODO: should not be here, but in line 17 #! 13 type-error-too-few-arguments return simple(*args) @@ -41,9 +41,7 @@ def two_params(x, y): two_params(y=2, x=1) two_params(1, y=2) -# The next two statements should generate errors. Basically it should generate -# something like `TypeError: x() got multiple values for keyword argument 'a'`. -# For now however, any error should be fine. +#! 10 type-error-multiple-values two_params(1, x=2) #! 17 type-error-too-many-arguments two_params(1, 2, y=3) diff --git a/test/test_integration.py b/test/test_integration.py index 78a1af43..237e823e 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -26,8 +26,8 @@ def assert_static_analysis(case, actual, desired): d = set(desired) assert actual == desired, """ Test %r failed. -too much = %s -missing = %s +specified, not raised = %s +missing = %s """ % (case, sorted(d - a), sorted(a - d))