py/bc: Fix checking for duplicate **kwargs.
The code was already checking for duplicate kwargs for named parameters but if `**kwargs` was given as a parameter, it did not check for multiples of the same argument name. This fixes the issue by adding an addition test to catch duplicates and adds a test to exercise the code. Fixes issue #10083. Signed-off-by: David Lechner <david@pybricks.com>
This commit is contained in:
parent
cc26bf7406
commit
d5181034f2
8
py/bc.c
8
py/bc.c
@ -213,6 +213,7 @@ STATIC void mp_setup_code_state_helper(mp_code_state_t *code_state, size_t n_arg
|
||||
#endif
|
||||
if (wanted_arg_name == MP_OBJ_NEW_QSTR(arg_qstr)) {
|
||||
if (code_state_state[n_state - 1 - j] != MP_OBJ_NULL) {
|
||||
error_multiple:
|
||||
mp_raise_msg_varg(&mp_type_TypeError,
|
||||
MP_ERROR_TEXT("function got multiple values for argument '%q'"), MP_OBJ_QSTR_VALUE(wanted_arg_name));
|
||||
}
|
||||
@ -229,7 +230,12 @@ STATIC void mp_setup_code_state_helper(mp_code_state_t *code_state, size_t n_arg
|
||||
MP_ERROR_TEXT("unexpected keyword argument '%q'"), MP_OBJ_QSTR_VALUE(wanted_arg_name));
|
||||
#endif
|
||||
}
|
||||
mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]);
|
||||
mp_map_elem_t *elem = mp_map_lookup(mp_obj_dict_get_map(dict), wanted_arg_name, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
|
||||
if (elem->value == MP_OBJ_NULL) {
|
||||
elem->value = kwargs[2 * i + 1];
|
||||
} else {
|
||||
goto error_multiple;
|
||||
}
|
||||
continue2:;
|
||||
}
|
||||
|
||||
|
@ -20,3 +20,13 @@ class A:
|
||||
a = A()
|
||||
a.f(1, **{'b':2})
|
||||
a.f(1, **{'b':val for val in range(1)})
|
||||
|
||||
# test for duplicate keys in **kwargs not allowed
|
||||
|
||||
def f1(**kwargs):
|
||||
print(kwargs)
|
||||
|
||||
try:
|
||||
f1(**{'a': 1, 'b': 2}, **{'b': 3, 'c': 4})
|
||||
except TypeError:
|
||||
print('TypeError')
|
||||
|
Loading…
Reference in New Issue
Block a user