Correct str/bytes mixup in ContainerIO

Image data is expected to be read in bytes mode, not text mode so
ContainerIO should return bytes in all methods. The passed in file
handler is expected to be opened in bytes mode (as TarIO already does).
This commit is contained in:
Jon Dufresne 2019-11-03 12:51:40 -08:00
parent 69a51877c4
commit 60d6b6e665
3 changed files with 29 additions and 29 deletions

View File

@ -19,7 +19,7 @@ class TestFileContainer(PillowTestCase):
def test_seek_mode_0(self): def test_seek_mode_0(self):
# Arrange # Arrange
mode = 0 mode = 0
with open(TEST_FILE) as fh: with open(TEST_FILE, "rb") as fh:
container = ContainerIO.ContainerIO(fh, 22, 100) container = ContainerIO.ContainerIO(fh, 22, 100)
# Act # Act
@ -32,7 +32,7 @@ class TestFileContainer(PillowTestCase):
def test_seek_mode_1(self): def test_seek_mode_1(self):
# Arrange # Arrange
mode = 1 mode = 1
with open(TEST_FILE) as fh: with open(TEST_FILE, "rb") as fh:
container = ContainerIO.ContainerIO(fh, 22, 100) container = ContainerIO.ContainerIO(fh, 22, 100)
# Act # Act
@ -45,7 +45,7 @@ class TestFileContainer(PillowTestCase):
def test_seek_mode_2(self): def test_seek_mode_2(self):
# Arrange # Arrange
mode = 2 mode = 2
with open(TEST_FILE) as fh: with open(TEST_FILE, "rb") as fh:
container = ContainerIO.ContainerIO(fh, 22, 100) container = ContainerIO.ContainerIO(fh, 22, 100)
# Act # Act
@ -57,7 +57,7 @@ class TestFileContainer(PillowTestCase):
def test_read_n0(self): def test_read_n0(self):
# Arrange # Arrange
with open(TEST_FILE) as fh: with open(TEST_FILE, "rb") as fh:
container = ContainerIO.ContainerIO(fh, 22, 100) container = ContainerIO.ContainerIO(fh, 22, 100)
# Act # Act
@ -65,11 +65,11 @@ class TestFileContainer(PillowTestCase):
data = container.read() data = container.read()
# Assert # Assert
self.assertEqual(data, "7\nThis is line 8\n") self.assertEqual(data, b"7\nThis is line 8\n")
def test_read_n(self): def test_read_n(self):
# Arrange # Arrange
with open(TEST_FILE) as fh: with open(TEST_FILE, "rb") as fh:
container = ContainerIO.ContainerIO(fh, 22, 100) container = ContainerIO.ContainerIO(fh, 22, 100)
# Act # Act
@ -77,11 +77,11 @@ class TestFileContainer(PillowTestCase):
data = container.read(3) data = container.read(3)
# Assert # Assert
self.assertEqual(data, "7\nT") self.assertEqual(data, b"7\nT")
def test_read_eof(self): def test_read_eof(self):
# Arrange # Arrange
with open(TEST_FILE) as fh: with open(TEST_FILE, "rb") as fh:
container = ContainerIO.ContainerIO(fh, 22, 100) container = ContainerIO.ContainerIO(fh, 22, 100)
# Act # Act
@ -89,32 +89,32 @@ class TestFileContainer(PillowTestCase):
data = container.read() data = container.read()
# Assert # Assert
self.assertEqual(data, "") self.assertEqual(data, b"")
def test_readline(self): def test_readline(self):
# Arrange # Arrange
with open(TEST_FILE) as fh: with open(TEST_FILE, "rb") as fh:
container = ContainerIO.ContainerIO(fh, 0, 120) container = ContainerIO.ContainerIO(fh, 0, 120)
# Act # Act
data = container.readline() data = container.readline()
# Assert # Assert
self.assertEqual(data, "This is line 1\n") self.assertEqual(data, b"This is line 1\n")
def test_readlines(self): def test_readlines(self):
# Arrange # Arrange
expected = [ expected = [
"This is line 1\n", b"This is line 1\n",
"This is line 2\n", b"This is line 2\n",
"This is line 3\n", b"This is line 3\n",
"This is line 4\n", b"This is line 4\n",
"This is line 5\n", b"This is line 5\n",
"This is line 6\n", b"This is line 6\n",
"This is line 7\n", b"This is line 7\n",
"This is line 8\n", b"This is line 8\n",
] ]
with open(TEST_FILE) as fh: with open(TEST_FILE, "rb") as fh:
container = ContainerIO.ContainerIO(fh, 0, 120) container = ContainerIO.ContainerIO(fh, 0, 120)
# Act # Act

View File

@ -468,17 +468,17 @@ Reading from an open file
with open("hopper.ppm", "rb") as fp: with open("hopper.ppm", "rb") as fp:
im = Image.open(fp) im = Image.open(fp)
To read an image from string data, use the :py:class:`~StringIO.StringIO` To read an image from bytes data, use the :py:class:`io.BytesIO` class:
class:
Reading from a string Reading from a byte string
^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
:: ::
import io
from PIL import Image from PIL import Image
import StringIO
im = Image.open(StringIO.StringIO(buffer)) im = Image.open(io.BytesIO(buffer))
Note that the library rewinds the file (using ``seek(0)``) before reading the Note that the library rewinds the file (using ``seek(0)``) before reading the
image header. In addition, seek will also be used when the image data is read image header. In addition, seek will also be used when the image data is read

View File

@ -82,7 +82,7 @@ class ContainerIO(object):
else: else:
n = self.length - self.pos n = self.length - self.pos
if not n: # EOF if not n: # EOF
return "" return b""
self.pos = self.pos + n self.pos = self.pos + n
return self.fh.read(n) return self.fh.read(n)
@ -92,13 +92,13 @@ class ContainerIO(object):
:returns: An 8-bit string. :returns: An 8-bit string.
""" """
s = "" s = b""
while True: while True:
c = self.read(1) c = self.read(1)
if not c: if not c:
break break
s = s + c s = s + c
if c == "\n": if c == b"\n":
break break
return s return s