Page 1 of 1

Instance attributes via C-API

Posted: Mon Sep 19, 2016 10:30 am
by seb
Hello,

im trying to implement a class by using the micropython c-api that needs to expose instance attributes for reading to the python domain. What is the prefered/most efficiant way to accomplish this? I found no example where instance attributes are used and exposed to the python domain within the existing micropython c-code.

Setting a ".attr" function in the type definition seems not to be a good approach, since i then have to handle all requests for attributes AND methods by myself and the "locals_dict" is used to only store class constants/attributes/methods.

Regards,
Sebastian

Re: Instance attributes via C-API

Posted: Mon Sep 19, 2016 4:12 pm
by dhylands
From python, you can call a function to get data from c-land. Is that what you're asking?

Re: Instance attributes via C-API

Posted: Tue Sep 20, 2016 6:00 am
by seb
Thanks for the quick reply. But what i mean is to add attributes to classes that are implemented in c. Maybe the following example describes better what im looking for:
C-Code

Code: Select all

STATIC mp_obj_t test_method(mp_obj_t self_in){
    return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(test_method_obj, test_method);

mp_map_elem_t test_class_locals_table[] = {
		{ MP_OBJ_NEW_QSTR(MP_QSTR_test_method), (mp_obj_t)&test_method_obj },
};

STATIC MP_DEFINE_CONST_DICT(test_class_locals, test_class_locals_table);

const mp_obj_type_t test_class = {
    .base = { &mp_type_type },
    .name = MP_QSTR_TestClass,
    .make_new = test_class_make_new,
    .locals_dict = (mp_obj_t)&test_class_locals,
    // .attr is actually not just about load/store of attributes, but also about load/store of methods. It basically replaces the locals_dict if set if i understood it right from mp_load_method_maybe(...) in runtime.c
};
// Register type somewhere ...
Python Script

Code: Select all

# Module import ...
t = TestClass()
t.test_method()
print(t.test_attribute) # <---- How to add per instance attributes in c-land to be able to read/write them in python
t.test_attribute = 42 # <----- How to add per instance attributes in c-land to be able to read/write them in python
Of course getters and setters could be an other solution, but im reimplementing an API that should be consistant to the original one.

Sebastian

Re: Instance attributes via C-API

Posted: Tue Sep 20, 2016 6:11 am
by pythoncoder
I think we understood your intention. As you've found, the MicroPython way of accessing attributes is via methods, as per for example the Pin class. I gather that this is at least partly for performance reasons. In MicroPython code it's faster to access a get/set method than using an @property decorator to access attributes which it seems requires a costly lookup. Perhaps the same would apply when accessing C classes if attributes were exposed directly?

In any event the core developers have standardised on this approach.

Re: Instance attributes via C-API

Posted: Tue Sep 20, 2016 2:36 pm
by seb
Ok then i try to stick to setters/getters. But in general i think it would be desirable to directly support definition of instance attributes in c code (Or maybe there is a way i have not discovered yet). The Pin class actually uses class attributes (e.g. the "Pin.board" attribute) which are constant in c and not specific to a certain class instance.

Thanks anyway!

Re: Instance attributes via C-API

Posted: Tue Sep 20, 2016 4:50 pm
by dhylands
So yeah, you can do attrs in C as well.

One of the members in a mpy type is called attr. So if you provide an attr method, it will be called to get/set/delete attributes.
https://github.com/micropython/micropyt ... #L466-L477

One place you can see this used is in uctypes:
https://github.com/micropython/micropyt ... pes.c#L645

Using localdict wound up being more convenient for most of the uses (most places have a fixed set of attributes).

You can use localdict to point to a python object and modify that python object in C. The downside is that the C code doesn't know when the python code accesses/modifies the object.