@@ -3413,6 +3413,24 @@ class Unrepresentable:
34133413 def __repr__ (self ) -> str :
34143414 raise Exception ("Unrepresentable" )
34153415
3416+
3417+ # Used in test_dont_swallow_cause_or_context_of_falsey_exception and
3418+ # test_dont_swallow_subexceptions_of_falsey_exceptiongroup.
3419+ class FalseyBoolException (Exception ):
3420+ def __bool__ (self ):
3421+ return False
3422+
3423+
3424+ class FalseyLenException (Exception ):
3425+ def __len__ (self ):
3426+ return 0
3427+
3428+
3429+ class FalseyExceptionGroup (ExceptionGroup ):
3430+ def __bool__ (self ):
3431+ return False
3432+
3433+
34163434class TestTracebackException (unittest .TestCase ):
34173435 def do_test_smoke (self , exc , expected_type_str ):
34183436 try :
@@ -3759,6 +3777,26 @@ def f():
37593777 'ZeroDivisionError: division by zero' ,
37603778 '' ])
37613779
3780+ def test_dont_swallow_cause_or_context_of_falsey_exception (self ):
3781+ # see gh-132308: Ensure that __cause__ or __context__ attributes of exceptions
3782+ # that evaluate as falsey are included in the output.
3783+ # Recall: `x` is falsey if `len(x)` returns 0 or `bool(x)` returns False.
3784+
3785+ for exc in (FalseyBoolException , FalseyLenException ):
3786+ try :
3787+ raise exc (0 ) from KeyError
3788+ except exc as e :
3789+ self .assertIn (cause_message , traceback .format_exception (e ))
3790+
3791+ for exc in (FalseyBoolException , FalseyLenException ):
3792+ try :
3793+ try :
3794+ 1 / 0
3795+ except :
3796+ raise exc (1 )
3797+ except exc as e :
3798+ self .assertIn (context_message , traceback .format_exception (e ))
3799+
37623800
37633801class TestTracebackException_ExceptionGroups (unittest .TestCase ):
37643802 def setUp (self ):
@@ -3960,6 +3998,25 @@ def test_comparison(self):
39603998 self .assertNotEqual (exc , object ())
39613999 self .assertEqual (exc , ALWAYS_EQ )
39624000
4001+ def test_dont_swallow_subexceptions_of_falsey_exceptiongroup (self ):
4002+ # see gh-132308: Ensure that subexceptions of exception group
4003+ # that evaluate as falsey are displayed in the output.
4004+ # Recall: `x` is falsey if `len(x)` returns 0 or `bool(x)` returns False.
4005+
4006+ try :
4007+ raise FalseyExceptionGroup ("Gih" , (KeyError (2 ), NameError ('Guh' )))
4008+ except Exception as ee :
4009+ str_exc = '' .join (traceback .format_exception (ee ))
4010+ self .assertIn ('+---------------- 1 ----------------' , str_exc )
4011+ self .assertIn ('+---------------- 2 ----------------' , str_exc )
4012+
4013+ # Test with a falsey exception, in last position, as sub-exceptions.
4014+ msg = 'bool'
4015+ try :
4016+ raise FalseyExceptionGroup ("Gih" , (KeyError (2 ), FalseyBoolException (msg )))
4017+ except Exception as ee :
4018+ str_exc = traceback .format_exception (ee )
4019+ self .assertIn (f'{ FalseyBoolException .__name__ } : { msg } ' , str_exc [- 2 ])
39634020
39644021global_for_suggestions = None
39654022
0 commit comments