forked from micropython/micropython
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Closed
Labels
Milestone
Description
CircuitPython version
Adafruit CircuitPython 8.0.0-alpha.1 on 2022-06-09; Adafruit Feather ESP32S3 4MB Flash 2MB PSRAM with ESP32S3.Code/REPL
class RecursiveProperty:
def __init__(self):
self.value = 0 # first: "value" is our backing *field*
def set_value(self, new_value):
"""
A setter for the "value" field
"""
print('In set_value, new_value =', new_value)
self.value = new_value
# note that here we use the same "value" name for the property,
# even though we were already using it for the field backing that property(!)
value = property(None, set_value)
rec = RecursiveProperty()
rec.value = 42Behavior
The lines starting with [tio] are messages from the serial client tio.
[tio] Waiting for tty device..
[tio] Connected
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
In set_value, new_value = 0
[tio] Disconnected
[tio] Connected
Auto-reload is off.
Running in safe mode! Not running saved code.
You are in safe mode because:
CircuitPython core code crashed hard. Whoops!
Crash into the HardFault_Handler.
Please file an issue with the contents of your CIRCUITPY drive at
https://github.com/adafruit/circuitpython/issues
Press any key to enter the REPL. Use CTRL-D to reload.
Description
This crash happens when a class sets a field with a given name in its constructor, and then below the constructor declares a property with the exact same name, providing a setter to assign values.
So:
self.some_name = some_valuefollowed by:
some_name = property(None, setter_for_the_field)I have not tried the case where there's also a getter, or just a getter and no setter, just what's in this report.
Note: yes I do know how to write this correctly with different names for the backing field and the property. This was accidental :-)
Additional information
This is what happens when the same code is executed with Python 3.9.13:
In set_value, new_value = 0
In set_value, new_value = 0
[ … many, many more of the same line … ]
In set_value, new_value = 0
In set_value, new_value = 0
Traceback (most recent call last):
File "/private/tmp/test.py", line 16, in <module>
rec = RecursiveProperty()
File "/private/tmp/test.py", line 3, in __init__
self.value = 0 # first: "value" is our backing *field*
File "/private/tmp/test.py", line 10, in set_value
self.value = new_value
File "/private/tmp/test.py", line 10, in set_value
self.value = new_value
File "/private/tmp/test.py", line 10, in set_value
self.value = new_value
[Previous line repeated 990 more times]
File "/private/tmp/test.py", line 9, in set_value
print('In set_value, new_value =', new_value)
RecursionError: maximum recursion depth exceeded while calling a Python object