pudb icon indicating copy to clipboard operation
pudb copied to clipboard

n doesn't step out of generator expressions

Open asmeurer opened this issue 9 years ago • 5 comments

Say you have

if all(i == j for i, j in zip(range(10), range(10))):
    print("yes")

and you step into the first line, so that you are inside the generator expression. Then press n ten times. After you reach the final iteration, the script will continue. What should happen is that it moves to the print("yes") line.

asmeurer avatar Jun 03 '15 20:06 asmeurer

Yeah, I've bumped into this issue many times. I believe what makes this complicated is, what if you have:

def some_generator():
    for i in range(10):
        yield i

if all(i == j for i, j in zip(range(10), some_generator())):
    print("yes")

In this case, instead of going to the print("yes") line, one would expect it to step into some_generator function.

eliasdorneles avatar Jun 13 '16 00:06 eliasdorneles

What does pdb do in these situations? (I'm asking because I'd assume we inherit most of this behavior from pdb via the bdb built-in modules, and thus in a sense, that might be the more suitable spot to report these bugs--if they're indeed in pdb, too.)

inducer avatar Jun 13 '16 01:06 inducer

Just tried it with pdb with both snippets, and it has the same weird behavior of having to iterate several times for the whole all line.

While trying the second snippet with pudb though, I think I've run into another issue: it does step into the some_generator function but when the generation is done (StopIteration) I end up in what seems like an infinite loop inside some urwid code -- screenshot running with the default settings:

elias traveller -home-elias_2016-06-12_23 12 56

In the console output, it shows:

Exception KeyError: (<weakref at 0x7fef3fdf4cb0; dead>,) in <bound method type.cleanup of <class 'urwid.canvas.CanvasCache'>> ignored

Are you able to reproduce? Should I create a separate issue?

eliasdorneles avatar Jun 13 '16 02:06 eliasdorneles

Just providing another simpler snippet, plus some extra information on this one.

#!/usr/bin/ipython3
# -*- coding: utf-8 -*-

from typing import Generator


def fib() -> Generator[int, None, None]:
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b


fib_gen = fib()
for _ in range(10):
    next(fib_gen)

pudb3 steps into next(fib_gen) just fine, but once it it's inside, it cycles the last two lines of the generator until the whole program is done. Interestingly, spyder3's pdb front-end behaves correctly on this, stepping in and out appropriately.

BehindTheBrain avatar Sep 25 '20 02:09 BehindTheBrain

Thanks for following up. Maybe we can just steal spyder's approach given that it seems to allow stepping in and out of generators even when pdb does not. Here is where that code seems to live. An interesting thing I noticed is that it seems to be based on IPython's ipyPdb.

inducer avatar Sep 25 '20 21:09 inducer