summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xLib/pdb.py21
-rw-r--r--Lib/test/test_pdb.py47
-rw-r--r--Misc/NEWS.d/next/Library/2023-10-09-19-09-32.gh-issue-65052.C2mRlo.rst1
3 files changed, 62 insertions, 7 deletions
diff --git a/Lib/pdb.py b/Lib/pdb.py
index 2cbd6f6..930cb91 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -431,8 +431,9 @@ class Pdb(bdb.Bdb, cmd.Cmd):
# fields are changed to be displayed
if newvalue is not oldvalue and newvalue != oldvalue:
displaying[expr] = newvalue
- self.message('display %s: %r [old: %r]' %
- (expr, newvalue, oldvalue))
+ self.message('display %s: %s [old: %s]' %
+ (expr, self._safe_repr(newvalue, expr),
+ self._safe_repr(oldvalue, expr)))
def _get_tb_and_exceptions(self, tb_or_exc):
"""
@@ -1460,7 +1461,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
for i in range(n):
name = co.co_varnames[i]
if name in dict:
- self.message('%s = %r' % (name, dict[name]))
+ self.message('%s = %s' % (name, self._safe_repr(dict[name], name)))
else:
self.message('%s = *** undefined ***' % (name,))
do_a = do_args
@@ -1474,7 +1475,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
self._print_invalid_arg(arg)
return
if '__return__' in self.curframe_locals:
- self.message(repr(self.curframe_locals['__return__']))
+ self.message(self._safe_repr(self.curframe_locals['__return__'], "retval"))
else:
self.error('Not yet returned!')
do_rv = do_retval
@@ -1509,6 +1510,12 @@ class Pdb(bdb.Bdb, cmd.Cmd):
except:
self._error_exc()
+ def _safe_repr(self, obj, expr):
+ try:
+ return repr(obj)
+ except Exception as e:
+ return _rstr(f"*** repr({expr}) failed: {self._format_exc(e)} ***")
+
def do_p(self, arg):
"""p expression
@@ -1688,8 +1695,8 @@ class Pdb(bdb.Bdb, cmd.Cmd):
if not arg:
if self.displaying:
self.message('Currently displaying:')
- for item in self.displaying.get(self.curframe, {}).items():
- self.message('%s: %r' % item)
+ for key, val in self.displaying.get(self.curframe, {}).items():
+ self.message('%s: %s' % (key, self._safe_repr(val, key)))
else:
self.message('No expression is being displayed')
else:
@@ -1698,7 +1705,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
else:
val = self._getval_except(arg)
self.displaying.setdefault(self.curframe, {})[arg] = val
- self.message('display %s: %r' % (arg, val))
+ self.message('display %s: %s' % (arg, self._safe_repr(val, arg)))
complete_display = _complete_expression
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index b1652e9..ff677ae 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -2350,6 +2350,53 @@ def test_pdb_ambiguous_statements():
(Pdb) continue
"""
+def test_pdb_issue_gh_65052():
+ """See GH-65052
+
+ args, retval and display should not crash if the object is not displayable
+ >>> class A:
+ ... def __new__(cls):
+ ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+ ... return object.__new__(cls)
+ ... def __init__(self):
+ ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+ ... self.a = 1
+ ... def __repr__(self):
+ ... return self.a
+
+ >>> def test_function():
+ ... A()
+ >>> with PdbTestInput([ # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+ ... 's',
+ ... 'retval',
+ ... 'continue',
+ ... 'args',
+ ... 'display self',
+ ... 'display',
+ ... 'continue',
+ ... ]):
+ ... test_function()
+ > <doctest test.test_pdb.test_pdb_issue_gh_65052[0]>(4)__new__()
+ -> return object.__new__(cls)
+ (Pdb) s
+ --Return--
+ > <doctest test.test_pdb.test_pdb_issue_gh_65052[0]>(4)__new__()-><A instance at ...>
+ -> return object.__new__(cls)
+ (Pdb) retval
+ *** repr(retval) failed: AttributeError: 'A' object has no attribute 'a' ***
+ (Pdb) continue
+ > <doctest test.test_pdb.test_pdb_issue_gh_65052[0]>(7)__init__()
+ -> self.a = 1
+ (Pdb) args
+ self = *** repr(self) failed: AttributeError: 'A' object has no attribute 'a' ***
+ (Pdb) display self
+ display self: *** repr(self) failed: AttributeError: 'A' object has no attribute 'a' ***
+ (Pdb) display
+ Currently displaying:
+ self: *** repr(self) failed: AttributeError: 'A' object has no attribute 'a' ***
+ (Pdb) continue
+ """
+
@support.requires_subprocess()
class PdbTestCase(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Library/2023-10-09-19-09-32.gh-issue-65052.C2mRlo.rst b/Misc/NEWS.d/next/Library/2023-10-09-19-09-32.gh-issue-65052.C2mRlo.rst
new file mode 100644
index 0000000..4739c63
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-10-09-19-09-32.gh-issue-65052.C2mRlo.rst
@@ -0,0 +1 @@
+Prevent :mod:`pdb` from crashing when trying to display undisplayable objects