py: Allow keyword arguments for namedtuple
This commit is contained in:
parent
12340147b0
commit
021dc44009
@ -89,9 +89,39 @@ STATIC mp_obj_t namedtuple_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_
|
||||
// Counts include implicit "self"
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"__new__() takes %d positional arguments but %d were given",
|
||||
num_fields + 1, n_args + 1));
|
||||
num_fields + 1, n_args + n_kw + 1));
|
||||
}
|
||||
mp_obj_tuple_t *tuple = mp_obj_new_tuple(n_args, args);
|
||||
|
||||
mp_obj_t *arg_objects;
|
||||
if (n_args == num_fields) {
|
||||
arg_objects = (mp_obj_t*)args;
|
||||
} else {
|
||||
size_t alloc_size = sizeof(mp_obj_t) * num_fields;
|
||||
arg_objects = alloca(alloc_size);
|
||||
memset(arg_objects, 0, alloc_size);
|
||||
|
||||
for (mp_uint_t i = 0; i < n_args; i++) {
|
||||
arg_objects[i] = args[i];
|
||||
}
|
||||
|
||||
for (mp_uint_t i = n_args; i < n_args + 2 * n_kw; i += 2) {
|
||||
qstr kw = MP_OBJ_QSTR_VALUE(args[i]);
|
||||
int id = namedtuple_find_field(type, kw);
|
||||
if (id == -1) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"__new__() got an unexpected keyword argument '%s'",
|
||||
qstr_str(kw)));
|
||||
}
|
||||
if (arg_objects[id] != NULL) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
|
||||
"__new__() got multiple values for argument '%s'",
|
||||
qstr_str(kw)));
|
||||
}
|
||||
arg_objects[id] = args[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_tuple_t *tuple = mp_obj_new_tuple(num_fields, arg_objects);
|
||||
tuple->base.type = type_in;
|
||||
return tuple;
|
||||
}
|
||||
|
@ -6,19 +6,19 @@ except ImportError:
|
||||
T = namedtuple("Tup", ["foo", "bar"])
|
||||
# CPython prints fully qualified name, what we don't bother to do so far
|
||||
#print(T)
|
||||
t = T(1, 2)
|
||||
print(t)
|
||||
print(t[0], t[1])
|
||||
print(t.foo, t.bar)
|
||||
for t in T(1, 2), T(bar=1, foo=2):
|
||||
print(t)
|
||||
print(t[0], t[1])
|
||||
print(t.foo, t.bar)
|
||||
|
||||
print(len(t))
|
||||
print(bool(t))
|
||||
print(t + t)
|
||||
print(t * 3)
|
||||
print(len(t))
|
||||
print(bool(t))
|
||||
print(t + t)
|
||||
print(t * 3)
|
||||
|
||||
print([f for f in t])
|
||||
print([f for f in t])
|
||||
|
||||
print(isinstance(t, tuple))
|
||||
print(isinstance(t, tuple))
|
||||
|
||||
try:
|
||||
t[0] = 200
|
||||
@ -39,6 +39,16 @@ try:
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
try:
|
||||
t = T(foo=1)
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
try:
|
||||
t = T(1, foo=1)
|
||||
except TypeError:
|
||||
print("TypeError")
|
||||
|
||||
# Try single string
|
||||
# Not implemented so far
|
||||
#T3 = namedtuple("TupComma", "foo bar")
|
||||
|
Loading…
Reference in New Issue
Block a user