@@ -258,6 +258,8 @@ def testSyntaxErrorOffset(self):
258258 check ('def f():\n continue' , 2 , 3 )
259259 check ('def f():\n break' , 2 , 3 )
260260 check ('try:\n pass\n except:\n pass\n except ValueError:\n pass' , 3 , 1 )
261+ check ('try:\n pass\n except*:\n pass' , 3 , 8 )
262+ check ('try:\n pass\n except*:\n pass\n except* ValueError:\n pass' , 3 , 8 )
261263
262264 # Errors thrown by tokenizer.c
263265 check ('(0x+1)' , 1 , 3 )
@@ -555,6 +557,35 @@ def testAttributes(self):
555557 'pickled "%r", attribute "%s' %
556558 (e , checkArgName ))
557559
560+ # TODO: RUSTPYTHON
561+ @unittest .expectedFailure
562+ def test_notes (self ):
563+ for e in [BaseException (1 ), Exception (2 ), ValueError (3 )]:
564+ with self .subTest (e = e ):
565+ self .assertFalse (hasattr (e , '__notes__' ))
566+ e .add_note ("My Note" )
567+ self .assertEqual (e .__notes__ , ["My Note" ])
568+
569+ with self .assertRaises (TypeError ):
570+ e .add_note (42 )
571+ self .assertEqual (e .__notes__ , ["My Note" ])
572+
573+ e .add_note ("Your Note" )
574+ self .assertEqual (e .__notes__ , ["My Note" , "Your Note" ])
575+
576+ del e .__notes__
577+ self .assertFalse (hasattr (e , '__notes__' ))
578+
579+ e .add_note ("Our Note" )
580+ self .assertEqual (e .__notes__ , ["Our Note" ])
581+
582+ e .__notes__ = 42
583+ self .assertEqual (e .__notes__ , 42 )
584+
585+ with self .assertRaises (TypeError ):
586+ e .add_note ("will not work" )
587+ self .assertEqual (e .__notes__ , 42 )
588+
558589 def testWithTraceback (self ):
559590 try :
560591 raise IndexError (4 )
@@ -1010,20 +1041,20 @@ def do_send(g):
10101041 self .fail ("should have raised StopIteration" )
10111042 self ._check_generator_cleanup_exc_state (do_send )
10121043
1013- # def test_3114(self):
1014- # # Bug #3114: in its destructor, MyObject retrieves a pointer to
1015- # # obsolete and/or deallocated objects.
1016- # class MyObject:
1017- # def __del__(self):
1018- # nonlocal e
1019- # e = sys.exc_info()
1020- # e = ()
1021- # try:
1022- # raise Exception(MyObject())
1023- # except:
1024- # pass
1025- # gc_collect() # For PyPy or other GCs.
1026- # self.assertEqual(e, (None, None, None))
1044+ def test_3114 (self ):
1045+ # Bug #3114: in its destructor, MyObject retrieves a pointer to
1046+ # obsolete and/or deallocated objects.
1047+ class MyObject :
1048+ def __del__ (self ):
1049+ nonlocal e
1050+ e = sys .exc_info ()
1051+ e = ()
1052+ try :
1053+ raise Exception (MyObject ())
1054+ except :
1055+ pass
1056+ gc_collect () # For PyPy or other GCs.
1057+ self .assertEqual (e , (None , None , None ))
10271058
10281059 def test_raise_does_not_create_context_chain_cycle (self ):
10291060 class A (Exception ):
@@ -1173,6 +1204,56 @@ class E(Exception):
11731204 self .assertIs (b .__context__ , a )
11741205 self .assertIs (a .__context__ , c )
11751206
1207+ def test_context_of_exception_in_try_and_finally (self ):
1208+ try :
1209+ try :
1210+ te = TypeError (1 )
1211+ raise te
1212+ finally :
1213+ ve = ValueError (2 )
1214+ raise ve
1215+ except Exception as e :
1216+ exc = e
1217+
1218+ self .assertIs (exc , ve )
1219+ self .assertIs (exc .__context__ , te )
1220+
1221+ def test_context_of_exception_in_except_and_finally (self ):
1222+ try :
1223+ try :
1224+ te = TypeError (1 )
1225+ raise te
1226+ except :
1227+ ve = ValueError (2 )
1228+ raise ve
1229+ finally :
1230+ oe = OSError (3 )
1231+ raise oe
1232+ except Exception as e :
1233+ exc = e
1234+
1235+ self .assertIs (exc , oe )
1236+ self .assertIs (exc .__context__ , ve )
1237+ self .assertIs (exc .__context__ .__context__ , te )
1238+
1239+ def test_context_of_exception_in_else_and_finally (self ):
1240+ try :
1241+ try :
1242+ pass
1243+ except :
1244+ pass
1245+ else :
1246+ ve = ValueError (1 )
1247+ raise ve
1248+ finally :
1249+ oe = OSError (2 )
1250+ raise oe
1251+ except Exception as e :
1252+ exc = e
1253+
1254+ self .assertIs (exc , oe )
1255+ self .assertIs (exc .__context__ , ve )
1256+
11761257 # TODO: RUSTPYTHON
11771258 @unittest .expectedFailure
11781259 def test_unicode_change_attributes (self ):
@@ -1410,9 +1491,7 @@ def recurse(cnt):
14101491 """
14111492 with SuppressCrashReport ():
14121493 rc , out , err = script_helper .assert_python_failure ("-c" , code )
1413- self .assertIn (b'Fatal Python error: _PyErr_NormalizeException: '
1414- b'Cannot recover from MemoryErrors while '
1415- b'normalizing exceptions.' , err )
1494+ self .assertIn (b'MemoryError' , err )
14161495
14171496 @cpython_only
14181497 def test_MemoryError (self ):
@@ -2008,6 +2087,8 @@ def test_attributes(self):
20082087 self .assertEqual (exc .name , 'carry' )
20092088 self .assertIs (exc .obj , sentinel )
20102089
2090+ # TODO: RUSTPYTHON
2091+ @unittest .expectedFailure
20112092 def test_getattr_has_name_and_obj (self ):
20122093 class A :
20132094 blech = None
@@ -2018,6 +2099,11 @@ class A:
20182099 except AttributeError as exc :
20192100 self .assertEqual ("bluch" , exc .name )
20202101 self .assertEqual (obj , exc .obj )
2102+ try :
2103+ object .__getattribute__ (obj , "bluch" )
2104+ except AttributeError as exc :
2105+ self .assertEqual ("bluch" , exc .name )
2106+ self .assertEqual (obj , exc .obj )
20212107
20222108 def test_getattr_has_name_and_obj_for_method (self ):
20232109 class A :
@@ -2526,6 +2612,23 @@ def test_incorrect_constructor(self):
25262612 self .assertRaises (TypeError , SyntaxError , "bad bad" , args )
25272613
25282614
2615+ class TestInvalidExceptionMatcher (unittest .TestCase ):
2616+ # TODO: RUSTPYTHON
2617+ @unittest .expectedFailure
2618+ def test_except_star_invalid_exception_type (self ):
2619+ with self .assertRaises (TypeError ):
2620+ try :
2621+ raise ValueError
2622+ except 42 :
2623+ pass
2624+
2625+ with self .assertRaises (TypeError ):
2626+ try :
2627+ raise ValueError
2628+ except (ValueError , 42 ):
2629+ pass
2630+
2631+
25292632class PEP626Tests (unittest .TestCase ):
25302633
25312634 def lineno_after_raise (self , f , * expected ):
@@ -2628,7 +2731,7 @@ def test_missing_lineno_shows_as_none(self):
26282731 def f ():
26292732 1 / 0
26302733 self .lineno_after_raise (f , 1 )
2631- f .__code__ = f .__code__ .replace (co_linetable = b'\x04 \x80 \xff \x80 ' )
2734+ f .__code__ = f .__code__ .replace (co_linetable = b'\xf8 \xf8 \xf8 \xf9 \xf8 \xf8 \xf8 ' )
26322735 self .lineno_after_raise (f , None )
26332736
26342737 def test_lineno_after_raise_in_with_exit (self ):
0 commit comments