Skip to content
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

Changing runtime state #26

Open
orientalperil opened this issue Nov 29, 2011 · 9 comments · May be fixed by #571
Open

Changing runtime state #26

orientalperil opened this issue Nov 29, 2011 · 9 comments · May be fixed by #571

Comments

@orientalperil
Copy link

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?

@inducer
Copy link
Owner

inducer commented Nov 29, 2011

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 inducer closed this as completed Nov 29, 2011
@orientalperil
Copy link
Author

I see. It sounds like a hard problem.

@kgabor
Copy link

kgabor commented Apr 8, 2019

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

@inducer inducer reopened this Apr 9, 2019
@inducer
Copy link
Owner

inducer commented Apr 9, 2019

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.

@asmeurer
Copy link
Collaborator

asmeurer commented Apr 9, 2019

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

@inducer
Copy link
Owner

inducer commented Apr 26, 2019

@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 inducer closed this as completed Apr 26, 2019
@disketten
Copy link

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

When I test the code from #26 (comment), 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.

@asmeurer
Copy link
Collaborator

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 asmeurer reopened this Nov 16, 2022
asmeurer added a commit to asmeurer/PuDB that referenced this issue Nov 16, 2022
This still requires more testing, especially for the different shells.

For the IPython shell, this requires not making a copy of locals(), but this
also causes the IPython shell to pollute the locals() namespace with all its
internal variables (like _0 and so on), so a better fix is needed.

Fixes inducer#26.
@asmeurer
Copy link
Collaborator

I have an in progress PR for a similar change for pudb to #571. It requires more testing, and also some cleaning up for the different shells.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants