-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
py: Implement __dict__ for instances #1757
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Note that even though wrapped in MICROPY_CPYTHON_COMPAT, it is not fully compatible because the modifications to the dictionary do not propagate to the actual instance members.
// Create a new dict with a copy of the instance's map items. | ||
// This creates, unlike CPython, a 'read-only' __dict__: modifying | ||
// it will not result in modifications to the actual instance members. | ||
mp_map_t *map = &(self->members); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's up with those parentheses?
Though wait, while all this creation of copies, why not reuse self->members? |
I'm not sure how. Is it ok to create a new mp_obj_dict_t, then use |
Ok so I gave reuse a go but it does not seem safe, maybe because it's not the correct way but I don't immediately see another way:
Through the dict returned class members can now be modified. However what seems 'unsafe' to me:
|
That doesn't sound right... I think the reason it's like that is because (up until now) only ordered maps could be fixed (ie fixed implied ordered). But that won't be the case if #1731 is used. So it should be changed so that fixed is independent of ordered. Then probably your new way would work. |
is_fixed problem fixed in 6dde019. |
Thanks! This introduces a bunch of possible NULL dereferencing locations since functions like dict_update/dict_store do not check the return value of mp_map_lookup. Changing those to check the value just to accomodate this PR doesn't seem right - moreover it would create a dict which isn't really a dict but rather some cross-breed readonly dict which advertises itself as a dict.. Leaving it as-is feels even more wrong because of the same problem (not really a dict) but it adds segfaulting on top. Not really sure what to do here. Possible options I see:
|
@stinos : Right, I missed that mp_obj_dict contains map, not references it. I'd still think that just making a clone of a map with a couple of memcpy() would be less code bytes than recreating it by inserting, but if you think it's not worth it, let's be back to the original patch. |
Another potential solution would be to make self->members be a dict and have I did some checks and what I see for memory usage is the following: I think that means that instance of objects which are declared class Foo: take up 1 heap block, and instance of objects declared class Foo(object) take up 2. If we changed mp_obj_dict_t to use a pointer to a map, then every dictionary would take up 2 heap blocks, where it currently only takes up 1. If we changed mp_obj_instance_t to contain a dict rather than a map, then instances of objects declared class Foo: would now take up 2 heap blocks, but instances of objects declared class Foo(object): would still only take up 2 heap blocks. |
Ok, let's have this merged and move on. Note that trivial changes/optimizations applied and test added. |
The original PR included a new test... should we merge both that and the new one into a single file? |
Both tests do basically the same so I'd just keep the one with the most suitable name? @dpgeorge object_dict or builtin_dict? |
@stinos I'd expect builtin_dict to be a test for the builtin |
Expose displayio.Display.bus
No description provided.