8000 bpo-20853: fixed PDB's args and retval commands to handle objects with broken repr() by akulakov · Pull Request #28400 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-20853: fixed PDB's args and retval commands to handle objects with broken repr() #28400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

8000
Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Doc/library/pdb.rst
8000
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,9 @@ can be overridden by the local file.

.. pdbcommand:: retval

Print the return value for the last return of a function.
Print the return value for the last return of a function. This command must
be used immediately after the return line is executed; *return* command can
be used to jump to the location where *retval* can be used.

.. rubric:: Footnotes

Expand Down
12 changes: 10 additions & 2 deletions Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,12 @@ def do_args(self, arg):
for i in range(n):
name = co.co_varnames[i]
if name in dict:
self.message('%s = %r' % (name, dict[name]))
try:
r = dict[name]
repr(r)
except Exception as e:
r = e
self.message('%s = %r' % (name, r))
else:
self.message('%s = *** undefined ***' % (name,))
do_a = do_args
Expand All @@ -1240,7 +1245,10 @@ def do_retval(self, arg):
Print the return value for the last return of a function.
"""
if '__return__' in self.curframe_locals:
self.message(repr(self.curframe_locals['__return__']))
try:
self.message(repr(self.curframe_locals['__return__']))
except:
self._error_exc()
else:
self.error('Not yet returned!')
do_rv = do_retval
Expand Down
36 changes: 36 additions & 0 deletions Lib/test/test_pdb.py
8000
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,42 @@ def test_pdb_pp_repr_exc():
(Pdb) continue
"""

def test_pdb_bad_repr():
# Note that return of test_function() needs to be assigned to a value;
# otherwise doctest tries to run repr() on it and fails.
"""Test that args/retval commands handle bad repr objects.

>>> class BadRepr:
... def __repr__(self):
... raise AttributeError("'BadRepr' object has no attribute 'foo'")
... def __str__(self):
... return '<BadRepr>'
>>> obj = BadRepr()

>>> def test_function(x):
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
... return x

>>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS
... 'args',
... 'return',
... 'retval',
... 'continue',
... ]):
... x = test_function(obj)
> <doctest test.test_pdb.test_pdb_bad_repr[2]>(3)test_function()
-> return x
(Pdb) args
x = AttributeError("'BadRepr' object has no attribute 'foo'")
(Pdb) return
--Return--
> <doctest test.test_pdb.test_pdb_bad_repr[2]>(3)test_function()...
-> return x
(Pdb) retval
*** AttributeError: 'BadRepr' object has no attribute 'foo'
(Pdb) continue
"""


def do_nothing():
pass
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
In :mod:`pdb`, *args* and *retval* commands were fixed to properly handle
objects for which :func:`repr` raises an exception.
0