py/modbuiltins: Make built-in hasattr work properly for user types.
It now allows __getattr__ in a user type to raise AttributeError when the attribute does not exist.
This commit is contained in:
parent
bc87b862fd
commit
529860643b
@ -525,14 +525,8 @@ MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_delattr_obj, mp_builtin_delattr);
|
|||||||
|
|
||||||
STATIC mp_obj_t mp_builtin_hasattr(mp_obj_t object_in, mp_obj_t attr_in) {
|
STATIC mp_obj_t mp_builtin_hasattr(mp_obj_t object_in, mp_obj_t attr_in) {
|
||||||
qstr attr = mp_obj_str_get_qstr(attr_in);
|
qstr attr = mp_obj_str_get_qstr(attr_in);
|
||||||
|
|
||||||
mp_obj_t dest[2];
|
mp_obj_t dest[2];
|
||||||
// TODO: https://docs.python.org/3/library/functions.html?highlight=hasattr#hasattr
|
mp_load_method_protected(object_in, attr, dest, false);
|
||||||
// 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, attr, dest);
|
|
||||||
|
|
||||||
return mp_obj_new_bool(dest[0] != MP_OBJ_NULL);
|
return mp_obj_new_bool(dest[0] != MP_OBJ_NULL);
|
||||||
}
|
}
|
||||||
MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_hasattr_obj, mp_builtin_hasattr);
|
MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_hasattr_obj, mp_builtin_hasattr);
|
||||||
|
@ -21,12 +21,19 @@ class C:
|
|||||||
def __getattr__(self, attr):
|
def __getattr__(self, attr):
|
||||||
if attr == "exists":
|
if attr == "exists":
|
||||||
return attr
|
return attr
|
||||||
|
elif attr == "raise":
|
||||||
|
raise Exception(123)
|
||||||
raise AttributeError
|
raise AttributeError
|
||||||
|
|
||||||
c = C()
|
c = C()
|
||||||
print(hasattr(c, "exists"))
|
print(hasattr(c, "exists"))
|
||||||
# TODO
|
print(hasattr(c, "doesnt_exist"))
|
||||||
#print(hasattr(c, "doesnt_exist"))
|
|
||||||
|
# ensure that non-AttributeError exceptions propagate out of hasattr
|
||||||
|
try:
|
||||||
|
hasattr(c, "raise")
|
||||||
|
except Exception as er:
|
||||||
|
print(er)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
hasattr(1, b'123')
|
hasattr(1, b'123')
|
||||||
|
Loading…
Reference in New Issue
Block a user