diff options
author | Damien George <damien.p.george@gmail.com> | 2020-05-29 10:28:38 +1000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2020-06-02 15:42:20 +1000 |
commit | 203b10703e5df20939b88a2ce29bb961cce7e4b6 (patch) | |
tree | c7d9b303ed56097b1b0cd3ddd09f0218a4ec331b | |
parent | da71f55e23a97102d241481e410fdb22d7c55758 (diff) | |
download | micropython-203b10703e5df20939b88a2ce29bb961cce7e4b6.tar.gz micropython-203b10703e5df20939b88a2ce29bb961cce7e4b6.zip |
py/modbuiltins: Fix getattr to work with class raising AttributeError.
Fixes issue #6089.
-rw-r--r-- | py/modbuiltins.c | 6 | ||||
-rw-r--r-- | tests/basics/builtin_getattr.py | 12 |
2 files changed, 17 insertions, 1 deletions
diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 85d30ab66d..cfbfc5a256 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -558,7 +558,11 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted); static inline mp_obj_t mp_load_attr_default(mp_obj_t base, qstr attr, mp_obj_t defval) { mp_obj_t dest[2]; // use load_method, raising or not raising exception - ((defval == MP_OBJ_NULL) ? mp_load_method : mp_load_method_maybe)(base, attr, dest); + if (defval == MP_OBJ_NULL) { + mp_load_method(base, attr, dest); + } else { + mp_load_method_protected(base, attr, dest, false); + } if (dest[0] == MP_OBJ_NULL) { return defval; } else if (dest[1] == MP_OBJ_NULL) { diff --git a/tests/basics/builtin_getattr.py b/tests/basics/builtin_getattr.py index 59cb7e7f7a..afa4ab3293 100644 --- a/tests/basics/builtin_getattr.py +++ b/tests/basics/builtin_getattr.py @@ -16,3 +16,15 @@ print(getattr(a, "meth")(5)) print(getattr(a, "_none_such", 123)) print(getattr(list, "foo", 456)) print(getattr(a, "va" + "r2")) + +# test a class that defines __getattr__ and may raise AttributeError +class B: + def __getattr__(self, attr): + if attr == "a": + return attr + else: + raise AttributeError +b = B() +print(getattr(b, "a")) +print(getattr(b, "a", "default")) +print(getattr(b, "b", "default")) |