[Python-checkins] gh-87822: Make traceback module robust to exceptions from repr() of local values (GH-94691)
iritkatriel
webhook-mailer at python.org
Mon Jul 11 05:14:58 EDT 2022
https://github.com/python/cpython/commit/46fc584b00f2ccee5b77d8fc525881def8670a02
commit: 46fc584b00f2ccee5b77d8fc525881def8670a02
branch: main
author: Simon-Martin Schröder <martin.schroeder at nerdluecht.de>
committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com>
date: 2022年07月11日T10:14:15+01:00
summary:
gh-87822: Make traceback module robust to exceptions from repr() of local values (GH-94691)
files:
A Misc/NEWS.d/next/Library/2022-07-08-17-49-12.gh-issue-87822.F9dzkf.rst
M Doc/library/traceback.rst
M Lib/test/test_traceback.py
M Lib/traceback.py
M Misc/ACKS
diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst
index a8412cc93d16f..8cb6af9bc840b 100644
--- a/Doc/library/traceback.rst
+++ b/Doc/library/traceback.rst
@@ -341,6 +341,10 @@ capture data for later printing in a lightweight fashion.
local variables in each :class:`FrameSummary` are captured as object
representations.
+ .. versionchanged:: 3.12
+ Exceptions raised from :func:`repr` on a local variable (when
+ *capture_locals* is ``True``) are no longer propagated to the caller.
+
.. classmethod:: from_list(a_list)
Construct a :class:`StackSummary` object from a supplied list of
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index f4161fbf0178d..602bd2cae0a96 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -2279,6 +2279,9 @@ def format_frame_summary(self, frame_summary):
f' File "{__file__}", line {lno}, in f\n 1/0\n'
)
+class Unrepresentable:
+ def __repr__(self) -> str:
+ raise Exception("Unrepresentable")
class TestTracebackException(unittest.TestCase):
@@ -2546,12 +2549,13 @@ def test_locals(self):
linecache.updatecache('/foo.py', globals())
e = Exception("uh oh")
c = test_code('/foo.py', 'method')
- f = test_frame(c, globals(), {'something': 1, 'other': 'string'})
+ f = test_frame(c, globals(), {'something': 1, 'other': 'string', 'unrepresentable': Unrepresentable()})
tb = test_tb(f, 6, None, 0)
exc = traceback.TracebackException(
Exception, e, tb, capture_locals=True)
self.assertEqual(
- exc.stack[0].locals, {'something': '1', 'other': "'string'"})
+ exc.stack[0].locals,
+ {'something': '1', 'other': "'string'", 'unrepresentable': '<local repr() failed>'})
def test_no_locals(self):
linecache.updatecache('/foo.py', globals())
diff --git a/Lib/traceback.py b/Lib/traceback.py
index 55f8080044053..b1a5fd0a26d40 100644
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -279,7 +279,8 @@ def __init__(self, filename, lineno, name, *, lookup_line=True,
self._line = line
if lookup_line:
self.line
- self.locals = {k: repr(v) for k, v in locals.items()} if locals else None
+ self.locals = {k: _safe_string(v, 'local', func=repr)
+ for k, v in locals.items()} if locals else None
self.end_lineno = end_lineno
self.colno = colno
self.end_colno = end_colno
diff --git a/Misc/ACKS b/Misc/ACKS
index b6340414cf701..32475f874c36d 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1590,6 +1590,7 @@ Ed Schouten
Scott Schram
Robin Schreiber
Chad J. Schroeder
+Simon-Martin Schroeder
Christian Schubert
Sam Schulenburg
Andreas Schwab
diff --git a/Misc/NEWS.d/next/Library/2022-07-08-17-49-12.gh-issue-87822.F9dzkf.rst b/Misc/NEWS.d/next/Library/2022-07-08-17-49-12.gh-issue-87822.F9dzkf.rst
new file mode 100644
index 0000000000000..7b27f5df45ba2
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-07-08-17-49-12.gh-issue-87822.F9dzkf.rst
@@ -0,0 +1 @@
+When called with ``capture_locals=True``, the :mod:`traceback` module functions swallow exceptions raised from calls to ``repr()`` on local variables of frames. This is in order to prioritize the original exception over rendering errors. An indication of the failure is printed in place of the missing value. (Patch by Simon-Martin Schroeder).
More information about the Python-checkins
mailing list