@@ -1215,38 +1215,38 @@ def test_disable_gil_abi(self):
12151215
12161216@test .support .cpython_only
12171217class UnraisableHookTest (unittest .TestCase ):
1218- def write_unraisable_exc (self , exc , err_msg , obj ):
1219- import _testinternalcapi
1220- import types
1221- err_msg2 = f"Exception ignored { err_msg } "
1222- try :
1223- _testinternalcapi .write_unraisable_exc (exc , err_msg , obj )
1224- return types .SimpleNamespace (exc_type = type (exc ),
1225- exc_value = exc ,
1226- exc_traceback = exc .__traceback__ ,
1227- err_msg = err_msg2 ,
1228- object = obj )
1229- finally :
1230- # Explicitly break any reference cycle
1231- exc = None
1232-
12331218 def test_original_unraisablehook (self ):
1234- for err_msg in (None , "original hook" ):
1235- with self .subTest (err_msg = err_msg ):
1236- obj = "an object"
1237-
1238- with test .support .captured_output ("stderr" ) as stderr :
1239- with test .support .swap_attr (sys , 'unraisablehook' ,
1240- sys .__unraisablehook__ ):
1241- self .write_unraisable_exc (ValueError (42 ), err_msg , obj )
1242-
1243- err = stderr .getvalue ()
1244- if err_msg is not None :
1245- self .assertIn (f'Exception ignored { err_msg } : { obj !r} \n ' , err )
1246- else :
1247- self .assertIn (f'Exception ignored in: { obj !r} \n ' , err )
1248- self .assertIn ('Traceback (most recent call last):\n ' , err )
1249- self .assertIn ('ValueError: 42\n ' , err )
1219+ _testcapi = import_helper .import_module ('_testcapi' )
1220+ from _testcapi import err_writeunraisable , err_formatunraisable
1221+ obj = hex
1222+
1223+ with support .swap_attr (sys , 'unraisablehook' ,
1224+ sys .__unraisablehook__ ):
1225+ with support .captured_stderr () as stderr :
1226+ err_writeunraisable (ValueError (42 ), obj )
1227+ lines = stderr .getvalue ().splitlines ()
1228+ self .assertEqual (lines [0 ], f'Exception ignored in: { obj !r} ' )
1229+ self .assertEqual (lines [1 ], 'Traceback (most recent call last):' )
1230+ self .assertEqual (lines [- 1 ], 'ValueError: 42' )
1231+
1232+ with support .captured_stderr () as stderr :
1233+ err_writeunraisable (ValueError (42 ), None )
1234+ lines = stderr .getvalue ().splitlines ()
1235+ self .assertEqual (lines [0 ], 'Traceback (most recent call last):' )
1236+ self .assertEqual (lines [- 1 ], 'ValueError: 42' )
1237+
1238+ with support .captured_stderr () as stderr :
1239+ err_formatunraisable (ValueError (42 ), 'Error in %R' , obj )
1240+ lines = stderr .getvalue ().splitlines ()
1241+ self .assertEqual (lines [0 ], f'Error in { obj !r} :' )
1242+ self .assertEqual (lines [1 ], 'Traceback (most recent call last):' )
1243+ self .assertEqual (lines [- 1 ], 'ValueError: 42' )
1244+
1245+ with support .captured_stderr () as stderr :
1246+ err_formatunraisable (ValueError (42 ), None )
1247+ lines = stderr .getvalue ().splitlines ()
1248+ self .assertEqual (lines [0 ], 'Traceback (most recent call last):' )
1249+ self .assertEqual (lines [- 1 ], 'ValueError: 42' )
12501250
12511251 def test_original_unraisablehook_err (self ):
12521252 # bpo-22836: PyErr_WriteUnraisable() should give sensible reports
@@ -1293,6 +1293,8 @@ def test_original_unraisablehook_exception_qualname(self):
12931293 # Check that the exception is printed with its qualified name
12941294 # rather than just classname, and the module names appears
12951295 # unless it is one of the hard-coded exclusions.
1296+ _testcapi = import_helper .import_module ('_testcapi' )
1297+ from _testcapi import err_writeunraisable
12961298 class A :
12971299 class B :
12981300 class X (Exception ):
@@ -1304,9 +1306,7 @@ class X(Exception):
13041306 with test .support .captured_stderr () as stderr , test .support .swap_attr (
13051307 sys , 'unraisablehook' , sys .__unraisablehook__
13061308 ):
1307- expected = self .write_unraisable_exc (
1308- A .B .X (), "msg" , "obj"
1309- )
1309+ err_writeunraisable (A .B .X (), "obj" )
13101310 report = stderr .getvalue ()
13111311 self .assertIn (A .B .X .__qualname__ , report )
13121312 if moduleName in ['builtins' , '__main__' ]:
@@ -1322,34 +1322,45 @@ def test_original_unraisablehook_wrong_type(self):
13221322 sys .unraisablehook (exc )
13231323
13241324 def test_custom_unraisablehook (self ):
1325+ _testcapi = import_helper .import_module ('_testcapi' )
1326+ from _testcapi import err_writeunraisable , err_formatunraisable
13251327 hook_args = None
13261328
13271329 def hook_func (args ):
13281330 nonlocal hook_args
13291331 hook_args = args
13301332
1331- obj = object ()
1333+ obj = hex
13321334 try :
13331335 with test .support .swap_attr (sys , 'unraisablehook' , hook_func ):
1334- expected = self .write_unraisable_exc (ValueError (42 ),
1335- "custom hook" , obj )
1336- for attr in "exc_type exc_value exc_traceback err_msg object" .split ():
1337- self .assertEqual (getattr (hook_args , attr ),
1338- getattr (expected , attr ),
1339- (hook_args , expected ))
1336+ exc = ValueError (42 )
1337+ err_writeunraisable (exc , obj )
1338+ self .assertIs (hook_args .exc_type , type (exc ))
1339+ self .assertIs (hook_args .exc_value , exc )
1340+ self .assertIs (hook_args .exc_traceback , exc .__traceback__ )
1341+ self .assertIsNone (hook_args .err_msg )
1342+ self .assertEqual (hook_args .object , obj )
1343+
1344+ err_formatunraisable (exc , "custom hook %R" , obj )
1345+ self .assertIs (hook_args .exc_type , type (exc ))
1346+ self .assertIs (hook_args .exc_value , exc )
1347+ self .assertIs (hook_args .exc_traceback , exc .__traceback__ )
1348+ self .assertEqual (hook_args .err_msg , f'custom hook { obj !r} ' )
1349+ self .assertIsNone (hook_args .object )
13401350 finally :
13411351 # expected and hook_args contain an exception: break reference cycle
13421352 expected = None
13431353 hook_args = None
13441354
13451355 def test_custom_unraisablehook_fail (self ):
1356+ _testcapi = import_helper .import_module ('_testcapi' )
1357+ from _testcapi import err_writeunraisable
13461358 def hook_func (* args ):
13471359 raise Exception ("hook_func failed" )
13481360
13491361 with test .support .captured_output ("stderr" ) as stderr :
13501362 with test .support .swap_attr (sys , 'unraisablehook' , hook_func ):
1351- self .write_unraisable_exc (ValueError (42 ),
1352- "custom hook fail" , None )
1363+ err_writeunraisable (ValueError (42 ), "custom hook fail" )
13531364
13541365 err = stderr .getvalue ()
13551366 self .assertIn (f'Exception ignored in sys.unraisablehook: '
0 commit comments