pudb icon indicating copy to clipboard operation
pudb copied to clipboard

Changing runtime state

Open orientalperil opened this issue 14 years ago • 10 comments

Why is it that when I assign variables in the shell, these assignments are not reflected in the running programme? When I use pdb, I am able to freely change the values of variables and execute the programme with my changes.

Is this ability omitted intentionally?

Is it possible to add?

orientalperil avatar Nov 29 '11 00:11 orientalperil

pudb and pdb use literally the same code to implement user commands/variable assignments. It turns out that this is fine (and works in pudb and pdb) within the global scope, where variables are kept in a dict, but it very nearly can't be done inside a function, where variables are kept in the VM stack.

If you know otherwise, please let me know.

inducer avatar Nov 29 '11 00:11 inducer

I see. It sounds like a hard problem.

orientalperil avatar Nov 29 '11 00:11 orientalperil

As of Python 3.6.6 this seems to be resolved in pdb, it can change local variables.

kgabor avatar Apr 08 '19 19:04 kgabor

Interesting. In that case, could you look into what pdb does to make that happen? We should be able to just steal what they do.

inducer avatar Apr 09 '19 14:04 inducer

I don't see any obvious changes to bdb.py or pdb.py related to this.

asmeurer avatar Apr 09 '19 17:04 asmeurer

@kgabor I can't reproduce this. I use this script to test, on Python 3.7.3rc1.

def f():
    i = 0

    while i < 10:
        i = i+1
        print(i)

f()

I use pdb to step into f until I'm in the middle of the loop, then say

(Pdb) s i = 20
> /home/andreas/tmp/zzz.py(5)f()
-> i = i+1
(Pdb) p i
1

which seems to contradict your statement.

inducer avatar Apr 26 '19 00:04 inducer

I think this should be re-opened as it works in pdb.

When I test the code from https://github.com/inducer/pudb/issues/26#issuecomment-486882575, I can modify i just fine:

$ python -m pdb zzz.py
> .../zzz.py(1)<module>()
-> def f():
(Pdb) n
> .../zzz.py(8)<module>()
-> f()
(Pdb) s
--Call--
> .../zzz.py(1)f()
-> def f():
(Pdb) n
> .../zzz.py(2)f()
-> i = 0
(Pdb) n
> .../zzz.py(4)f()
-> while i < 10:
(Pdb) n
> .../zzz.py(5)f()
-> i = i+1
(Pdb) n
-> print(i)
(Pdb) i
1
(Pdb) i = 20
(Pdb) i
20
(Pdb) n
20
> .../zzz.py(4)f()
-> while i < 10:

This is on Python 3.10.8.

disketten avatar Nov 15 '22 10:11 disketten

It looks like pdb achieves this by making a copy of f_locals https://github.com/python/cpython/blob/aa8b58cb33826bd2b1a1de631ebcd6a5353eecb5/Lib/pdb.py#L299. Otherwise, frame.f_locals recomputes the locals every time it is accessed, wiping any changes that were made to it.

asmeurer avatar Nov 16 '22 22:11 asmeurer

I have an in progress PR for a similar change for pudb to https://github.com/inducer/pudb/pull/571. It requires more testing, and also some cleaning up for the different shells.

asmeurer avatar Nov 16 '22 22:11 asmeurer