Search code examples
pythongeneratoripdb

Convert generator object to list for debugging


When I'm debugging in Python using IPython, I sometimes hit a break-point and I want to examine a variable that is currently a generator. The simplest way I can think of doing this is converting it to a list, but I'm not clear on what's an easy way of doing this in one line in ipdb, since I'm so new to Python.


Solution

  • Simply call list on the generator.

    lst = list(gen)
    lst
    

    Be aware that this affects the generator which will not return any further items.

    You also cannot directly call list in IPython, as it conflicts with a command for listing lines of code.

    Tested on this file:

    def gen():
        yield 1
        yield 2
        yield 3
        yield 4
        yield 5
    import ipdb
    ipdb.set_trace()
    
    g1 = gen()
    
    text = "aha" + "bebe"
    
    mylst = range(10, 20)
    

    which when run:

    $ python code.py 
    > /home/javl/sandbox/so/debug/code.py(10)<module>()
          9 
    ---> 10 g1 = gen()
         11 
    
    ipdb> n
    > /home/javl/sandbox/so/debug/code.py(12)<module>()
         11 
    ---> 12 text = "aha" + "bebe"
         13 
    
    ipdb> lst = list(g1)
    ipdb> lst
    [1, 2, 3, 4, 5]
    ipdb> q
    Exiting Debugger.
    

    General method for escaping function/variable/debugger name conflicts

    There are debugger commands p and pp that will print and prettyprint any expression following them.

    So you could use it as follows:

    $ python code.py 
    > /home/javl/sandbox/so/debug/code.py(10)<module>()
          9 
    ---> 10 g1 = gen()
         11 
    
    ipdb> n
    > /home/javl/sandbox/so/debug/code.py(12)<module>()
         11 
    ---> 12 text = "aha" + "bebe"
         13 
    
    ipdb> p list(g1)
    [1, 2, 3, 4, 5]
    ipdb> c
    

    There is also an exec command, called by prefixing your expression with !, which forces debugger to take your expression as Python one.

    ipdb> !list(g1)
    []
    

    For more details see help p, help pp and help exec when in debugger.

    ipdb> help exec
    (!) statement
    Execute the (one-line) statement in the context of
    the current stack frame.
    The exclamation point can be omitted unless the first word
    of the statement resembles a debugger command.
    To assign to a global variable you must always prefix the
    command with a 'global' command, e.g.:
    (Pdb) global list_options; list_options = ['-l']