diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index 47a11ed0227..9a333494cd3 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -210,11 +210,13 @@ w(here) Print a stack trace, with the most recent frame at the bottom. An arrow indicates the current frame, which determines the context of most commands. -d(own) - Move the current frame one level down in the stack trace (to a newer frame). +d(own) [*count*] + Move the current frame *count* (default one) levels down in the stack trace + (to a newer frame). -u(p) - Move the current frame one level up in the stack trace (to an older frame). +u(p) [*count*] + Move the current frame *count* (default one) levels up in the stack trace + (to an older frame). b(reak) [[*filename*:]\ *lineno* | *function*\ [, *condition*]] With a *lineno* argument, set a break there in the current file. With a diff --git a/Lib/pdb.doc b/Lib/pdb.doc index 0d32800ff6c..e509f7da655 100644 --- a/Lib/pdb.doc +++ b/Lib/pdb.doc @@ -68,13 +68,13 @@ w(here) An arrow indicates the "current frame", which determines the context of most commands. -d(own) - Move the current frame one level down in the stack trace - (to a newer frame). +d(own) [ count ] + Move the current frame count (default one) levels down in the + stack trace (to a newer frame). -u(p) - Move the current frame one level up in the stack trace - (to an older frame). +u(p) [ count ] + Move the current frame count (default one) levels up in the + stack trace (to an older frame). b(reak) [ ([filename:]lineno | function) [, condition] ] With a filename:line number argument, set a break there. If diff --git a/Lib/pdb.py b/Lib/pdb.py index b15a3d16004..43520d6b01d 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -618,26 +618,44 @@ class Pdb(bdb.Bdb, cmd.Cmd): do_w = do_where do_bt = do_where + def _select_frame(self, number): + assert 0 <= number < len(self.stack) + self.curindex = number + self.curframe = self.stack[self.curindex][0] + self.curframe_locals = self.curframe.f_locals + self.print_stack_entry(self.stack[self.curindex]) + self.lineno = None + def do_up(self, arg): if self.curindex == 0: print('*** Oldest frame', file=self.stdout) + return + try: + count = int(arg or 1) + except ValueError: + print('*** Invalid frame count (%s)' % arg, file=self.stdout) + return + if count < 0: + newframe = 0 else: - self.curindex = self.curindex - 1 - self.curframe = self.stack[self.curindex][0] - self.curframe_locals = self.curframe.f_locals - self.print_stack_entry(self.stack[self.curindex]) - self.lineno = None + newframe = max(0, self.curindex - count) + self._select_frame(newframe) do_u = do_up def do_down(self, arg): if self.curindex + 1 == len(self.stack): print('*** Newest frame', file=self.stdout) + return + try: + count = int(arg or 1) + except ValueError: + print('*** Invalid frame count (%s)' % arg, file=self.stdout) + return + if count < 0: + newframe = len(self.stack) - 1 else: - self.curindex = self.curindex + 1 - self.curframe = self.stack[self.curindex][0] - self.curframe_locals = self.curframe.f_locals - self.print_stack_entry(self.stack[self.curindex]) - self.lineno = None + newframe = min(len(self.stack) - 1, self.curindex + count) + self._select_frame(newframe) do_d = do_down def do_until(self, arg): diff --git a/Misc/NEWS b/Misc/NEWS index a9b19dc20db..1cb8c43343b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -456,6 +456,8 @@ C-API Library ------- +- Issue #9064: pdb's "up" and "down" commands now accept an optional argument. + - Issue #9018: os.path.normcase() now raises a TypeError if the argument is not ``str`` or ``bytes``.