from test.support import (Error, captured_output, cpython_only, ALWAYS_EQ,
requires_debug_ranges, has_no_debug_ranges,
requires_subprocess)
-from test.support.os_helper import TESTFN, unlink
-from test.support.script_helper import assert_python_ok, assert_python_failure
+from test.support.os_helper import TESTFN, temp_dir, unlink
+from test.support.script_helper import assert_python_ok, assert_python_failure, make_script
from test.support.import_helper import forget
from test.support import force_not_colorized, force_not_colorized_test_class
b'ZeroDivisionError: division by zero']
self.assertEqual(stderr.splitlines(), expected)
+ @cpython_only
+ def test_lost_io_open(self):
+ # GH-142737: Display the traceback even if io.open is lost
+ crasher = textwrap.dedent("""\
+ import io
+ import traceback
+ # Trigger fallback mode
+ traceback._print_exception_bltin = None
+ del io.open
+ raise RuntimeError("should not crash")
+ """)
+
+ # Create a temporary script to exercise _Py_FindSourceFile
+ with temp_dir() as script_dir:
+ script = make_script(
+ script_dir=script_dir,
+ script_basename='tb_test_no_io_open',
+ source=crasher)
+ rc, stdout, stderr = assert_python_failure(script)
+
+ self.assertEqual(rc, 1) # Make sure it's not a crash
+
+ expected = [b'Traceback (most recent call last):',
+ f' File "{script}", line 6, in <module>'.encode(),
+ b'RuntimeError: should not crash']
+ self.assertEqual(stderr.splitlines(), expected)
+
def test_print_exception(self):
output = StringIO()
traceback.print_exception(