allow attr value change but no new additions

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

allow attr value change but no new additions

Post by jickster » Mon Feb 26, 2018 6:54 pm

I'm creating a new type can_message

Here's relevant code so far

Code: Select all

STATIC const mp_rom_map_elem_t can_message_type_locals_dict_table[] =
{
		{MP_ROM_QSTR(MP_QSTR_msg_id), MP_ROM_PTR(&mp_type_int)},
		{MP_ROM_QSTR(MP_QSTR_msg_data), MP_ROM_PTR(&mp_type_list)},
};

STATIC MP_DEFINE_CONST_DICT(can_message_type_locals_dict, can_message_type_locals_dict_table);

const mp_obj_type_t can_message_type =
{
	{&mp_type_type},
	.name = MP_QSTR_message,
	.print = can_message_obj_print,
	.make_new = can_message_make_new,
	.locals_dict = (mp_obj_t)&can_message_type_locals_dict
};
I want user to be able to modify msg_id, msg_data fields directly

Python

Code: Select all

msg = can_message()
msg.msg_id = 55
msg.msg_data = [1, 2, 3, 4, 6]
However, I do NOT want them to be able to ADD new fields i.e.

Python

Code: Select all

msg.bajsdlsakdfa = 55
Using my c-debugger, I see the function mp_store_attr is called and it checks if the mp_type_can_message.attr is defined.
...
As I was writing this I think I know the answer: I need to create a mp_type_can_message.attr function and inside it, check if the "qstr attr" argument exists.

If there's a better way, please reply.

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

Re: allow attr value change but no new additions

Post by stijn » Mon Feb 26, 2018 7:38 pm

Yes you can implement attr.
However note that the code shown is a bit extraordinary: when providing locals_dict, you normally do so to map names to functions etc. What you do is saying 'here's a member msg_id and it's value is the type int' so if you make an instance of that class like a = can_message() then a.msg_id would return <class 'int'> which is not what you want, looking at the usage example provided. Moreover, that is a const dict so assigning to it isn't possible. Have a look at the code in objcomplex.c for instance: get rid of that dict, instead provide id/data members on the type and implement attr to get/set them.

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: allow attr value change but no new additions

Post by jickster » Tue Feb 27, 2018 2:53 pm

stijn wrote:
Mon Feb 26, 2018 7:38 pm
Yes you can implement attr.
However note that the code shown is a bit extraordinary: when providing locals_dict, you normally do so to map names to functions etc. What you do is saying 'here's a member msg_id and it's value is the type int' so if you make an instance of that class like a = can_message() then a.msg_id would return <class 'int'> which is not what you want, looking at the usage example provided. Moreover, that is a const dict so assigning to it isn't possible. Have a look at the code in objcomplex.c for instance: get rid of that dict, instead provide id/data members on the type and implement attr to get/set them.
Yes I realized that I do not know what the mapping in can_message_type_locals_dict_table should be.

What should it be?

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

Re: allow attr value change but no new additions

Post by stijn » Tue Feb 27, 2018 3:08 pm

You don't need really need locals_dict if you have no ordinary functions on your type.

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: allow attr value change but no new additions

Post by jickster » Tue Feb 27, 2018 7:03 pm

stijn wrote:
Tue Feb 27, 2018 3:08 pm
You don't need really need locals_dict if you have no ordinary functions on your type.
So how do I store the attributes i.e. can_msg.id, can_msg.data ?

And if I don't have .locals_dict, dir(can_message) won't return anything.

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

Re: allow attr value change but no new additions

Post by stijn » Tue Feb 27, 2018 7:34 pm

jickster wrote:
Tue Feb 27, 2018 7:03 pm
So how do I store the attributes i.e. can_msg.id, can_msg.data ?
In the attr function. And there you can also check the type etc, which you likely want to do because you probably don't want people to assign a list of strings to your data member for instance.
And if I don't have .locals_dict, dir(can_message) won't return anything.
Well that's a MicroPython limitation. Unlike CPython which returns pretty much the same for dir(can_message) and dir(can_message()), MicroPython will only return id/data for the latter case.

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: allow attr value change but no new additions

Post by jickster » Wed Feb 28, 2018 5:03 am

stijn wrote:
Tue Feb 27, 2018 7:34 pm
jickster wrote:
Tue Feb 27, 2018 7:03 pm
So how do I store the attributes i.e. can_msg.id, can_msg.data ?
In the attr function. And there you can also check the type etc, which you likely want to do because you probably don't want people to assign a list of strings to your data member for instance.
And if I don't have .locals_dict, dir(can_message) won't return anything.
Well that's a MicroPython limitation. Unlike CPython which returns pretty much the same for dir(can_message) and dir(can_message()), MicroPython will only return id/data for the latter case.
But then how would tab autocomplete on an instance of can_message?

I’m on my phone now so I’ll check the answer to this myself.

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

Re: allow attr value change but no new additions

Post by stijn » Wed Feb 28, 2018 8:58 am

See mp_repl_autocomplete: the principle is to try all possible strings with mp_load_method_maybe, which will eventually end up calling your attr function.

Post Reply