aboutsummaryrefslogtreecommitdiff
path: root/py/objtype.c
diff options
context:
space:
mode:
authorDamien George2014-04-13 18:59:45 +0100
committerDamien George2014-04-13 18:59:45 +0100
commit777b0f32f459dbf5aac051eab3d91abbc6505501 (patch)
tree30bac9053478173fa828758d1d301ea3018f29e3 /py/objtype.c
parent4417478d0fc39b69fda058e93730b3dc3fdb1ec9 (diff)
py: Add property object, with basic functionality.
Enabled by MICROPY_ENABLE_PROPERTY.
Diffstat (limited to 'py/objtype.c')
-rw-r--r--py/objtype.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/py/objtype.c b/py/objtype.c
index cb8cfc532..c1749ff5f 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -229,15 +229,35 @@ STATIC mp_obj_t class_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
STATIC void class_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
// logic: look in obj members then class locals (TODO check this against CPython)
mp_obj_class_t *self = self_in;
+
mp_map_elem_t *elem = mp_map_lookup(&self->members, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
if (elem != NULL) {
// object member, always treated as a value
+ // TODO should we check for properties?
dest[0] = elem->value;
return;
}
+
mp_obj_t member = mp_obj_class_lookup(self->base.type, attr);
if (member != MP_OBJ_NULL) {
- class_convert_return_attr(self_in, member, dest);
+ if (0) {
+#if MICROPY_ENABLE_PROPERTY
+ } else if (MP_OBJ_IS_TYPE(member, &mp_type_property)) {
+ // object member is a property
+ // delegate the store to the property
+ // TODO should this be part of class_convert_return_attr?
+ const mp_obj_t *proxy = mp_obj_property_get(member);
+ if (proxy[0] == mp_const_none) {
+ // TODO
+ } else {
+ dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self_in);
+ // TODO should we convert the returned value using class_convert_return_attr?
+ }
+#endif
+ } else {
+ // not a property
+ class_convert_return_attr(self_in, member, dest);
+ }
return;
}
@@ -257,10 +277,30 @@ STATIC void class_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
STATIC bool class_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
mp_obj_class_t *self = self_in;
+
+#if MICROPY_ENABLE_PROPERTY
+ // for property, we need to do a lookup first in the class dict
+ // this makes all stores slow... how to fix?
+ mp_obj_t member = mp_obj_class_lookup(self->base.type, attr);
+ if (member != MP_OBJ_NULL && MP_OBJ_IS_TYPE(member, &mp_type_property)) {
+ // attribute already exists and is a property
+ // delegate the store to the property
+ const mp_obj_t *proxy = mp_obj_property_get(member);
+ if (proxy[1] == mp_const_none) {
+ // TODO better error message
+ return false;
+ } else {
+ mp_obj_t dest[2] = {self_in, value};
+ mp_call_function_n_kw(proxy[1], 2, 0, dest);
+ return true;
+ }
+ }
+#endif
+
if (value == MP_OBJ_NULL) {
// delete attribute
- mp_map_elem_t *el = mp_map_lookup(&self->members, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP_REMOVE_IF_FOUND);
- return el != NULL;
+ mp_map_elem_t *elem = mp_map_lookup(&self->members, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP_REMOVE_IF_FOUND);
+ return elem != NULL;
} else {
// store attribute
mp_map_lookup(&self->members, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;