Skip to content

Commit 6cac113

Browse files
authored
bpo-38991: Remove test.support.strip_python_stderr() (GH-17490)
test.support: run_python_until_end(), assert_python_ok() and assert_python_failure() functions no longer strip whitespaces from stderr.
1 parent 2b7de66 commit 6cac113

File tree

11 files changed

+46
-61
lines changed

11 files changed

+46
-61
lines changed

Doc/library/test.rst

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -686,13 +686,6 @@ The :mod:`test.support` module defines the following functions:
686686
``sys.stdout`` if it's not set.
687687

688688

689-
.. function:: strip_python_strerr(stderr)
690-
691-
Strip the *stderr* of a Python process from potential debug output
692-
emitted by the interpreter. This will typically be run on the result of
693-
:meth:`subprocess.Popen.communicate`.
694-
695-
696689
.. function:: args_from_interpreter_flags()
697690

698691
Return a list of command line arguments reproducing the current settings
@@ -1499,6 +1492,9 @@ script execution tests.
14991492
in a subprocess. The values can include ``__isolated``, ``__cleanenv``,
15001493
``__cwd``, and ``TERM``.
15011494

1495+
.. versionchanged:: 3.9
1496+
The function no longer strips whitespaces from *stderr*.
1497+
15021498

15031499
.. function:: assert_python_ok(*args, **env_vars)
15041500

@@ -1512,6 +1508,9 @@ script execution tests.
15121508
Python is started in isolated mode (command line option ``-I``),
15131509
except if the ``__isolated`` keyword is set to ``False``.
15141510

1511+
.. versionchanged:: 3.9
1512+
The function no longer strips whitespaces from *stderr*.
1513+
15151514

15161515
.. function:: assert_python_failure(*args, **env_vars)
15171516

@@ -1521,6 +1520,9 @@ script execution tests.
15211520

15221521
See :func:`assert_python_ok` for more options.
15231522

1523+
.. versionchanged:: 3.9
1524+
The function no longer strips whitespaces from *stderr*.
1525+
15241526

15251527
.. function:: spawn_python(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw)
15261528

Lib/test/support/__init__.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2512,16 +2512,6 @@ def swap_item(obj, item, new_val):
25122512
if item in obj:
25132513
del obj[item]
25142514

2515-
def strip_python_stderr(stderr):
2516-
"""Strip the stderr of a Python process from potential debug output
2517-
emitted by the interpreter.
2518-
2519-
This will typically be run on the result of the communicate() method
2520-
of a subprocess.Popen object.
2521-
"""
2522-
stderr = re.sub(br"\[\d+ refs, \d+ blocks\]\r?\n?", b"", stderr).strip()
2523-
return stderr
2524-
25252515
requires_type_collecting = unittest.skipIf(hasattr(sys, 'getcounts'),
25262516
'types are immortal if COUNT_ALLOCS is defined')
25272517

Lib/test/support/script_helper.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import zipfile
1212

1313
from importlib.util import source_from_cache
14-
from test.support import make_legacy_pyc, strip_python_stderr
14+
from test.support import make_legacy_pyc
1515

1616

1717
# Cached result of the expensive test performed in the function below.
@@ -134,7 +134,6 @@ def run_python_until_end(*args, **env_vars):
134134
proc.kill()
135135
subprocess._cleanup()
136136
rc = proc.returncode
137-
err = strip_python_stderr(err)
138137
return _PythonRunResult(rc, out, err), cmd_line
139138

140139
def _assert_python(expected_success, /, *args, **env_vars):

Lib/test/test_cmd_line.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,10 @@ def test_output_newline(self):
332332

333333
if sys.platform == 'win32':
334334
self.assertEqual(b'1\r\n2\r\n', out)
335-
self.assertEqual(b'3\r\n4', err)
335+
self.assertEqual(b'3\r\n4\r\n', err)
336336
else:
337337
self.assertEqual(b'1\n2\n', out)
338-
self.assertEqual(b'3\n4', err)
338+
self.assertEqual(b'3\n4\n', err)
339339

340340
def test_unmached_quote(self):
341341
# Issue #10206: python program starting with unmatched quote
@@ -391,7 +391,7 @@ def preexec():
391391
stderr=subprocess.PIPE,
392392
preexec_fn=preexec)
393393
out, err = p.communicate()
394-
self.assertEqual(support.strip_python_stderr(err), b'')
394+
self.assertEqual(err, b'')
395395
self.assertEqual(p.returncode, 42)
396396

397397
def test_no_stdin(self):

Lib/test/test_cmd_line_script.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ def test_pep_409_verbiage(self):
535535
script_name = _make_test_script(script_dir, 'script', script)
536536
exitcode, stdout, stderr = assert_python_failure(script_name)
537537
text = stderr.decode('ascii').split('\n')
538-
self.assertEqual(len(text), 4)
538+
self.assertEqual(len(text), 5)
539539
self.assertTrue(text[0].startswith('Traceback'))
540540
self.assertTrue(text[1].startswith(' File '))
541541
self.assertTrue(text[3].startswith('NameError'))
@@ -579,7 +579,7 @@ def test_issue20500_exit_with_exception_value(self):
579579
script_name = _make_test_script(script_dir, 'script', script)
580580
exitcode, stdout, stderr = assert_python_failure(script_name)
581581
text = stderr.decode('ascii')
582-
self.assertEqual(text, "some text")
582+
self.assertEqual(text.rstrip(), "some text")
583583

584584
def test_syntaxerror_unindented_caret_position(self):
585585
script = "1 + 1 = 2\n"

Lib/test/test_faulthandler.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,8 @@ def get_output(self, code, filename=None, fd=None):
7171
with support.SuppressCrashReport():
7272
process = script_helper.spawn_python('-c', code, pass_fds=pass_fds)
7373
with process:
74-
stdout, stderr = process.communicate()
74+
output, stderr = process.communicate()
7575
exitcode = process.wait()
76-
output = support.strip_python_stderr(stdout)
7776
output = output.decode('ascii', 'backslashreplace')
7877
if filename:
7978
self.assertEqual(output, '')

Lib/test/test_gc.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import unittest
22
import unittest.mock
33
from test.support import (verbose, refcount_test, run_unittest,
4-
strip_python_stderr, cpython_only, start_threads,
4+
cpython_only, start_threads,
55
temp_dir, requires_type_collecting, TESTFN, unlink,
66
import_module)
77
from test.support.script_helper import assert_python_ok, make_script
@@ -671,8 +671,8 @@ def run_command(code):
671671
p.stdout.close()
672672
p.stderr.close()
673673
self.assertEqual(p.returncode, 0)
674-
self.assertEqual(stdout.strip(), b"")
675-
return strip_python_stderr(stderr)
674+
self.assertEqual(stdout, b"")
675+
return stderr
676676

677677
stderr = run_command(code % "0")
678678
self.assertIn(b"ResourceWarning: gc: 2 uncollectable objects at "

Lib/test/test_subprocess.py

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,6 @@ def tearDown(self):
8585
self.doCleanups()
8686
support.reap_children()
8787

88-
def assertStderrEqual(self, stderr, expected, msg=None):
89-
# In a debug build, stuff like "[6580 refs]" is printed to stderr at
90-
# shutdown time. That frustrates tests trying to check stderr produced
91-
# from a spawned Python process.
92-
actual = support.strip_python_stderr(stderr)
93-
# strip_python_stderr also strips whitespace, so we do too.
94-
expected = expected.strip()
95-
self.assertEqual(actual, expected, msg)
96-
9788

9889
class PopenTestException(Exception):
9990
pass
@@ -547,7 +538,7 @@ def test_stderr_pipe(self):
547538
'import sys; sys.stderr.write("strawberry")'],
548539
stderr=subprocess.PIPE)
549540
with p:
550-
self.assertStderrEqual(p.stderr.read(), b"strawberry")
541+
self.assertEqual(p.stderr.read(), b"strawberry")
551542

552543
def test_stderr_filedes(self):
553544
# stderr is set to open file descriptor
@@ -559,7 +550,7 @@ def test_stderr_filedes(self):
559550
stderr=d)
560551
p.wait()
561552
os.lseek(d, 0, 0)
562-
self.assertStderrEqual(os.read(d, 1024), b"strawberry")
553+
self.assertEqual(os.read(d, 1024), b"strawberry")
563554

564555
def test_stderr_fileobj(self):
565556
# stderr is set to open file object
@@ -570,7 +561,7 @@ def test_stderr_fileobj(self):
570561
stderr=tf)
571562
p.wait()
572563
tf.seek(0)
573-
self.assertStderrEqual(tf.read(), b"strawberry")
564+
self.assertEqual(tf.read(), b"strawberry")
574565

575566
def test_stderr_redirect_with_no_stdout_redirect(self):
576567
# test stderr=STDOUT while stdout=None (not set)
@@ -589,8 +580,8 @@ def test_stderr_redirect_with_no_stdout_redirect(self):
589580
stderr=subprocess.PIPE)
590581
stdout, stderr = p.communicate()
591582
#NOTE: stdout should get stderr from grandchild
592-
self.assertStderrEqual(stdout, b'42')
593-
self.assertStderrEqual(stderr, b'') # should be empty
583+
self.assertEqual(stdout, b'42')
584+
self.assertEqual(stderr, b'') # should be empty
594585
self.assertEqual(p.returncode, 0)
595586

596587
def test_stdout_stderr_pipe(self):
@@ -603,7 +594,7 @@ def test_stdout_stderr_pipe(self):
603594
stdout=subprocess.PIPE,
604595
stderr=subprocess.STDOUT)
605596
with p:
606-
self.assertStderrEqual(p.stdout.read(), b"appleorange")
597+
self.assertEqual(p.stdout.read(), b"appleorange")
607598

608599
def test_stdout_stderr_file(self):
609600
# capture stdout and stderr to the same open file
@@ -618,7 +609,7 @@ def test_stdout_stderr_file(self):
618609
stderr=tf)
619610
p.wait()
620611
tf.seek(0)
621-
self.assertStderrEqual(tf.read(), b"appleorange")
612+
self.assertEqual(tf.read(), b"appleorange")
622613

623614
def test_stdout_filedes_of_stdout(self):
624615
# stdout is set to 1 (#1531862).
@@ -767,7 +758,7 @@ def test_communicate_stderr(self):
767758
stderr=subprocess.PIPE)
768759
(stdout, stderr) = p.communicate()
769760
self.assertEqual(stdout, None)
770-
self.assertStderrEqual(stderr, b"pineapple")
761+
self.assertEqual(stderr, b"pineapple")
771762

772763
def test_communicate(self):
773764
p = subprocess.Popen([sys.executable, "-c",
@@ -782,7 +773,7 @@ def test_communicate(self):
782773
self.addCleanup(p.stdin.close)
783774
(stdout, stderr) = p.communicate(b"banana")
784775
self.assertEqual(stdout, b"banana")
785-
self.assertStderrEqual(stderr, b"pineapple")
776+
self.assertEqual(stderr, b"pineapple")
786777

787778
def test_communicate_timeout(self):
788779
p = subprocess.Popen([sys.executable, "-c",
@@ -801,7 +792,7 @@ def test_communicate_timeout(self):
801792
# after it completes.
802793
(stdout, stderr) = p.communicate()
803794
self.assertEqual(stdout, "banana")
804-
self.assertStderrEqual(stderr.encode(), b"pineapple\npear\n")
795+
self.assertEqual(stderr.encode(), b"pineapple\npear\n")
805796

806797
def test_communicate_timeout_large_output(self):
807798
# Test an expiring timeout while the child is outputting lots of data.
@@ -887,7 +878,7 @@ def test_writes_before_communicate(self):
887878
p.stdin.write(b"banana")
888879
(stdout, stderr) = p.communicate(b"split")
889880
self.assertEqual(stdout, b"bananasplit")
890-
self.assertStderrEqual(stderr, b"")
881+
self.assertEqual(stderr, b"")
891882

892883
def test_universal_newlines_and_text(self):
893884
args = [
@@ -1005,7 +996,6 @@ def test_universal_newlines_communicate_stdin_stdout_stderr(self):
1005996
self.assertEqual("line1\nline2\nline3\nline4\nline5\n", stdout)
1006997
# Python debug build push something like "[42442 refs]\n"
1007998
# to stderr at exit of subprocess.
1008-
# Don't use assertStderrEqual because it strips CR and LF from output.
1009999
self.assertTrue(stderr.startswith("eline2\neline6\neline7\n"))
10101000

10111001
def test_universal_newlines_communicate_encodings(self):
@@ -2240,13 +2230,13 @@ def test_send_signal(self):
22402230
def test_kill(self):
22412231
p = self._kill_process('kill')
22422232
_, stderr = p.communicate()
2243-
self.assertStderrEqual(stderr, b'')
2233+
self.assertEqual(stderr, b'')
22442234
self.assertEqual(p.wait(), -signal.SIGKILL)
22452235

22462236
def test_terminate(self):
22472237
p = self._kill_process('terminate')
22482238
_, stderr = p.communicate()
2249-
self.assertStderrEqual(stderr, b'')
2239+
self.assertEqual(stderr, b'')
22502240
self.assertEqual(p.wait(), -signal.SIGTERM)
22512241

22522242
def test_send_signal_dead(self):
@@ -2294,8 +2284,8 @@ def check_close_std_fds(self, fds):
22942284
stdin=stdin,
22952285
stdout=subprocess.PIPE,
22962286
stderr=subprocess.PIPE).communicate()
2297-
err = support.strip_python_stderr(err)
2298-
self.assertEqual((out, err), (b'apple', b'orange'))
2287+
self.assertEqual(out, b'apple')
2288+
self.assertEqual(err, b'orange')
22992289
finally:
23002290
self._restore_fds(saved_fds)
23012291

@@ -2380,7 +2370,7 @@ def test_remapping_std_fds(self):
23802370
os.lseek(fd, 0, 0)
23812371

23822372
out = os.read(temp_fds[2], 1024)
2383-
err = support.strip_python_stderr(os.read(temp_fds[0], 1024))
2373+
err = os.read(temp_fds[0], 1024).strip()
23842374
self.assertEqual(out, b"got STDIN")
23852375
self.assertEqual(err, b"err")
23862376

@@ -2422,7 +2412,7 @@ def check_swap_fds(self, stdin_no, stdout_no, stderr_no):
24222412
os.lseek(fd, 0, 0)
24232413

24242414
out = os.read(stdout_no, 1024)
2425-
err = support.strip_python_stderr(os.read(stderr_no, 1024))
2415+
err = os.read(stderr_no, 1024).strip()
24262416
finally:
24272417
self._restore_fds(saved_fds)
24282418

@@ -3338,7 +3328,7 @@ def _kill_process(self, method, *args):
33383328
p.stdout.read(1)
33393329
getattr(p, method)(*args)
33403330
_, stderr = p.communicate()
3341-
self.assertStderrEqual(stderr, b'')
3331+
self.assertEqual(stderr, b'')
33423332
returncode = p.wait()
33433333
self.assertNotEqual(returncode, 0)
33443334

@@ -3361,7 +3351,7 @@ def _kill_dead_process(self, method, *args):
33613351
# This shouldn't raise even though the child is now dead
33623352
getattr(p, method)(*args)
33633353
_, stderr = p.communicate()
3364-
self.assertStderrEqual(stderr, b'')
3354+
self.assertEqual(stderr, b'')
33653355
rc = p.wait()
33663356
self.assertEqual(rc, 42)
33673357

@@ -3550,7 +3540,7 @@ def test_pipe(self):
35503540
stdout=subprocess.PIPE,
35513541
stderr=subprocess.PIPE) as proc:
35523542
self.assertEqual(proc.stdout.read(), b"stdout")
3553-
self.assertStderrEqual(proc.stderr.read(), b"stderr")
3543+
self.assertEqual(proc.stderr.read(), b"stderr")
35543544

35553545
self.assertTrue(proc.stdout.closed)
35563546
self.assertTrue(proc.stderr.closed)

Lib/test/test_support.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,6 @@ def test_fd_count(self):
653653
# run_doctest
654654
# threading_cleanup
655655
# reap_threads
656-
# strip_python_stderr
657656
# can_symlink
658657
# skip_unless_symlink
659658
# SuppressCrashReport

Lib/test/test_warnings/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1219,7 +1219,8 @@ def __del__(self):
12191219
a=A()
12201220
"""
12211221
rc, out, err = assert_python_ok("-c", code)
1222-
self.assertEqual(err.decode(), '<string>:7: UserWarning: test')
1222+
self.assertEqual(err.decode().rstrip(),
1223+
'<string>:7: UserWarning: test')
12231224

12241225
def test_late_resource_warning(self):
12251226
# Issue #21925: Emitting a ResourceWarning late during the Python
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
:mod:`test.support`: :func:`~test.support.run_python_until_end`,
2+
:func:`~test.support.assert_python_ok` and
3+
:func:`~test.support.assert_python_failure` functions no longer strip
4+
whitespaces from stderr. Remove ``test.support.strip_python_stderr()``
5+
function.

0 commit comments

Comments
 (0)