@@ -421,10 +421,12 @@ def regex_search(self, regex, output):
421
421
self .fail ("%r not found in %r" % (regex , output ))
422
422
return match
423
423
424
- def check_line (self , output , regex , full = False ):
424
+ def check_line (self , output , pattern , full = False , regex = True ):
425
+ if not regex :
426
+ pattern = re .escape (pattern )
425
427
if full :
426
- regex += '\n '
427
- regex = re .compile (r'^' + regex , re .MULTILINE )
428
+ pattern += '\n '
429
+ regex = re .compile (r'^' + pattern , re .MULTILINE )
428
430
self .assertRegex (output , regex )
429
431
430
432
def parse_executed_tests (self , output ):
@@ -1755,9 +1757,8 @@ def test_leak_tmp_file(self):
1755
1757
f"files (1): mytmpfile" ,
1756
1758
output )
1757
1759
1758
- def test_mp_decode_error (self ):
1759
- # gh-101634: If a worker stdout cannot be decoded, report a failed test
1760
- # and a non-zero exit code.
1760
+ def test_worker_decode_error (self ):
1761
+ # gh-109425: Use "backslashreplace" error handler to decode stdout.
1761
1762
if sys .platform == 'win32' :
1762
1763
encoding = locale .getencoding ()
1763
1764
else :
@@ -1767,29 +1768,41 @@ def test_mp_decode_error(self):
1767
1768
if encoding is None :
1768
1769
self .skipTest ("cannot get regrtest worker encoding" )
1769
1770
1770
- nonascii = b"byte:\xa0 \xa9 \xff \n "
1771
+ nonascii = bytes (ch for ch in range (128 , 256 ))
1772
+ corrupted_output = b"nonascii:%s\n " % (nonascii ,)
1773
+ # gh-108989: On Windows, assertion errors are written in UTF-16: when
1774
+ # decoded each letter is follow by a NUL character.
1775
+ assertion_failed = 'Assertion failed: tstate_is_alive(tstate)\n '
1776
+ corrupted_output += assertion_failed .encode ('utf-16-le' )
1771
1777
try :
1772
- nonascii .decode (encoding )
1778
+ corrupted_output .decode (encoding )
1773
1779
except UnicodeDecodeError :
1774
1780
pass
1775
1781
else :
1776
- self .skipTest (f"{ encoding } can decode non-ASCII bytes { nonascii !a} " )
1782
+ self .skipTest (f"{ encoding } can decode non-ASCII bytes" )
1783
+
1784
+ expected_line = corrupted_output .decode (encoding , 'backslashreplace' )
1777
1785
1778
1786
code = textwrap .dedent (fr"""
1779
1787
import sys
1788
+ import unittest
1789
+
1790
+ class Tests(unittest.TestCase):
1791
+ def test_pass(self):
1792
+ pass
1793
+
1780
1794
# bytes which cannot be decoded from UTF-8
1781
- nonascii = { nonascii !a}
1782
- sys.stdout.buffer.write(nonascii )
1795
+ corrupted_output = { corrupted_output !a}
1796
+ sys.stdout.buffer.write(corrupted_output )
1783
1797
sys.stdout.buffer.flush()
1784
1798
""" )
1785
1799
testname = self .create_test (code = code )
1786
1800
1787
- output = self .run_tests ("--fail-env-changed" , "-v" , "-j1" , testname ,
1788
- exitcode = EXITCODE_BAD_TEST )
1801
+ output = self .run_tests ("--fail-env-changed" , "-v" , "-j1" , testname )
1789
1802
self .check_executed_tests (output , [testname ],
1790
- failed = [testname ],
1791
1803
parallel = True ,
1792
- stats = 0 )
1804
+ stats = 1 )
1805
+ self .check_line (output , expected_line , regex = False )
1793
1806
1794
1807
def test_doctest (self ):
1795
1808
code = textwrap .dedent (r'''
0 commit comments