8000 bpo-34421: Improve distutils logging for non-ASCII strings. (GH-9126)… · python/cpython@0b67995 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0b67995

Browse files
bpo-34421: Improve distutils logging for non-ASCII strings. (GH-9126) (GH-9506)
Use "backslashreplace" instead of "unicode-escape". It is not implementation depended and escapes only non-encodable characters. Also simplify the code. (cherry picked from commit 8000 4b860fd) (cherry picked from commit c73df53) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
1 parent 94812f7 commit 0b67995

File tree

2 files changed

+32
-25
lines changed

2 files changed

+32
-25
lines changed

Lib/distutils/log.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,13 @@ def _log(self, level, msg, args):
2727
stream = sys.stderr
2828
else:
2929
stream = sys.stdout
30-
if stream.errors == 'strict':
30+
try:
31+
stream.write('%s\n' % msg)
32+
except UnicodeEncodeError:
3133
# emulate backslashreplace error handler
3234
encoding = stream.encoding
3335
msg = msg.encode(encoding, "backslashreplace").decode(encoding)
34-
try:
3536
stream.write('%s\n' % msg)
36-
except UnicodeEncodeError:
37-
stream.write('%s\n' % msg.encode('unicode-escape').decode('ascii'))
3837
stream.flush()
3938

4039
def log(self, level, msg, *args):

Lib/distutils/tests/test_log.py

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,43 @@
11
"""Tests for distutils.log"""
22

3+
import io
34
import sys
45
import unittest
5-
from tempfile import NamedTemporaryFile
6-
from test.support import run_unittest
6+
from test.support import swap_attr, run_unittest
77

88
from distutils import log
99

1010
class TestLog(unittest.TestCase):
1111
def test_non_ascii(self):
12-
# Issue #8663: test that non-ASCII text is escaped with
13-
# backslashreplace error handler (stream use ASCII encoding and strict
14-
# error handler)
15-
old_stdout = sys.stdout
16-
old_stderr = sys.stderr
17-
old_threshold = log.set_threshold(log.DEBUG)
18-
try:
19-
with NamedTemporaryFile(mode="w+", encoding='ascii') as stdout, \
20-
NamedTemporaryFile(mode="w+", encoding='ascii') as stderr:
21-
sys.stdout = stdout
22-
sys.stderr = stderr
23-
log.debug("debug:\xe9")
24-
log.fatal("fatal:\xe9")
12+
# Issues #8663, #34421: test that non-encodable text is escaped with
13+
# backslashreplace error handler and encodable non-ASCII text is
14+
# output as is.
15+
for errors in ('strict', 'backslashreplace', 'surrogateescape',
16+
'replace', 'ignore'):
17+
with self.subTest(errors=errors):
18+
stdout = io.TextIOWrapper(io.BytesIO(),
19+
encoding='cp437', errors=errors)
20+
stderr = io.TextIOWrapper(io.BytesIO(),
21+
encoding='cp437', errors=errors)
22+
old_threshold = log.set_threshold(log.DEBUG)
23+
try:
24+
with swap_attr(sys, 'stdout', stdout), \
25+
swap_attr(sys, 'stderr', stderr):
26+
log.debug('Dεbug\tMėssãge')
27+
log.fatal('Fαtal\tÈrrōr')
28+
8000 finally:
29+
log.set_threshold(old_threshold)
30+
2531
stdout.seek(0)
26-
self.assertEqual(stdout.read().rstrip(), "debug:\\xe9")
32+
self.assertEqual(stdout.read().rstrip(),
33+
'Dεbug\tM?ss?ge' if errors == 'replace' else
34+
'Dεbug\tMssge' if errors == 'ignore' else
35+
'Dεbug\tM\\u0117ss\\xe3ge')
2736
stderr.seek(0)
28-
self.assertEqual(stderr.read().rstrip(), "fatal:\\xe9")
29-
finally:
30-
log.set_threshold(old_threshold)
31-
sys.stdout = old_stdout
32-
sys.stderr = old_stderr
37+
self.assertEqual(stderr.read().rstrip(),
38+
'Fαtal\t?rr?r' if errors == 'replace' else
39+
'Fαtal\trrr' if errors == 'ignore' else
40+
'Fαtal\t\\xc8rr\\u014dr')
3341

3442
def test_suite():
3543
return unittest.makeSuite(TestLog)

0 commit comments

Comments
 (0)
0