-
-
Notifications
You must be signed in to change notification settings - Fork 32k
pdb fails to access variables closed over #70260
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
Comments
Consider the following example: def f(x=1):
def g():
y = 2
raise Exception
g()
f() $ python -mpdb -ccontinue example.py
<... traceback ...>
> /tmp/example.py(4)g()
-> raise Exception
(Pdb) p x
##### this can be worked around using "up"
*** NameError: name 'x' is not defined
(Pdb) p y
2
(Pdb) p (lambda: y)()
##### this is more awkward to work around, e.g. (lambda *, y=y: y)()
*** NameError: name 'y' is not defined Use case: I wan to pass a lambda to a numerical optimizer, but the optimizer fails using the default starting point. Within pdb, I'd like to pass a different starting point but the same lambda, to see whether this helps. |
Confirming. Another use case is the use any lambda, or function definition inside the scope of a function, for checking conditions in the REPL. Suppose two inner functions named condition1 and condition2, and a parameter X as a Collection: (Pdb) any(condition1(x) and condition2(x) for x in X) |
What Antony Lee mentioned are two different cases. The former is what PDB should behave because it is not reasonable to inspect a variable does not exist in the current frame. If you want to do so, you have to reference the variable The latter is same as what Jesús Gómez confirmed. It's a problem about creating correct closures in an interaction prompt of PDB. It can be found in almost every versions of Python. The following are several forms of the problem: # (1) raise exception 1 def f(): # (2) no exception, but get the wrong value 1 x = 100 # (3) similar to (1), but this one usually makes me upset if I forget the cause of the problem (Pdb) ll It's easy to alleviate the problem by using 1 def f():
2 -> import pdb; pdb.set_trace();
(Pdb) x = 5
(Pdb) interact
*interactive*
>>> [i for i in range(10) if (i % x) == 0]
[0, 5] Now the behavior looks right. However, the problem still exists for those PDB users don't know how to pass it, and it's quite inconvenient to start an interactive interpreter every time. Maybe it's worth to keep the behavior of PDB consistent and expectable just like the behavior inside interactive interpreter. I will try to send a patch to solve the problem in these days. Please stop me if it's inappropriate. |
Surrender. After digging into the implementation of how CPython handles closures, I am sure that it is impossible to solve this problem now correctly. What I can do is create a patch to let Pdb print enough information when the problem occurs. It would look like: (Pdb) ll
*** NameError: name 'x' is not defined I believe it would be helpful and less annoyed for those who encounters this problem. Call for maintainers review, please. PS.
|
Call for review again. Maybe xdegaye would like to take a look? |
It seems that the last patch in bpo-21161 fixes all the problems described here, msg 149096 explains why. Can you confirm that this is a duplicate of bpo-21161. |
The last patch in bpo-21161 fixes some problems but also brings up critical issues: (Pdb) list . I think that we should not copy local variables to globals() while doing execution. It will always bring out the wrong result of So, the patch I proposed here is focused on "Showing Friendly Error Message" to let the users be less confused. # The patch works when a user tries to bound a free variable to a list comprehension. It will show the proper error message, too. |
This patch fixes the problems raised in this issue and allows accessing the globals at the Pdb prompt with the globals() dictionary: (Pdb) list |
Your solution is quite neat. 1 y = 2 |
Hey xdegaye, have you confirmed it? |
Fixed by #111094 |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: