builtin property: accept keyword arguments
this allows python code to use property(lambda:..., doc=...) idiom. named versions for the fget, fset and fdel arguments are left out in the interest of saving space; they are rarely used and easy to enable when actually needed. a test case is included.
This commit is contained in:
parent
dea585f8ae
commit
f8ba2eca80
|
@ -38,28 +38,22 @@ typedef struct _mp_obj_property_t {
|
||||||
} mp_obj_property_t;
|
} mp_obj_property_t;
|
||||||
|
|
||||||
STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
mp_arg_check_num(n_args, n_kw, 0, 4, false);
|
enum { ARG_fget, ARG_fset, ARG_fdel, ARG_doc };
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} },
|
||||||
|
{ MP_QSTR_, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} },
|
||||||
|
{ MP_QSTR_, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} },
|
||||||
|
{ MP_QSTR_doc, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} },
|
||||||
|
};
|
||||||
|
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
|
||||||
|
|
||||||
mp_obj_property_t *o = m_new_obj(mp_obj_property_t);
|
mp_obj_property_t *o = m_new_obj(mp_obj_property_t);
|
||||||
o->base.type = type;
|
o->base.type = type;
|
||||||
if (n_args >= 4) {
|
o->proxy[0] = vals[ARG_fget].u_obj;
|
||||||
// doc ignored
|
o->proxy[1] = vals[ARG_fset].u_obj;
|
||||||
}
|
o->proxy[2] = vals[ARG_fdel].u_obj;
|
||||||
if (n_args >= 3) {
|
// vals[ARG_doc] is silently discarded
|
||||||
o->proxy[2] = args[2];
|
|
||||||
} else {
|
|
||||||
o->proxy[2] = mp_const_none;
|
|
||||||
}
|
|
||||||
if (n_args >= 2) {
|
|
||||||
o->proxy[1] = args[1];
|
|
||||||
} else {
|
|
||||||
o->proxy[1] = mp_const_none;
|
|
||||||
}
|
|
||||||
if (n_args >= 1) {
|
|
||||||
o->proxy[0] = args[0];
|
|
||||||
} else {
|
|
||||||
o->proxy[0] = mp_const_none;
|
|
||||||
}
|
|
||||||
return MP_OBJ_FROM_PTR(o);
|
return MP_OBJ_FROM_PTR(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -570,6 +570,7 @@ Q(property)
|
||||||
Q(getter)
|
Q(getter)
|
||||||
Q(setter)
|
Q(setter)
|
||||||
Q(deleter)
|
Q(deleter)
|
||||||
|
Q(doc)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MICROPY_PY_UZLIB
|
#if MICROPY_PY_UZLIB
|
||||||
|
|
|
@ -93,3 +93,10 @@ try:
|
||||||
del d.prop
|
del d.prop
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
print('AttributeError')
|
print('AttributeError')
|
||||||
|
|
||||||
|
# properties take keyword arguments
|
||||||
|
class E:
|
||||||
|
p = property(lambda self: 42, doc="This is truth.")
|
||||||
|
# not tested for because the other keyword arguments are not accepted
|
||||||
|
# q = property(fget=lambda self: 21, doc="Half the truth.")
|
||||||
|
print(E().p)
|
||||||
|
|
Loading…
Reference in New Issue