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
py: Support object __getattr__, __delattr__ and __setattr__ #2689
Conversation
@@ -533,6 +533,15 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des | |||
|
|||
// try __getattr__ | |||
if (attr != MP_QSTR___getattr__) { | |||
|
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.
This empty line is superfluous.
@@ -533,6 +533,15 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des | |||
|
|||
// try __getattr__ | |||
if (attr != MP_QSTR___getattr__) { | |||
|
|||
#if MICROPY_PY_ATTRS_METHODS | |||
// if __getattr__ was called with attr == __setattr__ return MP_OBJ_NULL for indicate success |
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.
Typo in comment
Commit message should explain how all this stuff works. |
This change isn't exactly compatible with Python3:
|
@pfalcon I don't understand your comment. If I run the unix build of micropython using this PR and your example:
I get exactly the same output as python3. Perhaps you could clarify what you meant? |
del a.a | ||
print(a.a) | ||
except AttributeError: | ||
print("AttributeError") |
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.
Missing newline.
Ok, then I'm wrong, I didn't run-test this patch. But something in this patch looks superfluous, maybe this check in |
@pfalcon |
@pfalcon @dhylands the unix version of this patch has the macro "MICROPY_PY_ATTRS_METHODS" setted to 0 inherited from py/mpconfig.h only into "coverage" version the macro "MICROPY_PY_ATTRS_METHODS" is enabled. Enabling it:
|
ok - I was confusing config options. When I enable it properly, then
|
@dmazzella : Ok. My note on different behavior regarding |
(Note there's no need to close one pullreq and open another if you update a patch - just push --force after rebase/amend). |
only
|
From Python3 docs the correct way to implement attribute access is implement method @pfalcon and @dpgeorge i have implemented |
…etattr__ implemented __getattribute__
@pfalcon now we can see:
|
I have measured performance on pyboard 1.1 with this script:
Without MICROPY_PY_ATTRS_METHODS:
with MICROPY_PY_ATTRS_METHODS:
|
I have measured performance on pyboard 1.1 with this script:
Without MICROPY_PY_ATTRS_METHODS:
With MICROPY_PY_ATTRS_METHODS:
|
I have measured performance on pyboard 1.1 with this script:
Without MICROPY_PY_ATTRS_METHODS:
With MICROPY_PY_ATTRS_METHODS:
|
@dmazella an important performance test is for code that doesn't use this new feature. Eg just a simple load of an instance member, like this: class A:
def __init__(self):
self.a = 1
def test_set(self):
self.a = 1
self.a = 1
self.a = 1
self.a = 1 And then benchmark the |
You will need to write tests to cover all the new lines of code that you add. There are 10 new lines in objobject.c that you don't hit with your test file. Because this is tricky stuff it's important to have test for the behaviour, to match CPython. Also, it's not clear to me that the additional methods for @stinos I recall that you tried out these new special methods. Did you need to use |
I already gave my suggestion: please make sure that commit message discusses in the detail how the code works. That hasn't been done. There're more suggestions: it started with |
@dpgeorge i have used this script for run tests:
The results are: uPy without patch:
uPy with patch:
cPy:
|
@pfalcon ok, if you prefer i can close this pr and split it in more pr. |
That's my personal suggestion, you may want to wait for @dpgeorge's further comments. |
@dpgeorge i have used for example in objobject.c:
as map where i lookup for attributes, is correct to use this or is more appropriate to use:
? |
It looks like Having The original discussion started with a need for |
@dpgeorge Tested latest version again with this and it's still working (for the rather limited code tested with):
|
ok, I close this, divide into 2 new PR as soon as possible |
In relatively unusual circumstances, such as entering `l = 17 ** 17777` at the REPL, you could hit ctrl-c, but not get KeyboardInterrupt. This can lead to a condition where the display would stop updating (micropython#2689).
In micropython#2689, hitting ctrl-c during the printing of an object with a lot of sub-objects could cause the screen to stop updating (without showing a KeyboardInterrupt). This makes the printing of such objects acutally interruptable, and also correctly handles the KeyboardInterrupt: ``` >>> l = ["a" * 100] * 200 >>> l ['aaaaaaaaaaaaaaaaaaaaaa...aaaaaaaaaaa', Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyboardInterrupt: >>> ```
This patch implements methods
__delattr__
,__getattr__
and__setattr__
for user-type and allows the use of calls likesuper(A, self).__setattr__('a', 1)
for discussion see #2375