py: Add basic implementation of hasattr() function.
This commit is contained in:
parent
a0863158f5
commit
ff30666c69
15
py/builtin.c
15
py/builtin.c
|
@ -462,6 +462,21 @@ STATIC mp_obj_t mp_builtin_getattr(uint n_args, const mp_obj_t *args) {
|
||||||
|
|
||||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_getattr_obj, 2, 3, mp_builtin_getattr);
|
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_getattr_obj, 2, 3, mp_builtin_getattr);
|
||||||
|
|
||||||
|
STATIC mp_obj_t mp_builtin_hasattr(mp_obj_t object_in, mp_obj_t attr_in) {
|
||||||
|
assert(MP_OBJ_IS_QSTR(attr_in));
|
||||||
|
|
||||||
|
mp_obj_t dest[2];
|
||||||
|
// TODO: https://docs.python.org/3.3/library/functions.html?highlight=hasattr#hasattr
|
||||||
|
// explicitly says "This is implemented by calling getattr(object, name) and seeing
|
||||||
|
// whether it raises an AttributeError or not.", so we should explicitly wrap this
|
||||||
|
// in nlr_push and handle exception.
|
||||||
|
mp_load_method_maybe(object_in, MP_OBJ_QSTR_VALUE(attr_in), dest);
|
||||||
|
|
||||||
|
return MP_BOOL(dest[0] != MP_OBJ_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_hasattr_obj, mp_builtin_hasattr);
|
||||||
|
|
||||||
// These two are defined in terms of MicroPython API functions right away
|
// These two are defined in terms of MicroPython API functions right away
|
||||||
MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_globals_obj, mp_globals_get);
|
MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_globals_obj, mp_globals_get);
|
||||||
MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_locals_obj, mp_locals_get);
|
MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_locals_obj, mp_locals_get);
|
||||||
|
|
|
@ -41,6 +41,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin_eval_obj);
|
||||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_exec_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_exec_obj);
|
||||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_getattr_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_getattr_obj);
|
||||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_globals_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_globals_obj);
|
||||||
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hasattr_obj);
|
||||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hash_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hash_obj);
|
||||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hex_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hex_obj);
|
||||||
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_id_obj);
|
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_id_obj);
|
||||||
|
|
|
@ -90,6 +90,7 @@ STATIC const mp_map_elem_t mp_builtin_object_table[] = {
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_exec), (mp_obj_t)&mp_builtin_exec_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_exec), (mp_obj_t)&mp_builtin_exec_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getattr), (mp_obj_t)&mp_builtin_getattr_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_getattr), (mp_obj_t)&mp_builtin_getattr_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_globals), (mp_obj_t)&mp_builtin_globals_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_globals), (mp_obj_t)&mp_builtin_globals_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_hasattr), (mp_obj_t)&mp_builtin_hasattr_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hash), (mp_obj_t)&mp_builtin_hash_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_hash), (mp_obj_t)&mp_builtin_hash_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hex), (mp_obj_t)&mp_builtin_hex_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_hex), (mp_obj_t)&mp_builtin_hex_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_id), (mp_obj_t)&mp_builtin_id_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_id), (mp_obj_t)&mp_builtin_id_obj },
|
||||||
|
|
|
@ -142,6 +142,7 @@ Q(float)
|
||||||
Q(from_bytes)
|
Q(from_bytes)
|
||||||
Q(getattr)
|
Q(getattr)
|
||||||
Q(globals)
|
Q(globals)
|
||||||
|
Q(hasattr)
|
||||||
Q(hash)
|
Q(hash)
|
||||||
Q(hex)
|
Q(hex)
|
||||||
Q(%#x)
|
Q(%#x)
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
class A:
|
||||||
|
|
||||||
|
var = 132
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.var2 = 34
|
||||||
|
|
||||||
|
def meth(self, i):
|
||||||
|
return 42 + i
|
||||||
|
|
||||||
|
|
||||||
|
a = A()
|
||||||
|
print(hasattr(a, "var"))
|
||||||
|
print(hasattr(a, "var2"))
|
||||||
|
print(hasattr(a, "meth"))
|
||||||
|
print(hasattr(a, "_none_such"))
|
||||||
|
print(hasattr(list, "foo"))
|
||||||
|
|
||||||
|
class C:
|
||||||
|
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
if attr == "exists":
|
||||||
|
return attr
|
||||||
|
raise AttributeError
|
||||||
|
|
||||||
|
c = C()
|
||||||
|
print(hasattr(c, "exists"))
|
||||||
|
# TODO
|
||||||
|
#print(hasattr(c, "doesnt_exist"))
|
Loading…
Reference in New Issue