Skip to content

Commit b01a3fe

Browse files
[fix] Permit to display the output even in case of unicode errors
Closes #8736
1 parent 32304fe commit b01a3fe

File tree

6 files changed

+35
-4
lines changed

6 files changed

+35
-4
lines changed

doc/whatsnew/fragments/8736.bugfix

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
When displaying unicode with surrogates (or other potential ``UnicodeEncodeError``),
2+
pylint will now display a '?' character (using ``encode(encoding="utf-8", errors="replace")``)
3+
instead of crashing. The functional tests classes are also updated to handle this case.
4+
5+
Closes #8736.

pylint/reporters/base_reporter.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,14 @@ def handle_message(self, msg: Message) -> None:
4242

4343
def writeln(self, string: str = "") -> None:
4444
"""Write a line in the output buffer."""
45-
print(string, file=self.out)
45+
try:
46+
print(string, file=self.out)
47+
except UnicodeEncodeError:
48+
print(self.reencode_output_after_unicode_error(string), file=self.out)
49+
50+
@staticmethod
51+
def reencode_output_after_unicode_error(string: str) -> str:
52+
return string.encode(encoding="utf-8", errors="replace").decode("utf8")
4653

4754
def display_reports(self, layout: Section) -> None:
4855
"""Display results encapsulated in the layout tree."""

pylint/testutils/functional/lint_module_output_update.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ def _check_output_text(
4040
with open(self._test_file.expected_output, "w", encoding="utf-8") as f:
4141
writer = csv.writer(f, dialect="test")
4242
for line in actual_output:
43-
writer.writerow(line.to_csv())
43+
self.safe_write_output_line(writer, line)

pylint/testutils/lint_module_test.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from collections import Counter
1212
from io import StringIO
1313
from pathlib import Path
14-
from typing import TextIO
14+
from typing import TYPE_CHECKING, TextIO
1515

1616
import pytest
1717
from _pytest.config import Config
@@ -20,6 +20,7 @@
2020
from pylint.config.config_initialization import _config_initialization
2121
from pylint.lint import PyLinter
2222
from pylint.message.message import Message
23+
from pylint.reporters import BaseReporter
2324
from pylint.testutils.constants import _EXPECTED_RE, _OPERATORS, UPDATE_OPTION
2425

2526
# need to import from functional.test_file to avoid cyclic import
@@ -31,6 +32,8 @@
3132
from pylint.testutils.output_line import OutputLine
3233
from pylint.testutils.reporter_for_tests import FunctionalTestReporter
3334

35+
if TYPE_CHECKING:
36+
import _csv
3437
MessageCounter = Counter[tuple[int, str]]
3538

3639
PYLINTRC = Path(__file__).parent / "testing_pylintrc"
@@ -309,10 +312,22 @@ def error_msg_for_unequal_output(
309312
expected_csv = StringIO()
310313
writer = csv.writer(expected_csv, dialect="test")
311314
for line in sorted(received_lines, key=sort_by_line_number):
312-
writer.writerow(line.to_csv())
315+
self.safe_write_output_line(writer, line)
313316
error_msg += expected_csv.getvalue()
314317
return error_msg
315318

319+
def safe_write_output_line(self, writer: _csv._writer, line: OutputLine) -> None:
320+
"""Write an OutputLine to the CSV writer, handling UnicodeEncodeError."""
321+
try:
322+
writer.writerow(line.to_csv())
323+
except UnicodeEncodeError:
324+
writer.writerow(
325+
[
326+
BaseReporter.reencode_output_after_unicode_error(s)
327+
for s in line.to_csv()
328+
]
329+
)
330+
316331
def _check_output_text(
317332
self,
318333
_: MessageCounter,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""This does not crash in the functional tests, but it did when called directly."""
2+
3+
assert "\U00010000" == "\ud800\udc00" # [comparison-of-constants]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
comparison-of-constants:3:7:3:37::"Comparison between constants: '𐀀 == ??' has a constant value":HIGH

0 commit comments

Comments
 (0)