Skip to content

Commit 0025350

Browse files
authored
bpo-37069: tests use catch_unraisable_exception() (GH-13762)
Modify test_coroutines, test_cprofile, test_generators, test_raise, test_ssl and test_yield_from to use support.catch_unraisable_exception() rather than support.captured_stderr(). test_thread: remove test_save_exception_state_on_error() which is now updated. test_unraisable_exception() checks that sys.unraisablehook() is called to handle _thread.start_new_thread() exception. test_cprofile now rely on unittest for test discovery: replace support.run_unittest() with unittest.main().
1 parent 13136e8 commit 0025350

File tree

8 files changed

+60
-69
lines changed

8 files changed

+60
-69
lines changed

‎Lib/test/test_coroutines.py‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,11 +2032,17 @@ async def func(): pass
20322032
def test_fatal_coro_warning(self):
20332033
# Issue 27811
20342034
async def func(): pass
2035-
with warnings.catch_warnings(), support.captured_stderr() as stderr:
2035+
with warnings.catch_warnings(), \
2036+
support.catch_unraisable_exception() as cm:
20362037
warnings.filterwarnings("error")
2037-
func()
2038+
coro = func()
2039+
# only store repr() to avoid keeping the coroutine alive
2040+
coro_repr = repr(coro)
2041+
coro = None
20382042
support.gc_collect()
2039-
self.assertIn("was never awaited", stderr.getvalue())
2043+
2044+
self.assertIn("was never awaited", str(cm.unraisable.exc_value))
2045+
self.assertEqual(repr(cm.unraisable.object), coro_repr)
20402046

20412047
def test_for_assign_raising_stop_async_iteration(self):
20422048
class BadTarget:

‎Lib/test/test_cprofile.py‎

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
"""Test suite for the cProfile module."""
22

33
import sys
4-
from test.support import run_unittest, TESTFN, unlink
54
import unittest
65

76
# rip off all interesting stuff from test_profile
87
import cProfile
98
from test.test_profile import ProfileTest, regenerate_expected_output
109
from test.support.script_helper import assert_python_failure, assert_python_ok
10+
from test import support
1111

1212

1313
class CProfileTest(ProfileTest):
@@ -18,24 +18,18 @@ class CProfileTest(ProfileTest):
1818
def get_expected_output(self):
1919
return _ProfileOutput
2020

21-
# Issue 3895.
2221
def test_bad_counter_during_dealloc(self):
22+
# bpo-3895
2323
import _lsprof
24-
# Must use a file as StringIO doesn't trigger the bug.
25-
orig_stderr = sys.stderr
26-
try:
27-
with open(TESTFN, 'w') as file:
28-
sys.stderr = file
29-
try:
30-
obj = _lsprof.Profiler(lambda: int)
31-
obj.enable()
32-
obj = _lsprof.Profiler(1)
33-
obj.disable()
34-
obj.clear()
35-
finally:
36-
sys.stderr = orig_stderr
37-
finally:
38-
unlink(TESTFN)
24+
25+
with support.catch_unraisable_exception() as cm:
26+
obj = _lsprof.Profiler(lambda: int)
27+
obj.enable()
28+
obj = _lsprof.Profiler(1)
29+
obj.disable()
30+
obj.clear()
31+
32+
self.assertEqual(cm.unraisable.exc_type, TypeError)
3933

4034
def test_profile_enable_disable(self):
4135
prof = self.profilerclass()
@@ -70,12 +64,10 @@ def test_sort(self):
7064
self.assertGreater(rc, 0)
7165
self.assertIn(b"option -s: invalid choice: 'demo'", err)
7266

73-
def test_main():
74-
run_unittest(CProfileTest, TestCommandLine)
7567

7668
def main():
7769
if '-r' not in sys.argv:
78-
test_main()
70+
unittest.main()
7971
else:
8072
regenerate_expected_output(__file__, CProfileTest)
8173

‎Lib/test/test_generators.py‎

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,15 +2051,17 @@ def printsolution(self, x):
20512051
20522052
Our ill-behaved code should be invoked during GC:
20532053
2054-
>>> import sys, io
2055-
>>> old, sys.stderr = sys.stderr, io.StringIO()
2056-
>>> g = f()
2057-
>>> next(g)
2058-
>>> del g
2059-
>>> "RuntimeError: generator ignored GeneratorExit" in sys.stderr.getvalue()
2054+
>>> with support.catch_unraisable_exception() as cm:
2055+
... g = f()
2056+
... next(g)
2057+
... del g
2058+
...
2059+
... cm.unraisable.exc_type == RuntimeError
2060+
... "generator ignored GeneratorExit" in str(cm.unraisable.exc_value)
2061+
... cm.unraisable.exc_traceback is not None
2062+
True
2063+
True
20602064
True
2061-
>>> sys.stderr = old
2062-
20632065
20642066
And errors thrown during closing should propagate:
20652067

‎Lib/test/test_raise.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,12 @@ def f():
459459
self.assertNotEqual(e.__context__, None)
460460
self.assertIsInstance(e.__context__, AttributeError)
461461

462-
with support.captured_output("stderr"):
462+
with support.catch_unraisable_exception() as cm:
463463
f()
464464

465+
self.assertEqual(ZeroDivisionError, cm.unraisable.exc_type)
466+
467+
465468
class TestRemovedFunctionality(unittest.TestCase):
466469
def test_tuples(self):
467470
try:

‎Lib/test/test_ssl.py‎

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4051,13 +4051,15 @@ def cb_raising(ssl_sock, server_name, initial_context):
40514051
1/0
40524052
server_context.set_servername_callback(cb_raising)
40534053

4054-
with self.assertRaises(ssl.SSLError) as cm, \
4055-
support.captured_stderr() as stderr:
4056-
stats = server_params_test(client_context, server_context,
4057-
chatty=False,
4058-
sni_name='supermessage')
4059-
self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE')
4060-
self.assertIn("ZeroDivisionError", stderr.getvalue())
4054+
with support.catch_unraisable_exception() as catch:
4055+
with self.assertRaises(ssl.SSLError) as cm:
4056+
stats = server_params_test(client_context, server_context,
4057+
chatty=False,
4058+
sni_name='supermessage')
4059+
4060+
self.assertEqual(cm.exception.reason,
4061+
'SSLV3_ALERT_HANDSHAKE_FAILURE')
4062+
self.assertEqual(catch.unraisable.exc_type, ZeroDivisionError)
40614063

40624064
@needs_sni
40634065
def test_sni_callback_wrong_return_type(self):
@@ -4069,13 +4071,15 @@ def cb_wrong_return_type(ssl_sock, server_name, initial_context):
40694071
return "foo"
40704072
server_context.set_servername_callback(cb_wrong_return_type)
40714073

4072-
with self.assertRaises(ssl.SSLError) as cm, \
4073-
support.captured_stderr() as stderr:
4074-
stats = server_params_test(client_context, server_context,
4075-
chatty=False,
4076-
sni_name='supermessage')
4077-
self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
4078-
self.assertIn("TypeError", stderr.getvalue())
4074+
with support.catch_unraisable_exception() as catch:
4075+
with self.assertRaises(ssl.SSLError) as cm:
4076+
stats = server_params_test(client_context, server_context,
4077+
chatty=False,
4078+
sni_name='supermessage')
4079+
4080+
4081+
self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
4082+
self.assertEqual(catch.unraisable.exc_type, TypeError)
40794083

40804084
def test_shared_ciphers(self):
40814085
client_context, server_context, hostname = testing_context()

‎Lib/test/test_thread.py‎

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -133,27 +133,6 @@ def task():
133133
time.sleep(POLL_SLEEP)
134134
self.assertEqual(thread._count(), orig)
135135

136-
def test_save_exception_state_on_error(self):
137-
# See issue #14474
138-
def task():
139-
started.release()
140-
raise SyntaxError
141-
def mywrite(self, *args):
142-
try:
143-
raise ValueError
144-
except ValueError:
145-
pass
146-
real_write(self, *args)
147-
started = thread.allocate_lock()
148-
with support.captured_output("stderr") as stderr:
149-
real_write = stderr.write
150-
stderr.write = mywrite
151-
started.acquire()
152-
with support.wait_threads_exit():
153-
thread.start_new_thread(task, ())
154-
started.acquire()
155-
self.assertIn("Traceback", stderr.getvalue())
156-
157136
def test_unraisable_exception(self):
158137
def task():
159138
started.release()

‎Lib/test/test_yield_from.py‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import inspect
1212

1313
from test.support import captured_stderr, disable_gc, gc_collect
14+
from test import support
1415

1516
class TestPEP380Operation(unittest.TestCase):
1617
"""
@@ -562,11 +563,12 @@ def g():
562563
self.assertEqual(next(gi), 1)
563564
gi.throw(AttributeError)
564565

565-
with captured_stderr() as output:
566+
with support.catch_unraisable_exception() as cm:
566567
gi = g()
567568
self.assertEqual(next(gi), 1)
568569
gi.close()
569-
self.assertIn('ZeroDivisionError', output.getvalue())
570+
571+
self.assertEqual(ZeroDivisionError, cm.unraisable.exc_type)
570572

571573
def test_exception_in_initial_next_call(self):
572574
"""
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Modify test_coroutines, test_cprofile, test_generators, test_raise, test_ssl
2+
and test_yield_from to use :func:`test.support.catch_unraisable_exception`
3+
rather than :func:`test.support.captured_stderr`.

0 commit comments

Comments
 (0)