@@ -37,6 +37,8 @@ def __init__(self, skip=None):
3737 self .frame_returning = None
3838 self .trace_opcodes = False
3939 self .enterframe = None
40+ self .cmdframe = None
41+ self .cmdlineno = None
4042
4143 self ._load_breaks ()
4244
@@ -124,7 +126,12 @@ def dispatch_line(self, frame):
124126 self.user_line(). Raise BdbQuit if self.quitting is set.
125127 Return self.trace_dispatch to continue tracing in this scope.
126128 """
127- if self .stop_here (frame ) or self .break_here (frame ):
129+ # GH-136057
130+ # For line events, we don't want to stop at the same line where
131+ # the latest next/step command was issued.
132+ if (self .stop_here (frame ) or self .break_here (frame )) and not (
133+ self .cmdframe == frame and self .cmdlineno == frame .f_lineno
134+ ):
128135 self .user_line (frame )
129136 if self .quitting : raise BdbQuit
130137 return self .trace_dispatch
@@ -316,7 +323,8 @@ def _set_trace_opcodes(self, trace_opcodes):
316323 break
317324 frame = frame .f_back
318325
319- def _set_stopinfo (self , stopframe , returnframe , stoplineno = 0 , opcode = False ):
326+ def _set_stopinfo (self , stopframe , returnframe , stoplineno = 0 , opcode = False ,
327+ cmdframe = None , cmdlineno = None ):
320328 """Set the attributes for stopping.
321329
322330 If stoplineno is greater than or equal to 0, then stop at line
@@ -329,6 +337,10 @@ def _set_stopinfo(self, stopframe, returnframe, stoplineno=0, opcode=False):
329337 # stoplineno >= 0 means: stop at line >= the stoplineno
330338 # stoplineno -1 means: don't stop at all
331339 self .stoplineno = stoplineno
340+ # cmdframe/cmdlineno is the frame/line number when the user issued
341+ # step/next commands.
342+ self .cmdframe = cmdframe
343+ self .cmdlineno = cmdlineno
332344 self ._set_trace_opcodes (opcode )
333345
334346 def _set_caller_tracefunc (self , current_frame ):
@@ -354,15 +366,17 @@ def set_until(self, frame, lineno=None):
354366
355367 def set_step (self ):
356368 """Stop after one line of code."""
357- self ._set_stopinfo (None , None )
369+ # set_step() could be called from signal handler so enterframe might be None
370+ self ._set_stopinfo (None , None , cmdframe = self .enterframe ,
371+ cmdlineno = getattr (self .enterframe , 'f_lineno' , None ))
358372
359373 def set_stepinstr (self ):
360374 """Stop before the next instruction."""
361375 self ._set_stopinfo (None , None , opcode = True )
362376
363377 def set_next (self , frame ):
364378 """Stop on the next line in or below the given frame."""
365- self ._set_stopinfo (frame , None )
379+ self ._set_stopinfo (frame , None , cmdframe = frame , cmdlineno = frame . f_lineno )
366380
367381 def set_return (self , frame ):
368382 """Stop when returning from the given frame."""
0 commit comments