summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--py/modbuiltins.c8
-rw-r--r--tests/basics/builtin_hasattr.py11
2 files changed, 10 insertions, 9 deletions
diff --git a/py/modbuiltins.c b/py/modbuiltins.c
index e45c714e9..2f3526415 100644
--- a/py/modbuiltins.c
+++ b/py/modbuiltins.c
@@ -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) {
qstr attr = mp_obj_str_get_qstr(attr_in);
-
mp_obj_t dest[2];
- // TODO: https://docs.python.org/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, attr, dest);
-
+ mp_load_method_protected(object_in, attr, dest, false);
return mp_obj_new_bool(dest[0] != MP_OBJ_NULL);
}
MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_hasattr_obj, mp_builtin_hasattr);
diff --git a/tests/basics/builtin_hasattr.py b/tests/basics/builtin_hasattr.py
index 118a19e57..c60033b96 100644
--- a/tests/basics/builtin_hasattr.py
+++ b/tests/basics/builtin_hasattr.py
@@ -21,12 +21,19 @@ class C:
def __getattr__(self, attr):
if attr == "exists":
return attr
+ elif attr == "raise":
+ raise Exception(123)
raise AttributeError
c = C()
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:
hasattr(1, b'123')