8000 bpo-39983: Add test.support.print_warning() (GH-19683) (GH-19687) · python/cpython@3340b2a · GitHub
[go: up one dir, main page]

Skip to content

Commit 3340b2a

Browse files
authored
bpo-39983: Add test.support.print_warning() (GH-19683) (GH-19687)
Log "Warning -- ..." test warnings into sys.__stderr__ rather than sys.stderr, to ensure to display them even if sys.stderr is captured. test.libregrtest.utils.print_warning() now calls test.support.print_warning(). (cherry picked from commit d663d34)
1 parent 714aa83 commit 3340b2a

File tree

5 files changed

+51
-31
lines changed

5 files changed

+51
-31
lines changed

Lib/test/_test_multiprocessing.py

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5310,10 +5310,9 @@ def wait_proc_exit(self):
53105310
dt = time.monotonic() - start_time
53115311
if dt >= 5.0:
53125312
test.support.environment_altered = True
5313-
print("Warning -- multiprocessing.Manager still has %s active "
5314-
"children after %s seconds"
5315-
% (multiprocessing.active_children(), dt),
5316-
file=sys.stderr)
5313+
support.print_warning(f"multiprocessing.Manager still has "
5314+
f"{multiprocessing.active_children()} "
5315+
f"active children after {dt} seconds")
53175316
break
53185317

53195318
def run_worker(self, worker, obj):
@@ -5513,15 +5512,13 @@ def tearDownClass(cls):
55135512
processes = set(multiprocessing.process._dangling) - set(cls.dangling[0])
55145513
if processes:
55155514
test.support.environment_altered = True
5516-
print('Warning -- Dangling processes: %s' % processes,
5517-
file=sys.stderr)
5515+
support.print_warning(f'Dangling processes: {processes}')
55185516
processes = None
55195517

55205518
threads = set(threading._dangling) - set(cls.dangling[1])
55215519
if threads:
55225520
test.support.environment_altered = True
5523-
print('Warning -- Dangling threads: %s' % threads,
5524-
file=sys.stderr)
5521+
support.print_warning(f'Dangling threads: {threads}')
55255522
threads = None
55265523

55275524

@@ -5589,10 +5586,9 @@ def tearDownClass(cls):
55895586
dt = time.monotonic() - start_time
55905587
if dt >= 5.0:
55915588
test.support.environment_altered = True
5592-
print("Warning -- multiprocessing.Manager still has %s active "
5593-
"children after %s seconds"
5594-
% (multiprocessing.active_children(), dt),
5595-
file=sys.stderr)
5589+
support.print_warning(f"multiprocessing.Manager still has "
5590+
f"{multiprocessing.active_children()} "
5591+
f"active children after {dt} seconds")
55965592
break
55975593

55985594
gc.collect() # do garbage collection
@@ -5601,9 +5597,9 @@ def tearDownClass(cls):
56015597
# ensure that all processes which hold a reference to a
56025598
# managed object have been joined.
56035599
test.support.environment_altered = True
5604-
print('Warning -- Shared objects which still exist at manager '
5605-
'shutdown:')
5606-
print(cls.manager._debug_info())
5600+
support.print_warning('Shared objects which still exist '
5601+
'at manager shutdown:')
5602+
support.print_warning(cls.manager._debug_info())
56075603
cls.manager.shutdown()
56085604
cls.manager.join()
56095605
cls.manager = None
@@ -5700,16 +5696,14 @@ def tearDownModule():
57005696
if processes:
57015697
need_sleep = True
57025698
test.support.environment_altered = True
5703-
print('Warning -- Dangling processes: %s' % processes,
5704-
file=sys.stderr)
5699+
support.print_warning(f'Dangling processes: {processes}')
57055700
processes = None
57065701

57075702
threads = set(threading._dangling) - set(dangling[1])
57085703
if threads:
57095704
need_sleep = True
57105705
test.support.environment_altered = True
5711-
print('Warning -- Dangling threads: %s' % threads,
5712-
file=sys.stderr)
5706+
support.print_warning(f'Dangling threads: {threads}')
57135707
threads = None
57145708

57155709
# Sleep 500 ms to give time to child processes to complete.

Lib/test/libregrtest/runtest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ def cleanup_test_droppings(test_name, verbose):
327327
f"directory nor file")
328328

329329
if verbose:
330-
print_warning("%r left behind %s %r" % (test_name, kind, name))
330+
print_warning(f"{test_name} left behind {kind} {name!r}")
331331
support.environment_altered = True
332332

333333
try:

Lib/test/libregrtest/utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os.path
33
import sys
44
import textwrap
5+
from test import support
56

67

78
def format_duration(seconds):
@@ -61,4 +62,4 @@ def printlist(x, width=70, indent=4, file=None):
6162

6263

6364
def print_warning(msg):
64-
print(f"Warning -- {msg}", file=sys.stderr, flush=True)
65+
support.print_warning(msg)

Lib/test/support/__init__.py

Lines changed: 12 additions & 9 deletions
< F438 /tr>
Original file line numberDiff line numberDiff line change
@@ -2201,6 +2201,12 @@ def run_doctest(module, verbosity=None, optionflags=0):
22012201
#=======================================================================
22022202
# Support for saving and restoring the imported modules.
22032203

2204+
def print_warning(msg):
2205+
# bpo-39983: Print into sys.__stderr__ to display the warning even
2206+
# when sys.stderr is captured temporarily by a test
2207+
for line in msg.splitlines():
2208+
print(f"Warning -- {line}", file=sys.__stderr__, flush=True)
2209+
22042210
def modules_setup():
22052211
return sys.modules.copy(),
22062212

@@ -2256,14 +2262,12 @@ def threading_cleanup(*original_values):
22562262
# Display a warning at the first iteration
22572263
environment_altered = True
22582264
dangling_threads = values[1]
2259-
print("Warning -- threading_cleanup() failed to cleanup "
2260-
"%s threads (count: %s, dangling: %s)"
2261-
% (values[0] - original_values[0],
2262-
values[0], len(dangling_threads)),
2263-
file=sys.stderr)
2265+
print_warning(f"threading_cleanup() failed to cleanup "
2266+
f"{values[0] - original_values[0]} threads "
2267+
f"(count: {values[0]}, "
2268+
f"dangling: {len(dangling_threads)})")
22642269
for thread in dangling_threads:
2265-
print(f"Dangling thread: {thread!r}", file=sys.stderr)
2266-
sys.stderr.flush()
2270+
print_warning(f"Dangling thread: {thread!r}")
22672271

22682272
# Don't hold references to threads
22692273
dangling_threads = None
@@ -2356,8 +2360,7 @@ def reap_children():
23562360
if pid == 0:
23572361
break
23582362

2359-
print("Warning -- reap_children() reaped child process %s"
2360-
% pid, file=sys.stderr)
2363+
print_warning(f"reap_children() reaped child process {pid}")
23612364
environment_altered = True
23622365

23632366

Lib/test/test_support.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,8 +433,12 @@ def test_reap_children(self):
433433
if time.monotonic() > deadline:
434434
self.fail("timeout")
435435

436-
with contextlib.redirect_stderr(stderr):
436+
old_stderr = sys.__stderr__
437+
try:
438+
sys.__stderr__ = stderr
437439
support.reap_children()
440+
finally:
441+
sys.__stderr__ = old_stderr
438442

439443
# Use environment_altered to check if reap_children() found
440444
# the child process
@@ -633,6 +637,24 @@ def test_fd_count(self):
633637
os.close(fd)
634638
self.assertEqual(more - start, 1)
635639

640+
def check_print_warning(self, msg, expected):
641+
stderr = io.StringIO()
642+
643+
old_stderr = sys.__stderr__
644+
try:
645+
sys.__stderr__ = stderr
646+
support.print_warning(msg)
647+
finally:
648+
sys.__stderr__ = old_stderr
649+
650+
self.assertEqual(stderr.getvalue(), expected)
651+
652+
def test_print_warning(self):
653+
self.check_print_warning("msg",
654+
"Warning -- msg\n")
655+
self.check_print_warning("a\nb",
656+
'Warning -- a\nWarning -- b\n')
657+
636658
# XXX -follows a list of untested API
637659
# make_legacy_pyc
638660
# is_resource_enabled

0 commit comments

Comments
 (0)
0