bpo-44666: Use default encoding as fallback for compile_file (GH-27236)

When sys.stdout.encoding is None compile_file will fall back to
sys.getdefaultencoding to encode/decode error messages.

Co-authored-by: Stefan Hoelzl <stefan.hoelzl@posteo.de>
Co-authored-by: Mickaël Schoentgen <contact@tiger-222.fr>
This commit is contained in:
Stefan Hoelzl 2021-07-30 18:38:42 +02:00 committed by GitHub
parent 7cad0bee80
commit 80f0707629
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 13 additions and 3 deletions

View File

@ -254,9 +254,8 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0,
else:
print('*** ', end='')
# escape non-printable characters in msg
msg = err.msg.encode(sys.stdout.encoding,
errors='backslashreplace')
msg = msg.decode(sys.stdout.encoding)
encoding = sys.stdout.encoding or sys.getdefaultencoding()
msg = err.msg.encode(encoding, errors='backslashreplace').decode(encoding)
print(msg)
except (SyntaxError, UnicodeError, OSError) as e:
success = False

View File

@ -169,6 +169,14 @@ class CompileallTestsBase:
compileall.compile_file(data_file)
self.assertFalse(os.path.exists(os.path.join(data_dir, '__pycache__')))
def test_compile_file_encoding_fallback(self):
# Bug 44666 reported that compile_file failed when sys.stdout.encoding is None
self.add_bad_source_file()
with contextlib.redirect_stdout(io.StringIO()):
self.assertFalse(compileall.compile_file(self.bad_source_path))
def test_optimize(self):
# make sure compiling with different optimization settings than the
# interpreter's creates the correct file names

View File

@ -794,6 +794,7 @@ Fredrik Håård
Florian Höch
Oleg Höfling
Robert Hölzl
Stefan Hölzl
Catalin Iacob
Mihai Ibanescu
Ali Ikinci

View File

@ -0,0 +1,2 @@
Fixed issue in :func:`compileall.compile_file` when ``sys.stdout`` is redirected.
Patch by Stefan Hölzl.