kopia lustrzana https://github.com/micropython/micropython
Merge 49cec95fdd
into 01c31ea804
commit
a015ea81d7
11
py/compile.c
11
py/compile.c
|
@ -2425,8 +2425,17 @@ static void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar
|
||||||
}
|
}
|
||||||
star_flags |= MP_EMIT_STAR_FLAG_SINGLE;
|
star_flags |= MP_EMIT_STAR_FLAG_SINGLE;
|
||||||
star_args |= (mp_uint_t)1 << i;
|
star_args |= (mp_uint_t)1 << i;
|
||||||
|
|
||||||
|
if (n_keyword == 0) {
|
||||||
|
// star-args before kwargs encoded as positional arg
|
||||||
|
n_positional++;
|
||||||
|
} else {
|
||||||
|
// star-args after kwargs encoded as kw arg with key=NULL
|
||||||
|
EMIT(load_null);
|
||||||
|
n_keyword++;
|
||||||
|
}
|
||||||
|
|
||||||
compile_node(comp, pns_arg->nodes[0]);
|
compile_node(comp, pns_arg->nodes[0]);
|
||||||
n_positional++;
|
|
||||||
} else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_dbl_star) {
|
} else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_dbl_star) {
|
||||||
star_flags |= MP_EMIT_STAR_FLAG_DOUBLE;
|
star_flags |= MP_EMIT_STAR_FLAG_DOUBLE;
|
||||||
// double-star args are stored as kw arg with key of None
|
// double-star args are stored as kw arg with key of None
|
||||||
|
|
52
py/runtime.c
52
py/runtime.c
|
@ -757,17 +757,30 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||||
mp_obj_t *args2;
|
mp_obj_t *args2;
|
||||||
size_t args2_alloc;
|
size_t args2_alloc;
|
||||||
size_t args2_len = 0;
|
size_t args2_len = 0;
|
||||||
|
size_t n_args_star_args = n_args;
|
||||||
|
|
||||||
// Try to get a hint for unpacked * args length
|
// Try to get a hint for unpacked * args length
|
||||||
ssize_t list_len = 0;
|
ssize_t list_len = 0;
|
||||||
|
|
||||||
if (star_args != 0) {
|
if (star_args) {
|
||||||
for (size_t i = 0; i < n_args; i++) {
|
// kw can also contain star args.
|
||||||
if ((star_args >> i) & 1) {
|
n_args_star_args += n_kw;
|
||||||
mp_obj_t len = mp_obj_len_maybe(args[i]);
|
|
||||||
if (len != MP_OBJ_NULL) {
|
for (size_t i = 0; i < n_args_star_args; i++) {
|
||||||
|
if (!((star_args >> i) & 1)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t arg = i >= n_args ? args[n_args + 2 * (i - n_args) + 1] : args[i];
|
||||||
|
|
||||||
|
mp_obj_t len = mp_obj_len_maybe(arg);
|
||||||
|
|
||||||
|
if (len != MP_OBJ_NULL) {
|
||||||
|
list_len += mp_obj_get_int(len);
|
||||||
|
|
||||||
|
if (i < n_args) {
|
||||||
// -1 accounts for 1 of n_args occupied by this arg
|
// -1 accounts for 1 of n_args occupied by this arg
|
||||||
list_len += mp_obj_get_int(len) - 1;
|
list_len--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -779,9 +792,20 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||||
for (size_t i = 0; i < n_kw; i++) {
|
for (size_t i = 0; i < n_kw; i++) {
|
||||||
mp_obj_t key = args[n_args + i * 2];
|
mp_obj_t key = args[n_args + i * 2];
|
||||||
mp_obj_t value = args[n_args + i * 2 + 1];
|
mp_obj_t value = args[n_args + i * 2 + 1];
|
||||||
if (key == MP_OBJ_NULL && value != MP_OBJ_NULL && mp_obj_is_type(value, &mp_type_dict)) {
|
|
||||||
|
if (key == MP_OBJ_NULL) {
|
||||||
// -1 accounts for 1 of n_kw occupied by this arg
|
// -1 accounts for 1 of n_kw occupied by this arg
|
||||||
kw_dict_len += mp_obj_dict_len(value) - 1;
|
kw_dict_len--;
|
||||||
|
|
||||||
|
if (((star_args >> (n_args + i)) & 1)) {
|
||||||
|
// star args were already handled above
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// double-star args
|
||||||
|
if (mp_obj_is_type(value, &mp_type_dict)) {
|
||||||
|
kw_dict_len += mp_obj_dict_len(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,8 +838,9 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||||
args2[args2_len++] = self;
|
args2[args2_len++] = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < n_args; i++) {
|
for (size_t i = 0; i < n_args_star_args; i++) {
|
||||||
mp_obj_t arg = args[i];
|
mp_obj_t arg = i >= n_args ? args[n_args + 2 * (i - n_args) + 1] : args[i];
|
||||||
|
|
||||||
if ((star_args >> i) & 1) {
|
if ((star_args >> i) & 1) {
|
||||||
// star arg
|
// star arg
|
||||||
if (mp_obj_is_type(arg, &mp_type_tuple) || mp_obj_is_type(arg, &mp_type_list)) {
|
if (mp_obj_is_type(arg, &mp_type_tuple) || mp_obj_is_type(arg, &mp_type_list)) {
|
||||||
|
@ -846,7 +871,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||||
args2[args2_len++] = item;
|
args2[args2_len++] = item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if (i < n_args) {
|
||||||
// normal argument
|
// normal argument
|
||||||
assert(args2_len < args2_alloc);
|
assert(args2_len < args2_alloc);
|
||||||
args2[args2_len++] = arg;
|
args2[args2_len++] = arg;
|
||||||
|
@ -870,6 +895,11 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
||||||
mp_obj_t kw_key = args[n_args + i * 2];
|
mp_obj_t kw_key = args[n_args + i * 2];
|
||||||
mp_obj_t kw_value = args[n_args + i * 2 + 1];
|
mp_obj_t kw_value = args[n_args + i * 2 + 1];
|
||||||
if (kw_key == MP_OBJ_NULL) {
|
if (kw_key == MP_OBJ_NULL) {
|
||||||
|
if ((star_args >> (n_args + i)) & 1) {
|
||||||
|
// star args have already been handled above
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// double-star args
|
// double-star args
|
||||||
if (mp_obj_is_type(kw_value, &mp_type_dict)) {
|
if (mp_obj_is_type(kw_value, &mp_type_dict)) {
|
||||||
// dictionary
|
// dictionary
|
||||||
|
|
|
@ -23,6 +23,10 @@ foo(*range(3))
|
||||||
# pos then iterator
|
# pos then iterator
|
||||||
foo(1, *range(2, 4))
|
foo(1, *range(2, 4))
|
||||||
|
|
||||||
|
# star after kw
|
||||||
|
foo(1, 2, c=3, *())
|
||||||
|
foo(b=2, *(1,), c=3)
|
||||||
|
|
||||||
# an iterator with many elements
|
# an iterator with many elements
|
||||||
def foo(*rest):
|
def foo(*rest):
|
||||||
print(rest)
|
print(rest)
|
||||||
|
|
Ładowanie…
Reference in New Issue