diff options
author | Laurens Valk <laurens@pybricks.com> | 2022-11-21 21:35:26 +0100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2024-07-25 12:01:43 +1000 |
commit | 9ca668f881865958cbcc0e6341849a6133c4c7b4 (patch) | |
tree | 5bc69513c0fa68868aa7f6dedb69a542363eb8f1 /tests/misc/cexample_subclass.py | |
parent | 19b1333cb1376ef60376a07e8e76a41854014840 (diff) | |
download | micropython-9ca668f881865958cbcc0e6341849a6133c4c7b4.tar.gz micropython-9ca668f881865958cbcc0e6341849a6133c4c7b4.zip |
py/objtype: Avoid crash on calling members of uninitialized native type.
When subclassing a native type, calling native members in `__init__` before
`super().__init__()` has been called could cause a crash. In this
situation, `self` in `mp_convert_member_lookup` is the
`native_base_init_wrapper_obj`. The check added in this commit ensures
that an `AttributeError` is raised before this happens, which is consistent
with other failed lookups.
Also fix a typo in a related comment.
Signed-off-by: Laurens Valk <laurens@pybricks.com>
Diffstat (limited to 'tests/misc/cexample_subclass.py')
-rw-r--r-- | tests/misc/cexample_subclass.py | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/tests/misc/cexample_subclass.py b/tests/misc/cexample_subclass.py new file mode 100644 index 0000000000..9f52a2c737 --- /dev/null +++ b/tests/misc/cexample_subclass.py @@ -0,0 +1,37 @@ +# test subclassing custom native class + +try: + from cexample import AdvancedTimer +except ImportError: + print("SKIP") + raise SystemExit + + +class SubTimer(AdvancedTimer): + def __init__(self): + # At this point, self does not yet represent a AdvancedTimer instance. + print(self) + + # So lookups via type.attr handler will fail. + try: + self.seconds + except AttributeError: + print("AttributeError") + + # Also applies to builtin methods. + try: + self.time() + except AttributeError: + print("AttributeError") + + # Initialize base class. + super().__init__(self) + + # Now you can access methods and attributes normally. + self.time() + print(self.seconds) + self.seconds = 123 + print(self.seconds) + + +watch = SubTimer() |