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
Preserve changes to frame locals when going up/down in the stack frame #13051
base: main
Are you sure you want to change the base?
Preserve changes to frame locals when going up/down in the stack frame #13051
Conversation
ab1ac90
to
1337bbf
Compare
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.
Unfortunately, this causes a regression - it makes it impossible to change the values of the variables in the local scope. The changes are only visible to the debugger, but not to the debugged code.
On master
branch:
Python 3.8.6 (default, Jun 23 2021, 23:50:42)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.0.0.dev -- An enhanced Interactive Python. Type '?' for help.
In [1]: def print_my_var():
...: my_var = '==== unchanged ===='
...: print(my_var)
...:
In [2]: %debug print_my_var()
NOTE: Enter 'c' at the ipdb> prompt to continue execution.
> <string>(1)<module>()
ipdb> s
--Call--
> <ipython-input-1-5aa28ff21139>(1)print_my_var()
----> 1 def print_my_var():
2 my_var = '==== unchanged ===='
3 print(my_var)
4
ipdb> n
> <ipython-input-1-5aa28ff21139>(2)print_my_var()
1 def print_my_var():
----> 2 my_var = '==== unchanged ===='
3 print(my_var)
4
ipdb> n
> <ipython-input-1-5aa28ff21139>(3)print_my_var()
1 def print_my_var():
2 my_var = '==== unchanged ===='
----> 3 print(my_var)
4
ipdb> my_var = "==== changed ===="
ipdb> n
==== changed ====
--Return--
None
> <ipython-input-1-5aa28ff21139>(3)print_my_var()
1 def print_my_var():
2 my_var = '==== unchanged ===='
----> 3 print(my_var)
4
With the changes presented in this PR:
Python 3.8.6 (default, Jun 23 2021, 23:50:42)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.0.0.dev -- An enhanced Interactive Python. Type '?' for help.
In [1]: def print_my_var():
...: my_var = '==== unchanged ===='
...: print(my_var)
...:
In [2]: %debug print_my_var()
NOTE: Enter 'c' at the ipdb> prompt to continue execution.
> <string>(1)<module>()
ipdb> s
--Call--
> <ipython-input-1-5aa28ff21139>(1)print_my_var()
----> 1 def print_my_var():
2 my_var = '==== unchanged ===='
3 print(my_var)
4
ipdb> n
> <ipython-input-1-5aa28ff21139>(2)print_my_var()
1 def print_my_var():
----> 2 my_var = '==== unchanged ===='
3 print(my_var)
4
ipdb> n
> <ipython-input-1-5aa28ff21139>(3)print_my_var()
1 def print_my_var():
2 my_var = '==== unchanged ===='
----> 3 print(my_var)
4
ipdb> my_var = "==== changed ===="
ipdb> n
==== unchanged ====
--Return--
None
> <ipython-input-1-5aa28ff21139>(3)print_my_var()
1 def print_my_var():
2 my_var = '==== unchanged ===='
----> 3 print(my_var)
4
Hey @MrMino, thanks a lot for checking that! I'll try to address that problem when I have some free time. |
+1 when this work. marking as for 7.x |
when going up/down in the stack frame. | ||
""" | ||
self.frame_locals = [ | ||
stack_entry[0].f_locals.copy() for stack_entry in self.stack |
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.
@ccordoba12 , is there any need to copy this dict?
If there isn't, removing copy()
could fix the problem mentioned by @MrMino (I've tested locally their example, and it worked as expected).
stack_entry[0].f_locals.copy() for stack_entry in self.stack | |
stack_entry[0].f_locals for stack_entry in self.stack |
If you need to keep only certain subset of changes, I would suggest to wrap the original locals with a ChainMap
s at some point.
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.
Could you clarify? What's a ChainMap
?
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.
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.
Ok, thanks a lot for the suggestion! I'll take a look at it as soon as Io have some free time.
Description
This complements the excellent improvements on PR #13021 by preserving frame locals when going up/down in the stack. Below I show gifs of the previous and new behaviors using Spyder:
Before
After
Implementation
This was accomplished by saving a copy of all frame locals before the debugger starts and using them to set
curframe_locals
after every command run in the debugger. That prevents that accesses tof_locals
(which happens in up/down) reset the locals set by the user.Notes