py: Support 3-arg getattr() builtin (with default value).
This commit is contained in:
parent
438d504e27
commit
bfb7d6a26d
12
py/builtin.c
12
py/builtin.c
|
@ -400,9 +400,13 @@ STATIC mp_obj_t mp_builtin_id(mp_obj_t o_in) {
|
|||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_id_obj, mp_builtin_id);
|
||||
|
||||
STATIC mp_obj_t mp_builtin_getattr(mp_obj_t o_in, mp_obj_t attr) {
|
||||
assert(MP_OBJ_IS_QSTR(attr));
|
||||
return mp_load_attr(o_in, MP_OBJ_QSTR_VALUE(attr));
|
||||
STATIC mp_obj_t mp_builtin_getattr(uint n_args, const mp_obj_t *args) {
|
||||
assert(MP_OBJ_IS_QSTR(args[1]));
|
||||
mp_obj_t defval = MP_OBJ_NULL;
|
||||
if (n_args > 2) {
|
||||
defval = args[2];
|
||||
}
|
||||
return mp_load_attr_default(args[0], MP_OBJ_QSTR_VALUE(args[1]), defval);
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_getattr_obj, mp_builtin_getattr);
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_getattr_obj, 2, 3, mp_builtin_getattr);
|
||||
|
|
14
py/runtime.c
14
py/runtime.c
|
@ -689,12 +689,14 @@ too_long:
|
|||
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "too many values to unpack (expected %d)", num));
|
||||
}
|
||||
|
||||
mp_obj_t mp_load_attr(mp_obj_t base, qstr attr) {
|
||||
mp_obj_t mp_load_attr_default(mp_obj_t base, qstr attr, mp_obj_t defval) {
|
||||
DEBUG_OP_printf("load attr %p.%s\n", base, qstr_str(attr));
|
||||
// use load_method
|
||||
mp_obj_t dest[2];
|
||||
mp_load_method(base, attr, dest);
|
||||
if (dest[1] == MP_OBJ_NULL) {
|
||||
// use load_method, raising or not raising exception
|
||||
((defval == MP_OBJ_NULL) ? mp_load_method : mp_load_method_maybe)(base, attr, dest);
|
||||
if (dest[0] == MP_OBJ_NULL) {
|
||||
return defval;
|
||||
} else if (dest[1] == MP_OBJ_NULL) {
|
||||
// load_method returned just a normal attribute
|
||||
return dest[0];
|
||||
} else {
|
||||
|
@ -703,6 +705,10 @@ mp_obj_t mp_load_attr(mp_obj_t base, qstr attr) {
|
|||
}
|
||||
}
|
||||
|
||||
mp_obj_t mp_load_attr(mp_obj_t base, qstr attr) {
|
||||
return mp_load_attr_default(base, attr, MP_OBJ_NULL);
|
||||
}
|
||||
|
||||
// no attribute found, returns: dest[0] == MP_OBJ_NULL, dest[1] == MP_OBJ_NULL
|
||||
// normal attribute found, returns: dest[0] == <attribute>, dest[1] == MP_OBJ_NULL
|
||||
// method attribute found, returns: dest[0] == <method>, dest[1] == <self>
|
||||
|
|
|
@ -45,6 +45,7 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, uint n_args_n_kw, const mp_obj_
|
|||
void mp_unpack_sequence(mp_obj_t seq, uint num, mp_obj_t *items);
|
||||
mp_obj_t mp_store_map(mp_obj_t map, mp_obj_t key, mp_obj_t value);
|
||||
mp_obj_t mp_load_attr(mp_obj_t base, qstr attr);
|
||||
mp_obj_t mp_load_attr_default(mp_obj_t base, qstr attr, mp_obj_t defval);
|
||||
void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest);
|
||||
void mp_load_method_maybe(mp_obj_t base, qstr attr, mp_obj_t *dest);
|
||||
void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t val);
|
||||
|
|
|
@ -13,3 +13,5 @@ a = A()
|
|||
print(getattr(a, "var"))
|
||||
print(getattr(a, "var2"))
|
||||
print(getattr(a, "meth")(5))
|
||||
print(getattr(a, "_none_such", 123))
|
||||
print(getattr(list, "foo", 456))
|
||||
|
|
Loading…
Reference in New Issue