Merge pull request #6566 from blueyed/rm-encodedfile-writelines

Fix `EncodedFile.writelines`
This commit is contained in:
Daniel Hahler 2020-01-27 22:58:31 +01:00 committed by GitHub
commit 20b66e60c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 13 deletions

View File

@ -0,0 +1 @@
Fix ``EncodedFile.writelines`` to call the underlying buffer's ``writelines`` method.

View File

@ -9,6 +9,8 @@ import os
import sys
from io import UnsupportedOperation
from tempfile import TemporaryFile
from typing import BinaryIO
from typing import Iterable
import pytest
from _pytest.compat import CaptureIO
@ -413,30 +415,27 @@ def safe_text_dupfile(f, mode, default_encoding="UTF8"):
class EncodedFile:
errors = "strict" # possibly needed by py3 code (issue555)
def __init__(self, buffer, encoding):
def __init__(self, buffer: BinaryIO, encoding: str) -> None:
self.buffer = buffer
self.encoding = encoding
def write(self, obj):
if isinstance(obj, str):
obj = obj.encode(self.encoding, "replace")
else:
def write(self, s: str) -> int:
if not isinstance(s, str):
raise TypeError(
"write() argument must be str, not {}".format(type(obj).__name__)
"write() argument must be str, not {}".format(type(s).__name__)
)
return self.buffer.write(obj)
return self.buffer.write(s.encode(self.encoding, "replace"))
def writelines(self, linelist):
data = "".join(linelist)
self.write(data)
def writelines(self, lines: Iterable[str]) -> None:
self.buffer.writelines(x.encode(self.encoding, "replace") for x in lines)
@property
def name(self):
def name(self) -> str:
"""Ensure that file.name is a string."""
return repr(self.buffer)
@property
def mode(self):
def mode(self) -> str:
return self.buffer.mode.replace("b", "")
def __getattr__(self, name):

View File

@ -7,6 +7,8 @@ import sys
import textwrap
from io import StringIO
from io import UnsupportedOperation
from typing import BinaryIO
from typing import Generator
from typing import List
from typing import TextIO
@ -831,7 +833,7 @@ def test_dontreadfrominput():
@pytest.fixture
def tmpfile(testdir):
def tmpfile(testdir) -> Generator[BinaryIO, None, None]:
f = testdir.makepyfile("").open("wb+")
yield f
if not f.closed:
@ -1497,3 +1499,15 @@ def test_typeerror_encodedfile_write(testdir):
def test_stderr_write_returns_len(capsys):
"""Write on Encoded files, namely captured stderr, should return number of characters written."""
assert sys.stderr.write("Foo") == 3
def test_encodedfile_writelines(tmpfile: BinaryIO) -> None:
ef = capture.EncodedFile(tmpfile, "utf-8")
with pytest.raises(AttributeError):
ef.writelines([b"line1", b"line2"]) # type: ignore[list-item] # noqa: F821
assert ef.writelines(["line1", "line2"]) is None # type: ignore[func-returns-value] # noqa: F821
tmpfile.seek(0)
assert tmpfile.read() == b"line1line2"
tmpfile.close()
with pytest.raises(ValueError):
ef.read()