summaryrefslogtreecommitdiffstatshomepage
path: root/tests/misc/cexample_subclass.py
diff options
context:
space:
mode:
authorLaurens Valk <laurens@pybricks.com>2022-11-21 21:35:26 +0100
committerDamien George <damien@micropython.org>2024-07-25 12:01:43 +1000
commit9ca668f881865958cbcc0e6341849a6133c4c7b4 (patch)
tree5bc69513c0fa68868aa7f6dedb69a542363eb8f1 /tests/misc/cexample_subclass.py
parent19b1333cb1376ef60376a07e8e76a41854014840 (diff)
downloadmicropython-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.py37
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()