Implement a property in a builtin module

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
User avatar
gcarver
Posts: 34
Joined: Sun Oct 26, 2014 4:07 am
Location: New Market, Maryland
Contact:

Implement a property in a builtin module

Post by gcarver » Tue Nov 25, 2014 3:48 am

Is it possible to implement a python property in a c implemented module?
I have an instance method, class method and class constant but can't find an example of a property.

//instance method
{ MP_OBJ_NEW_QSTR(MP_QSTR_circle), (mp_obj_t)&pyb_tft_circle_obj },

//class method
{ MP_OBJ_NEW_QSTR(MP_QSTR_color), (mp_obj_t)&tft_color_obj },

//class constant
{ MP_OBJ_NEW_QSTR(MP_QSTR_BLACK), MP_OBJ_NEW_SMALL_INT(TFT_COLOR_BLACK) },
End of line...

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Implement a property in a builtin module

Post by stijn » Tue Nov 25, 2014 9:34 am

I think you have to implement it as load_attr/store_attr (at least that is what I'm using and it works ok), but maybe I'm overlooking something and there's another way.
Anyway see objmodule.c for a possible implementation which just loads/stores to the module's dict

Code: Select all

STATIC void module_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
    mp_obj_module_t *self = self_in;
    mp_map_elem_t *elem = mp_map_lookup(&self->globals->map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
    if (elem != NULL) {
        dest[0] = elem->value;
    }
}

STATIC bool module_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
    mp_obj_module_t *self = self_in;
    if (value == MP_OBJ_NULL) {
        // delete attribute
        mp_obj_dict_delete(self->globals, MP_OBJ_NEW_QSTR(attr));
    } else {
        // store attribute
        // TODO CPython allows STORE_ATTR to a module, but is this the correct implementation?
        mp_obj_dict_store(self->globals, MP_OBJ_NEW_QSTR(attr), value);
    }
    return true;
}

const mp_obj_type_t mp_type_module = {
    { &mp_type_type },
    .name = MP_QSTR_module,
    .print = module_print,
    .load_attr = module_load_attr,
    .store_attr = module_store_attr,
};

User avatar
gcarver
Posts: 34
Joined: Sun Oct 26, 2014 4:07 am
Location: New Market, Maryland
Contact:

Re: Implement a property in a builtin module

Post by gcarver » Wed Nov 26, 2014 10:49 pm

Thanks for the help. I got my "size" property working but all methods and variables broke.
It seems that if I set .load_attr then my .locals_dict is not accessible. help() shows all of my methods but attempting to call them returns an error TFT object has not attribute ???.
End of line...

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Implement a property in a builtin module

Post by dhylands » Thu Nov 27, 2014 5:01 am

Currently the code assumes that if load_attr exists. then it does the right thing.

I think that mp_load_method_maybe (from py/runtime.c) is the function that makes this decision.

It might be interesting to split out this portion: https://github.com/micropython/micropyt ... #L900-L928 into a separate function so that you could override load_attr and have it call the new method if load_attr didn't find what it was looking for.

You should probably bring this up as an issue on github in case there is a better way to implement what you want.

User avatar
gcarver
Posts: 34
Joined: Sun Oct 26, 2014 4:07 am
Location: New Market, Maryland
Contact:

Re: Implement a property in a builtin module

Post by gcarver » Thu Nov 27, 2014 6:26 am

I might do that but right now I'm trying a different approach. I am attempting to create an actual property using mp_obj_property_t. I have created the property and help() shows the property on my TFT class. But the property doesn't work. It simply returns a property object rather than calling the getter/setter. So I'm still doing something wrong but I think it's the better approach. I'll take a couple more stabs at it. Maybe create a test that builds in windows so I can debug it.
End of line...

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Implement a property in a builtin module

Post by stijn » Thu Nov 27, 2014 7:58 am

dhylands wrote:It might be interesting to split out this portion: https://github.com/micropython/micropyt ... #L900-L928 into a separate function so that you could override load_attr and have it call the new method if load_attr didn't find what it was looking for.
Or maybe just switch the two cases so if first checks locals_dict and then load_attr. Though likely there's a good reason it is the way it is now. Yet, it doesn't make much sense (to me) that when there is a load_attr the type has to do al the work itself?

Post Reply