| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3413,6 +3413,19 @@ class Unrepresentable: | |||
| 3413 | 3413 | def __repr__(self) -> str: | |
| 3414 | 3414 | raise Exception("Unrepresentable") | |
| 3415 | 3415 | ||
| 3416 | + | ||
| 3417 | + # Used in test_dont_swallow_cause_or_context_of_falsey_exception and | ||
| 3418 | + # test_dont_swallow_subexceptions_of_falsey_exceptiongroup. | ||
| 3419 | + class FalseyException(Exception): | ||
| 3420 | + def __bool__(self): | ||
| 3421 | + return False | ||
| 3422 | + | ||
| 3423 | + | ||
| 3424 | + class FalseyExceptionGroup(ExceptionGroup): | ||
| 3425 | + def __bool__(self): | ||
| 3426 | + return False | ||
| 3427 | + | ||
| 3428 | + | ||
| 3416 | 3429 | class TestTracebackException(unittest.TestCase): | |
| 3417 | 3430 | def do_test_smoke(self, exc, expected_type_str): | |
| 3418 | 3431 | try: | |
@@ -3759,6 +3772,24 @@ def f(): | |||
| 3759 | 3772 | 'ZeroDivisionError: division by zero', | |
| 3760 | 3773 | '']) | |
| 3761 | 3774 | ||
| 3775 | + def test_dont_swallow_cause_or_context_of_falsey_exception(self): | ||
| 3776 | + # see gh-132308: Ensure that __cause__ or __context__ attributes of exceptions | ||
| 3777 | + # that evaluate as falsey are included in the output. For falsey term, | ||
| 3778 | + # see https://docs.python.org/3/library/stdtypes.html#truth-value-testing. | ||
| 3779 | + | ||
| 3780 | + try: | ||
| 3781 | + raise FalseyException from KeyError | ||
| 3782 | + except FalseyException as e: | ||
| 3783 | + self.assertIn(cause_message, traceback.format_exception(e)) | ||
| 3784 | + | ||
| 3785 | + try: | ||
| 3786 | + try: | ||
| 3787 | + 1/0 | ||
| 3788 | + except ZeroDivisionError: | ||
| 3789 | + raise FalseyException | ||
| 3790 | + except FalseyException as e: | ||
| 3791 | + self.assertIn(context_message, traceback.format_exception(e)) | ||
| 3792 | + | ||
| 3762 | 3793 | ||
| 3763 | 3794 | class TestTracebackException_ExceptionGroups(unittest.TestCase): | |
| 3764 | 3795 | def setUp(self): | |
@@ -3960,6 +3991,26 @@ def test_comparison(self): | |||
| 3960 | 3991 | self.assertNotEqual(exc, object()) | |
| 3961 | 3992 | self.assertEqual(exc, ALWAYS_EQ) | |
| 3962 | 3993 | ||
| 3994 | + def test_dont_swallow_subexceptions_of_falsey_exceptiongroup(self): | ||
| 3995 | + # see gh-132308: Ensure that subexceptions of exception groups | ||
| 3996 | + # that evaluate as falsey are displayed in the output. For falsey term, | ||
| 3997 | + # see https://docs.python.org/3/library/stdtypes.html#truth-value-testing. | ||
| 3998 | + | ||
| 3999 | + try: | ||
| 4000 | + raise FalseyExceptionGroup("Gih", (KeyError(), NameError())) | ||
| 4001 | + except Exception as ee: | ||
| 4002 | + str_exc = ''.join(traceback.format_exception(ee)) | ||
| 4003 | + self.assertIn('+---------------- 1 ----------------', str_exc) | ||
| 4004 | + self.assertIn('+---------------- 2 ----------------', str_exc) | ||
| 4005 | + | ||
| 4006 | + # Test with a falsey exception, in last position, as sub-exceptions. | ||
| 4007 | + msg = 'bool' | ||
| 4008 | + try: | ||
| 4009 | + raise FalseyExceptionGroup("Gah", (KeyError(), FalseyException(msg))) | ||
| 4010 | + except Exception as ee: | ||
| 4011 | + str_exc = traceback.format_exception(ee) | ||
| 4012 | + self.assertIn(f'{FalseyException.__name__}: {msg}', str_exc[-2]) | ||
| 4013 | + | ||
| 3963 | 4014 | ||
| 3964 | 4015 | global_for_suggestions = None | |
| 3965 | 4016 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1120,7 +1120,7 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, | |||
| 1120 | 1120 | queue = [(self, exc_value)] | |
| 1121 | 1121 | while queue: | |
| 1122 | 1122 | te, e = queue.pop() | |
| 1123 | - if (e and e.__cause__ is not None | ||
| 1123 | + if (e is not None and e.__cause__ is not None | ||
| 1124 | 1124 | and id(e.__cause__) not in _seen): | |
| 1125 | 1125 | cause = TracebackException( | |
| 1126 | 1126 | type(e.__cause__), | |
@@ -1141,7 +1141,7 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, | |||
| 1141 | 1141 | not e.__suppress_context__) | |
| 1142 | 1142 | else: | |
| 1143 | 1143 | need_context = True | |
| 1144 | - if (e and e.__context__ is not None | ||
| 1144 | + if (e is not None and e.__context__ is not None | ||
| 1145 | 1145 | and need_context and id(e.__context__) not in _seen): | |
| 1146 | 1146 | context = TracebackException( | |
| 1147 | 1147 | type(e.__context__), | |
@@ -1156,7 +1156,7 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None, | |||
| 1156 | 1156 | else: | |
| 1157 | 1157 | context = None | |
| 1158 | 1158 | ||
| 1159 | - if e and isinstance(e, BaseExceptionGroup): | ||
| 1159 | + if e is not None and isinstance(e, BaseExceptionGroup): | ||
| 1160 | 1160 | exceptions = [] | |
| 1161 | 1161 | for exc in e.exceptions: | |
| 1162 | 1162 | texc = TracebackException( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + A :class:`traceback.TracebackException` now correctly renders the ``__context__`` | ||
| 2 | + and ``__cause__`` attributes from :ref:`falsey <truth>` :class:`Exception`, | ||
| 3 | + and the ``exceptions`` attribute from falsey :class:`ExceptionGroup`. | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments