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
Linked PRs
Bug report
In pdb,
llwill clear the local variable change.As you can tell,
awas changed through!a = 2but it was reverted afterll.print(a)also prints the unmodified value. Withoutll, everything works fine.The reason lies in
getsourcelinesinpdb.py. In that function, it tried to accessobj.f_locals, which will refresh the dict withPyFrame_FastToLocalsWithErroras it's a property now.As a result, the local variable changes will be erased.
The original reason to check if
obj.f_globals is obj.f_localsis to check whetherobjis an module frame. Now that it has side effects to pdb, we can do the check with: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 -j3passedllstill prints the full file for module frameI'll make a PR soon and please let me know if there are any concerns about the fix.
Your environment
Linked PRs