From 60d6b6e6659ca3e94722cd768caf4e5c6369b4a1 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Sun, 3 Nov 2019 12:51:40 -0800 Subject: [PATCH] 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). --- Tests/test_file_container.py | 40 ++++++++++++++++++------------------ docs/handbook/tutorial.rst | 12 +++++------ src/PIL/ContainerIO.py | 6 +++--- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/Tests/test_file_container.py b/Tests/test_file_container.py index 2f931fb68..6abf5cc14 100644 --- a/Tests/test_file_container.py +++ b/Tests/test_file_container.py @@ -19,7 +19,7 @@ class TestFileContainer(PillowTestCase): def test_seek_mode_0(self): # Arrange mode = 0 - with open(TEST_FILE) as fh: + with open(TEST_FILE, "rb") as fh: container = ContainerIO.ContainerIO(fh, 22, 100) # Act @@ -32,7 +32,7 @@ class TestFileContainer(PillowTestCase): def test_seek_mode_1(self): # Arrange mode = 1 - with open(TEST_FILE) as fh: + with open(TEST_FILE, "rb") as fh: container = ContainerIO.ContainerIO(fh, 22, 100) # Act @@ -45,7 +45,7 @@ class TestFileContainer(PillowTestCase): def test_seek_mode_2(self): # Arrange mode = 2 - with open(TEST_FILE) as fh: + with open(TEST_FILE, "rb") as fh: container = ContainerIO.ContainerIO(fh, 22, 100) # Act @@ -57,7 +57,7 @@ class TestFileContainer(PillowTestCase): def test_read_n0(self): # Arrange - with open(TEST_FILE) as fh: + with open(TEST_FILE, "rb") as fh: container = ContainerIO.ContainerIO(fh, 22, 100) # Act @@ -65,11 +65,11 @@ class TestFileContainer(PillowTestCase): data = container.read() # 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): # Arrange - with open(TEST_FILE) as fh: + with open(TEST_FILE, "rb") as fh: container = ContainerIO.ContainerIO(fh, 22, 100) # Act @@ -77,11 +77,11 @@ class TestFileContainer(PillowTestCase): data = container.read(3) # Assert - self.assertEqual(data, "7\nT") + self.assertEqual(data, b"7\nT") def test_read_eof(self): # Arrange - with open(TEST_FILE) as fh: + with open(TEST_FILE, "rb") as fh: container = ContainerIO.ContainerIO(fh, 22, 100) # Act @@ -89,32 +89,32 @@ class TestFileContainer(PillowTestCase): data = container.read() # Assert - self.assertEqual(data, "") + self.assertEqual(data, b"") def test_readline(self): # Arrange - with open(TEST_FILE) as fh: + with open(TEST_FILE, "rb") as fh: container = ContainerIO.ContainerIO(fh, 0, 120) # Act data = container.readline() # Assert - self.assertEqual(data, "This is line 1\n") + self.assertEqual(data, b"This is line 1\n") def test_readlines(self): # Arrange expected = [ - "This is line 1\n", - "This is line 2\n", - "This is line 3\n", - "This is line 4\n", - "This is line 5\n", - "This is line 6\n", - "This is line 7\n", - "This is line 8\n", + b"This is line 1\n", + b"This is line 2\n", + b"This is line 3\n", + b"This is line 4\n", + b"This is line 5\n", + b"This is line 6\n", + b"This is line 7\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) # Act diff --git a/docs/handbook/tutorial.rst b/docs/handbook/tutorial.rst index e5da549c3..b5f3b4e96 100644 --- a/docs/handbook/tutorial.rst +++ b/docs/handbook/tutorial.rst @@ -468,17 +468,17 @@ Reading from an open file with open("hopper.ppm", "rb") as fp: im = Image.open(fp) -To read an image from string data, use the :py:class:`~StringIO.StringIO` -class: +To read an image from bytes data, use the :py:class:`io.BytesIO` class: -Reading from a string -^^^^^^^^^^^^^^^^^^^^^ +Reading from a byte string +^^^^^^^^^^^^^^^^^^^^^^^^^^ :: + import io 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 image header. In addition, seek will also be used when the image data is read diff --git a/src/PIL/ContainerIO.py b/src/PIL/ContainerIO.py index 3cf9d82d2..b8a3d0582 100644 --- a/src/PIL/ContainerIO.py +++ b/src/PIL/ContainerIO.py @@ -82,7 +82,7 @@ class ContainerIO(object): else: n = self.length - self.pos if not n: # EOF - return "" + return b"" self.pos = self.pos + n return self.fh.read(n) @@ -92,13 +92,13 @@ class ContainerIO(object): :returns: An 8-bit string. """ - s = "" + s = b"" while True: c = self.read(1) if not c: break s = s + c - if c == "\n": + if c == b"\n": break return s