This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author blueyed
Recipients blueyed
Date 2020-01-06.04:14:24
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1578284065.37.0.657086816746.issue39228@roundup.psfhosted.org>
In-reply-to
Content
Exceptions within `__repr__` methods of captured locals
(e.g. via the `capture_locals` argument of `TracebackException`) are not handled:

```
import traceback


class CrashingRepr:
    def __repr__(self):
        raise RuntimeError("crash")


traceback.FrameSummary("fname", 1, "name", locals={"crash": CrashingRepr()})
```

Result:
```
Traceback (most recent call last):
  File "test_framesummary_repr.py", line 9, in <module>
    traceback.FrameSummary("fname", 1, "name", locals={"crash": CrashingRepr()})
  File "…/pyenv/3.8.0/lib/python3.8/traceback.py", line 260, in __init__
    self.locals = {k: repr(v) for k, v in locals.items()} if locals else None
  File "…/pyenv/3.8.0/lib/python3.8/traceback.py", line 260, in <dictcomp>
    self.locals = {k: repr(v) for k, v in locals.items()} if locals else None
  File "test_framesummary_repr.py", line 6, in __repr__
    raise RuntimeError("crash")
RuntimeError: crash
```

The following patch would fix this:

```diff
diff --git i/Lib/traceback.py w/Lib/traceback.py
index 7a4c8e19f9..eed7082db4 100644
--- i/Lib/traceback.py
+++ w/Lib/traceback.py
 class FrameSummary:
     """A single frame from a traceback.

@@ -257,7 +265,17 @@ 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
+        if locals:
+            self.locals = {}
+            for k, v in locals.items():
+                try:
+                    self.locals[k] = repr(v)
+                except (KeyboardInterrupt, SystemExit):
+                    raise
+                except BaseException as exc:
+                    self.locals[k] = f"<unrepresentable repr ({exc})>"
+        else:
+            self.locals = None

     def __eq__(self, other):
         if isinstance(other, FrameSummary):

```
History
Date User Action Args
2020-01-06 04:14:25blueyedsetrecipients: + blueyed
2020-01-06 04:14:25blueyedsetmessageid: <1578284065.37.0.657086816746.issue39228@roundup.psfhosted.org>
2020-01-06 04:14:25blueyedlinkissue39228 messages
2020-01-06 04:14:24blueyedcreate