Skip to content

Commit 973618a

Browse files
Gracefully handle encoding errors when writing to stdout (#18292)
Fixes #12692 Sets the [encoding error handler](https://docs.python.org/3/library/codecs.html#error-handlers) for `stdout` to `"backslashreplace"`. This prevents mypy from crashing if an error message has a character that can't be represented by the current I/O encoding. No change is made to `stderr` since its default is already `"backslashreplace"`. **Before** ```shell $ PYTHONIOENCODING=ascii mypy -c "x=γ" Traceback (most recent call last): ... UnicodeEncodeError: 'ascii' codec can't encode character '\u03b3' in position 50: ordinal not in range(128) ``` **After:** ```shell $ PYTHONIOENCODING=ascii mypy -c "x=γ" <string>:1: error: Name "\u03b3" is not defined [name-defined] Found 1 error in 1 file (checked 1 source file) ``` Externally setting the error handler to something other than `"strict"` still works. For example: ```shell $ PYTHONIOENCODING=ascii:namereplace mypy -c "x=γ" <string>:1: error: Name "\N{GREEK SMALL LETTER GAMMA}" is not defined [name-defined] Found 1 error in 1 file (checked 1 source file) ```
1 parent 7abcffe commit 973618a

File tree

1 file changed

+5
-0
lines changed

1 file changed

+5
-0
lines changed

mypy/main.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import time
1010
from collections import defaultdict
1111
from gettext import gettext
12+
from io import TextIOWrapper
1213
from typing import IO, Any, Final, NoReturn, Sequence, TextIO
1314

1415
from mypy import build, defaults, state, util
@@ -74,6 +75,10 @@ def main(
7475
if args is None:
7576
args = sys.argv[1:]
7677

78+
# Write an escape sequence instead of raising an exception on encoding errors.
79+
if isinstance(stdout, TextIOWrapper) and stdout.errors == "strict":
80+
stdout.reconfigure(errors="backslashreplace")
81+
7782
fscache = FileSystemCache()
7883
sources, options = process_options(args, stdout=stdout, stderr=stderr, fscache=fscache)
7984
if clean_exit:

0 commit comments

Comments
 (0)