@@ -524,6 +524,27 @@ def __del__(self):
524524 b'ZeroDivisionError: division by zero' ]
525525 self .assertEqual (stderr .splitlines (), expected )
526526
527+ def test_when_io_is_lost (self ):
528+ # GH-142737: Display the traceback even if io.open is lost
529+ code = textwrap .dedent ("""\
530+ import builtins
531+ import sys
532+
533+ def bad_import(name, *args, **kwargs):
534+ sys.modules[name] = 42
535+ return sys.modules[name]
536+
537+ builtins.__import__ = bad_import
538+ raise RuntimeError("should not crash")
539+ """ )
540+ rc , stdout , stderr = assert_python_failure ('-c' , code )
541+ expected = [b'Exception ignored in the internal traceback machinery:' ,
542+ b'AttributeError: \' int\' object has no attribute \' _print_exception_bltin\' ' ,
543+ b'Traceback (most recent call last):' ,
544+ b' File "<string>", line 9, in <module>' ,
545+ b'RuntimeError: should not crash' ]
546+ self .assertEqual (stderr .splitlines (), expected )
547+
527548 def test_print_exception (self ):
528549 output = StringIO ()
529550 traceback .print_exception (
@@ -2268,7 +2289,7 @@ class TestTracebackFormat(unittest.TestCase, TracebackFormatMixin):
22682289
22692290@cpython_only
22702291@force_not_colorized_test_class
2271- class TestFallbackFormatWhenPrinterRaises (unittest .TestCase , TracebackFormatMixin ):
2292+ class TestFallbackTracebackFormat (unittest .TestCase , TracebackFormatMixin ):
22722293 DEBUG_RANGES = False
22732294 def setUp (self ) -> None :
22742295 self .original_unraisable_hook = sys .unraisablehook
@@ -2282,40 +2303,6 @@ def tearDown(self) -> None:
22822303 sys .unraisablehook = self .original_unraisable_hook
22832304 return super ().tearDown ()
22842305
2285- @cpython_only
2286- @force_not_colorized_test_class
2287- class TestFallbackFormatWhenIOUnavailable (unittest .TestCase , TracebackFormatMixin ):
2288- """See GH-142737."""
2289-
2290- def setUp (self ) -> None :
2291- import io
2292- self .original_io = io
2293- self .original_hook = traceback ._print_exception_bltin
2294-
2295- # Triggers fallback path
2296- traceback ._print_exception_bltin = object ()
2297-
2298- # StringIO is still needed for test.support.captured_output() to work
2299- sys .modules ['io' ] = types .SimpleNamespace (StringIO = io .StringIO )
2300- return super ().setUp ()
2301-
2302- def test_unhashable (self ):
2303- raise unittest .SkipTest (
2304- "io unavailable (test requires source lines to be captured in tracebacks)" )
2305-
2306- def test_traceback_format_with_cleared_frames (self ):
2307- raise unittest .SkipTest (
2308- "io unavailable (test requires source lines to be captured in tracebacks)" )
2309-
2310- def test_traceback_format (self ):
2311- raise unittest .SkipTest (
2312- "io unavailable (test requires source lines to be captured in tracebacks)" )
2313-
2314- def tearDown (self ) -> None :
2315- sys .modules ['io' ] = self .original_io
2316- traceback ._print_exception_bltin = self .original_hook
2317- return super ().tearDown ()
2318-
23192306class BaseExceptionReportingTests :
23202307
23212308 def get_exception (self , exception_or_callable ):
0 commit comments