only write to stdout buffer when buffer object is available

This commit is contained in:
Thijs Kramer 2021-10-19 19:33:52 +02:00
parent bcb88c4c3e
commit 9cde73f106
No known key found for this signature in database
GPG key ID: 3C93635D4D4710AA
2 changed files with 36 additions and 1 deletions

View file

@ -184,7 +184,15 @@ class BaseFormatter:
if self.output_fd is not None:
self.output_fd.write(output + self.newline)
if self.output_fd is None or self.options.tee:
sys.stdout.buffer.write(output.encode() + self.newline.encode())
# sys.stdout might be replaced, and thus could also be
# a file like object like io.StringIO, which do not
# support the 'buffer' attribute.
try:
sys.stdout.buffer.write(
output.encode() + self.newline.encode()
)
except AttributeError:
sys.stdout.write(output + self.newline)
def write(self, line: Optional[str], source: Optional[str]) -> None:
"""Write the line either to the output file or stdout.

View file

@ -136,6 +136,33 @@ def test_write_produces_stdout(capsys):
assert capsys.readouterr().out == f"{line}\n{source}\n"
def test_write_without_stdout_buffer():
"""Verify that stdout writes when it has no buffer."""
line = "Something to write"
source = "source"
buffer_side_effect = AttributeError(
"'_io.StringIO' object has no \
attribute 'buffer'"
)
buffer_write_mock = mock.Mock(side_effect=buffer_side_effect)
write_mock = mock.Mock()
mock.patch("flake8.formatting.base.sys.stdout.write", write_mock)
with mock.patch(
"flake8.formatting.base.sys.stdout.buffer.write", buffer_write_mock
):
formatter = base.BaseFormatter(options())
formatter.write(line, source)
assert write_mock.called is True
assert write_mock.call_count == 2
assert write_mock.mock_calls == [
mock.call(line + formatter.newline),
mock.call(source + formatter.newline),
]
class AfterInitFormatter(base.BaseFormatter):
"""Subclass for testing after_init."""