@@ -443,6 +443,33 @@ def fmt():
443443 ' return traceback.format_stack()\n ' % (__file__ , lineno + 1 ),
444444 ])
445445
446+ @cpython_only
447+ def test_unhashable (self ):
448+ from _testcapi import exception_print
449+
450+ class UnhashableException (Exception ):
451+ def __eq__ (self , other ):
452+ return True
453+
454+ ex1 = UnhashableException ('ex1' )
455+ ex2 = UnhashableException ('ex2' )
456+ try :
457+ raise ex2 from ex1
458+ except UnhashableException :
459+ try :
460+ raise ex1
461+ except UnhashableException :
462+ exc_type , exc_val , exc_tb = sys .exc_info ()
463+
464+ with captured_output ("stderr" ) as stderr_f :
465+ exception_print (exc_val )
466+
467+ tb = stderr_f .getvalue ().strip ().splitlines ()
468+ self .assertEqual (11 , len (tb ))
469+ self .assertEqual (context_message .strip (), tb [5 ])
470+ self .assertIn ('UnhashableException: ex2' , tb [3 ])
471+ self .assertIn ('UnhashableException: ex1' , tb [10 ])
472+
446473
447474cause_message = (
448475 "\n The above exception was the direct cause "
@@ -994,6 +1021,25 @@ def test_context(self):
9941021 self .assertEqual (exc_info [0 ], exc .exc_type )
9951022 self .assertEqual (str (exc_info [1 ]), str (exc ))
9961023
1024+ def test_unhashable (self ):
1025+ class UnhashableException (Exception ):
1026+ def __eq__ (self , other ):
1027+ return True
1028+
1029+ ex1 = UnhashableException ('ex1' )
1030+ ex2 = UnhashableException ('ex2' )
1031+ try :
1032+ raise ex2 from ex1
1033+ except UnhashableException :
1034+ try :
1035+ raise ex1
1036+ except UnhashableException :
1037+ exc_info = sys .exc_info ()
1038+ exc = traceback .TracebackException (* exc_info )
1039+ formatted = list (exc .format ())
1040+ self .assertIn ('UnhashableException: ex2\n ' , formatted [2 ])
1041+ self .assertIn ('UnhashableException: ex1\n ' , formatted [6 ])
1042+
9971043 def test_limit (self ):
9981044 def recurse (n ):
9991045 if n :
0 commit comments