4

I am trying to view the result of a list comprehension call using Python's debugging module, pdb. However the pdb "environment" is simultaneously claiming that a variable is and is not defined, resulting in a NameError for a variable which pdb agrees is defined. The following is a minimal code example to duplicate the issue:

import pdb
        
def main():
    bar = [0, 0, 1, 1]
    foo(bar)
        
def foo(bar):
    pdb.set_trace()

    ### pdb COMMANDS LISTED BELOW ARE CALLED HERE ###

    print([False if bar[i] == 0 else True for i in range(len(bar))])
        
main()

Running the following pdb commands at the point of code execution indicated above leads to the following results.

(Pdb) p bar
[0, 0, 1, 1]
(Pdb) p [False if bar[i] == 0 else True for i in range(len(bar))]
*** NameError: name 'bar' is not defined
(Pdb) !print([False if bar[i] == 0 else True for i in range(len(bar))])
*** NameError: name 'bar' is not defined
(Pdb) n
[False, False, True, True]

Furthermore, running the code without the pdb module yields the expected result. Changing the location of the pdb.set_trace() method call to the main function has no impact on the result. What do I need to do in order to debug this list comprehension call?

3
  • Is the goal here to achieve a deep understanding of pdb or to be able to debug within a list comprehension? Commented Aug 19, 2020 at 20:39
  • The goal is to be able to debug within a list comprehension. Commented Aug 19, 2020 at 20:39
  • VSCode using either debugpy or pdb will handle these cases for you. I suspect you're running into a closure issue here -- one that most IDEs will account for at the moment. Is that a viable solution for you? Commented Aug 19, 2020 at 20:43

1 Answer 1

5

You've stumbled upon a bug in pdb! pdb's print command is not a full-blown interactive interpreter, and can struggle finding variables that intuitively should be easy to find, but aren't because of the underlying CPython implementation. In particular, it often fails to do so in closures and list comprehensions. Here's a bug report.

The bug report does mention a workaround though. Type interact, and you'll get a full blown interactive python shell in which you should be able to evaluate your list comprehension:

-> print([False if bar[i] == 0 else True for i in range(len(bar))])
(Pdb) p [False if bar[i] == 0 else True for i in range(len(bar))]
*** NameError: name 'bar' is not defined
(Pdb) interact
*interactive*
>>> [False if bar[i] == 0 else True for i in range(len(bar))]
[False, False, True, True]
>>>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.