Skip to content

Commit

Permalink
Gracefully handle encoding errors when writing to stdout (#18292)
Browse files Browse the repository at this point in the history
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)
```
  • Loading branch information
brianschubert authored Dec 14, 2024
1 parent 7abcffe commit 973618a
Showing 1 changed file with 5 additions and 0 deletions.
5 changes: 5 additions & 0 deletions mypy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import time
from collections import defaultdict
from gettext import gettext
from io import TextIOWrapper
from typing import IO, Any, Final, NoReturn, Sequence, TextIO

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

# Write an escape sequence instead of raising an exception on encoding errors.
if isinstance(stdout, TextIOWrapper) and stdout.errors == "strict":
stdout.reconfigure(errors="backslashreplace")

fscache = FileSystemCache()
sources, options = process_options(args, stdout=stdout, stderr=stderr, fscache=fscache)
if clean_exit:
Expand Down

0 comments on commit 973618a

Please sign in to comment.