1+ from pathlib import Path
2+ import tempfile
13import test .support
24from test .support .script_helper import assert_python_failure , assert_python_ok
35import textwrap
911@test .support .cpython_only
1012class PySysGetAttrTest (unittest .TestCase ):
1113
14+ common_faulthandler_code = textwrap .dedent ('''
15+ from contextlib import redirect_stderr
16+ from threading import Thread
17+ import time
18+ from faulthandler import dump_traceback, enable, dump_traceback_later
1219
13- def test_changing_stdout_from_thread (self ):
20+ class FakeFile:
21+ def __init__(self):
22+ self.f = open("{0}", "w")
23+ def write(self, s):
24+ self.f.write(s)
25+ def flush(self):
26+ time.sleep(0.2)
27+ def fileno(self):
28+ time.sleep(0.2)
29+ return self.f.fileno()
30+
31+ def thread1():
32+ text = FakeFile()
33+ with redirect_stderr(text):
34+ time.sleep(0.2)
35+
36+ def main():
37+ enable(None, True)
38+ t1 = Thread(target=thread1, args=())
39+ t1.start()
40+ time.sleep(0.1)
41+ {1}
42+
43+ if __name__ == "__main__":
44+ main()
45+ ''' )
46+
47+
48+ def test_print_deleted_stdout (self ):
1449 # print should use strong reference to the stdout.
1550 code = textwrap .dedent ('''
51+ # from https://gist.github.com/colesbury/c48f50e95d5d68e24814a56e2664e587
1652 from contextlib import redirect_stdout
1753 from io import StringIO
1854 from threading import Thread
@@ -23,7 +59,6 @@ def __repr__(self):
2359 time.sleep(0.2)
2460 return "Foo"
2561
26-
2762 def thread1():
2863 text = StringIO()
2964 with redirect_stdout(text):
@@ -43,5 +78,41 @@ def main():
4378 self .assertEqual (out , b"" )
4479 self .assertEqual (err , b"" )
4580
81+ def test_faulthandler_enable_deleted_stderr (self ):
82+ # faulthandler should use strong reference to the stderr
83+ with tempfile .TemporaryDirectory () as tmpdir :
84+ path = Path (tmpdir , "test_faulthandler_enable" )
85+ test_code = self .common_faulthandler_code .format (
86+ path .as_posix (),
87+ "enable(None, True)"
88+ )
89+ rc , out , err = assert_python_ok ('-c' , test_code )
90+ self .assertEqual (out , b"" )
91+ self .assertEqual (err , b"" )
92+
93+ def test_faulthandler_dump_traceback_deleted_stderr (self ):
94+ # faulthandler should use strong reference to the stderr
95+ with tempfile .TemporaryDirectory () as tmpdir :
96+ path = Path (tmpdir , "test_faulthandler_dump_traceback" )
97+ test_code = self .common_faulthandler_code .format (
98+ path .as_posix (),
99+ "dump_traceback(None, False)"
100+ )
101+ rc , out , err = assert_python_ok ('-c' , test_code )
102+ self .assertEqual (out , b"" )
103+ self .assertEqual (err , b"" )
104+
105+ def test_faulthandler_dump_traceback_later_deleted_stderr (self ):
106+ # faulthandler should use strong reference to the stderr
107+ with tempfile .TemporaryDirectory () as tmpdir :
108+ path = Path (tmpdir , "test_faulthandler_dump_traceback_later" )
109+ test_code = self .common_faulthandler_code .format (
110+ path .as_posix (),
111+ "dump_traceback_later(0.1, True, None, False)"
112+ )
113+ rc , out , err = assert_python_ok ('-c' , test_code )
114+ self .assertEqual (out , b"" )
115+ self .assertEqual (err , b"" )
116+
46117if __name__ == "__main__" :
47118 unittest .main ()
0 commit comments