diff options
-rw-r--r-- | Lib/test/test_traceback.py | 20 | ||||
-rw-r--r-- | Lib/traceback.py | 9 | ||||
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Python/pythonrun.c | 2 |
4 files changed, 30 insertions, 5 deletions
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 2145710..17413db 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -253,6 +253,26 @@ class BaseExceptionReportingTests: self.check_zero_div(blocks[0]) self.assertTrue('inner_raise() # Marker' in blocks[2]) + def test_cause_and_context(self): + # When both a cause and a context are set, only the cause should be + # displayed and the context should be muted. + def inner_raise(): + try: + self.zero_div() + except ZeroDivisionError as _e: + e = _e + try: + xyzzy + except NameError: + raise KeyError from e + def outer_raise(): + inner_raise() # Marker + blocks = boundaries.split(self.get_report(outer_raise)) + self.assertEquals(len(blocks), 3) + self.assertEquals(blocks[1], cause_message) + self.check_zero_div(blocks[0]) + self.assert_('inner_raise() # Marker' in blocks[2]) + def test_cause_recursive(self): def inner_raise(): try: diff --git a/Lib/traceback.py b/Lib/traceback.py index c0d8061..8d4e96e 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -120,13 +120,14 @@ def _iter_chain(exc, custom_tb=None, seen=None): seen.add(exc) its = [] cause = exc.__cause__ - context = exc.__context__ if cause is not None and cause not in seen: its.append(_iter_chain(cause, None, seen)) its.append([(_cause_message, None)]) - if context is not None and context is not cause and context not in seen: - its.append(_iter_chain(context, None, seen)) - its.append([(_context_message, None)]) + else: + context = exc.__context__ + if context is not None and context not in seen: + its.append(_iter_chain(context, None, seen)) + its.append([(_context_message, None)]) its.append([(exc, custom_tb or exc.__traceback__)]) # itertools.chain is in an extension module and may be unavailable for it in its: @@ -140,6 +140,10 @@ C-API Library ------- +- Issue #4486: When an exception has an explicit cause, do not print its + implicit context too. This affects the `traceback` module as well as + built-in exception printing. + - Issue #1515: Enable use of deepcopy() with instance methods. Patch by Robert Collins. diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 875e44e..3764740 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1576,7 +1576,7 @@ print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen) cause_message, f); } } - if (context) { + else if (context) { res = PySet_Contains(seen, context); if (res == -1) PyErr_Clear(); |