pdb loses local variable change after command longlist · Issue #101673 · python/cpython (original) (raw)
Bug report
In pdb, ll
will clear the local variable change.
def main(): a = 1 breakpoint() print(a)
main()
-> print(a) (Pdb) p a 1 (Pdb) !a = 2 (Pdb) p a 2 (Pdb) ll 1 def main(): 2 a = 1 3 breakpoint() 4 -> print(a) (Pdb) p a 1 (Pdb) s 1 --Return--
As you can tell, a
was changed through !a = 2
but it was reverted after ll
. print(a)
also prints the unmodified value. Without ll
, everything works fine.
The reason lies in getsourcelines
in pdb.py
. In that function, it tried to access obj.f_locals
, which will refresh the dict with PyFrame_FastToLocalsWithError
as it's a property now.
if inspect.isframe(obj) and obj.f_globals is obj.f_locals:
As a result, the local variable changes will be erased.
The original reason to check if obj.f_globals is obj.f_locals
is to check whether obj
is an module frame. Now that it has side effects to pdb, we can do the check with:
if inspect.isframe(obj) and obj.f_code.co_name == "":
It might not be the most delicate way, but I can't think of a situation where this won't work.
I did this change locally and I have confirmed:
./python -m test -j3
passed- The original bug is fixed
ll
still prints the full file for module frame
I'll make a PR soon and please let me know if there are any concerns about the fix.
Your environment
- CPython versions tested on: 3.11.1
- Operating system and architecture: Ubuntu 20.04