From f42c2adc5f2b7c2653cdfcb10afa5aa126675cf4 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 25 Jan 2020 13:30:57 +0100 Subject: [PATCH 1/4] pdb: do not swallow exceptions from `repr` with `do_p`/`do_pp` Fixes https://bugs.python.org/issue37022. --- Lib/pdb.py | 21 +++++++++++++-------- Lib/test/test_pdb.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index bf503f1e73ee14..62112c4ef81916 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1176,23 +1176,28 @@ def _getval_except(self, arg, frame=None): err = traceback.format_exception_only(*exc_info)[-1].strip() return _rstr('** raised %s **' % err) + def _msg_val_func(self, arg, func): + try: + val = self._getval(arg) + except: + return + try: + self.message(func(val)) + except: + exc_info = sys.exc_info()[:2] + self.error(traceback.format_exception_only(*exc_info)[-1].strip()) + def do_p(self, arg): """p expression Print the value of the expression. """ - try: - self.message(repr(self._getval(arg))) - except: - pass + self._msg_val_func(arg, repr) def do_pp(self, arg): """pp expression Pretty-print the value of the expression. """ - try: - self.message(pprint.pformat(self._getval(arg))) - except: - pass + self._msg_val_func(arg, pprint.pformat) complete_print = _complete_expression complete_p = _complete_expression diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index fcb7e4e6072cb6..989bd9492845f0 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -323,6 +323,34 @@ def test_pdb_breakpoint_commands(): """ +def test_pdb_pp_repr_exc(): + """Test that do_p/do_pp do not swallow exceptions. + + >>> class BadRepr: + ... def __repr__(self): + ... raise Exception('repr_exc') + >>> obj = BadRepr() + + >>> def test_function(): + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... 'p obj', + ... 'pp obj', + ... 'continue', + ... ]): + ... test_function() + --Return-- + > (2)test_function()->None + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) p obj + *** Exception: repr_exc + (Pdb) pp obj + *** Exception: repr_exc + (Pdb) continue + """ + + def do_nothing(): pass From 58f525a216e651f1e17a18d31f190db727ed3de5 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 25 Jan 2020 13:52:07 +0100 Subject: [PATCH 2/4] Factor out _error_exc Ref: https://bugs.python.org/msg343395 --- Lib/pdb.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index 62112c4ef81916..dc25f09d70f92e 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -383,8 +383,7 @@ def default(self, line): sys.stdin = save_stdin sys.displayhook = save_displayhook except: - exc_info = sys.exc_info()[:2] - self.error(traceback.format_exception_only(*exc_info)[-1].strip()) + self._error_exc() def precmd(self, line): """Handle alias expansion and ';;' separator.""" @@ -1102,8 +1101,7 @@ def do_debug(self, arg): try: sys.call_tracing(p.run, (arg, globals, locals)) except Exception: - exc_info = sys.exc_info()[:2] - self.error(traceback.format_exception_only(*exc_info)[-1].strip()) + self._error_exc() self.message("LEAVING RECURSIVE DEBUGGER") sys.settrace(self.trace_dispatch) self.lastcmd = p.lastcmd @@ -1161,8 +1159,7 @@ def _getval(self, arg): try: return eval(arg, self.curframe.f_globals, self.curframe_locals) except: - exc_info = sys.exc_info()[:2] - self.error(traceback.format_exception_only(*exc_info)[-1].strip()) + self._error_exc() raise def _getval_except(self, arg, frame=None): @@ -1176,6 +1173,10 @@ def _getval_except(self, arg, frame=None): err = traceback.format_exception_only(*exc_info)[-1].strip() return _rstr('** raised %s **' % err) + def _error_exc(self): + exc_info = sys.exc_info()[:2] + self.error(traceback.format_exception_only(*exc_info)[-1].strip()) + def _msg_val_func(self, arg, func): try: val = self._getval(arg) @@ -1184,8 +1185,7 @@ def _msg_val_func(self, arg, func): try: self.message(func(val)) except: - exc_info = sys.exc_info()[:2] - self.error(traceback.format_exception_only(*exc_info)[-1].strip()) + self._error_exc() def do_p(self, arg): """p expression From a0809c7a6ae7acc5add909f8d955c28b39f33007 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sat, 25 Jan 2020 12:58:23 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2020-01-25-12-58-20.bpo-37022.FUZI25.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2020-01-25-12-58-20.bpo-37022.FUZI25.rst diff --git a/Misc/NEWS.d/next/Library/2020-01-25-12-58-20.bpo-37022.FUZI25.rst b/Misc/NEWS.d/next/Library/2020-01-25-12-58-20.bpo-37022.FUZI25.rst new file mode 100644 index 00000000000000..7b923b3aa6e444 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-01-25-12-58-20.bpo-37022.FUZI25.rst @@ -0,0 +1 @@ +:mod:`pdb` now displays exceptions from ``repr()`` with its ``p`` and ``pp`` commands. \ No newline at end of file From 084d10b4619e53603d3c106a7a38db2c2627db7d Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Thu, 10 Jun 2021 16:11:54 +0100 Subject: [PATCH 4/4] Add a comment --- Lib/pdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index dc25f09d70f92e..b33b332a728af8 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1181,7 +1181,7 @@ def _msg_val_func(self, arg, func): try: val = self._getval(arg) except: - return + return # _getval() has displayed the error try: self.message(func(val)) except: