Description
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 == "<module>":
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