Skip to content

Commit

Permalink
Support binary read when encoding=None (python#29)
Browse files Browse the repository at this point in the history
Closes python#28
  • Loading branch information
warsaw authored Nov 30, 2017
1 parent 1f0aeb8 commit f1ccb15
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 5 deletions.
5 changes: 4 additions & 1 deletion importlib_resources/_py2.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ def read(package, file_name, encoding='utf-8', errors='strict'):
package = _get_package(package)
# Note this is **not** builtins.open()!
with open(package, file_name) as binary_file:
return binary_file.read().decode(encoding=encoding, errors=errors)
contents = binary_file.read()
if encoding is None:
return contents
return contents.decode(encoding=encoding, errors=errors)


@contextmanager
Expand Down
8 changes: 6 additions & 2 deletions importlib_resources/_py3.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,10 @@ def open(package: Package, file_name: FileName) -> BinaryIO:
return BytesIO(data)


def read(package: Package, file_name: FileName, encoding: str = 'utf-8',
errors: str = 'strict') -> str:
def read(package: Package,
file_name: FileName,
encoding: str = 'utf-8',
errors: str = 'strict') -> Union[str, bytes]:
"""Return the decoded string of the resource.
The decoding-related arguments have the same semantics as those of
Expand All @@ -88,6 +90,8 @@ def read(package: Package, file_name: FileName, encoding: str = 'utf-8',
package = _get_package(package)
# Note this is **not** builtins.open()!
with open(package, file_name) as binary_file:
if encoding is None:
return binary_file.read()
# Decoding from io.TextIOWrapper() instead of str.decode() in hopes
# that the former will be smarter about memory usage.
text_file = TextIOWrapper(
Expand Down
Binary file added importlib_resources/tests/data/binary.file
Binary file not shown.
Binary file modified importlib_resources/tests/data/ziptestdata.zip
Binary file not shown.
8 changes: 6 additions & 2 deletions importlib_resources/tests/test_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,21 @@ class ReadTests:

def test_default_encoding(self):
result = resources.read(self.data, 'utf-8.file')
self.assertEqual("Hello, UTF-8 world!\n", result)
self.assertEqual('Hello, UTF-8 world!\n', result)

def test_encoding(self):
result = resources.read(self.data, 'utf-16.file', encoding='utf-16')
self.assertEqual("Hello, UTF-16 world!\n", result)
self.assertEqual('Hello, UTF-16 world!\n', result)

def test_errors(self):
# Raises UnicodeError without the 'errors' argument.
resources.read(
self.data, 'utf-16.file', encoding='utf-8', errors='ignore')

def test_no_encoding(self):
result = resources.read(self.data, 'binary.file', encoding=None)
self.assertEqual(b'\0\1\2\3', result)


class ReadDiskTests(ReadTests, unittest.TestCase):

Expand Down
33 changes: 33 additions & 0 deletions update-tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env python3

"""Remake the ziptestdata.zip file.
Run this to rebuild the importlib_resources/tests/data/ziptestdata.zip file,
e.g. if you want to add a new file to the zip.
This will replace the file with the new build, but it won't commit anything to
git.
"""

import os
from zipfile import ZipFile

RELPATH = 'importlib_resources/tests/data'
CONTENTS = [
# filenames - the source will always be prepended by
# importlib_resources/tests/data/ziptestdata.zip and the destination will
# always be prepended by ziptestdata/
'__init__.py',
'binary.file',
'utf-16.file',
'utf-8.file',
]


zip_file_path = os.path.join(RELPATH, 'ziptestdata.zip')

with ZipFile(zip_file_path, 'w') as zf:
for filename in CONTENTS:
src = os.path.join(RELPATH, filename)
dst = os.path.join('ziptestdata', filename)
zf.write(src, dst)

0 comments on commit f1ccb15

Please sign in to comment.