summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorJeff Epler <jepler@unpythonic.net>2018-03-25 14:25:32 -0500
committerJeff Epler <jepler@unpythonic.net>2018-03-25 15:11:40 -0500
commit74fefe45a4cc6073d16af32e0fe35e1fd389d558 (patch)
tree841c2e31c4c1121475f2c720bbd4118d26c831c5 /py
parent922b7c313197a28aa8243710d2d26f1034575674 (diff)
super(): Do the same lookup tasks as regular getattr
.. in the presence of properties and descriptors
Diffstat (limited to 'py')
-rw-r--r--py/objtype.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/py/objtype.c b/py/objtype.c
index 1d6dc0b6c..7262892bd 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -567,6 +567,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des
mp_obj_class_lookup(&lookup, self->base.type);
mp_obj_t member = dest[0];
if (member != MP_OBJ_NULL) {
+ // changes here may may require changes to super_attr, below
#if MICROPY_PY_BUILTINS_PROPERTY
if (MP_OBJ_IS_TYPE(member, &mp_type_property)) {
// object member is a property; delegate the load to the property
@@ -1112,14 +1113,37 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type));
mp_obj_class_lookup(&lookup, (mp_obj_type_t*)MP_OBJ_TO_PTR(items[i]));
if (dest[0] != MP_OBJ_NULL) {
- return;
+ break;
}
}
} else {
mp_obj_class_lookup(&lookup, type->parent);
- if (dest[0] != MP_OBJ_NULL) {
- return;
+ }
+
+ if (dest[0] != MP_OBJ_NULL) {
+ mp_obj_t member = dest[0];
+ // changes to mp_obj_instance_load_attr may require changes
+ // here...
+ #if MICROPY_PY_BUILTINS_PROPERTY
+ if (MP_OBJ_IS_TYPE(member, &mp_type_property)) {
+ const mp_obj_t *proxy = mp_obj_property_get(member);
+ if (proxy[0] == mp_const_none) {
+ mp_raise_AttributeError("unreadable attribute");
+ } else {
+ dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self_in);
+ }
+ }
+ #endif
+ #if MICROPY_PY_DESCRIPTORS
+ mp_obj_t attr_get_method[4];
+ mp_load_method_maybe(member, MP_QSTR___get__, attr_get_method);
+ if (attr_get_method[0] != MP_OBJ_NULL) {
+ attr_get_method[2] = self_in;
+ attr_get_method[3] = MP_OBJ_FROM_PTR(mp_obj_get_type(self_in));
+ dest[0] = mp_call_method_n_kw(2, 0, attr_get_method);
}
+ #endif
+ return;
}
mp_obj_class_lookup(&lookup, &mp_type_object);