Skip to content

Commit

Permalink
Merge pull request python#9 from brettcannon/implement-read
Browse files Browse the repository at this point in the history
Implement read()
  • Loading branch information
brettcannon committed Oct 25, 2017
2 parents 61c76ef + 53747f5 commit be38279
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 4 deletions.
18 changes: 18 additions & 0 deletions importlib_resources/__init__.py
Expand Up @@ -54,3 +54,21 @@ def open(package: Package, file_name: Path) -> BinaryIO:
loader = typing.cast(importlib.abc.ResourceLoader, package.__spec__.loader)
data = loader.get_data(full_path)
return io.BytesIO(data)


def read(package: Package, file_name: Path, encoding: str = 'utf-8',
errors: str = 'strict') -> str:
"""Return the decoded string of the resource.
The decoding-related arguments have the same semantics as those of
bytes.decode().
"""
file_name = _normalize_path(file_name)
package = _get_package(package)
# Note this is **not** builtins.open()!
with open(package, file_name) as binary_file:
# Decoding from io.TextIOWrapper() instead of str.decode() in hopes that
# the former will be smarter about memory usage.
text_file = io.TextIOWrapper(binary_file, encoding=encoding,
errors=errors)
return text_file.read()
Binary file added importlib_resources/tests/data/utf-16.file
Binary file not shown.
2 changes: 1 addition & 1 deletion importlib_resources/tests/data/utf-8.file
@@ -1 +1 @@
Hello, world!
Hello, UTF-8 world!
6 changes: 3 additions & 3 deletions importlib_resources/tests/test_open.py
Expand Up @@ -35,7 +35,7 @@ def test_pathlib_path(self):

def test_absolute_path(self):
# An absolute path is a ValueError.
path = pathlib.Path(__spec__.origin)
path = pathlib.Path(__file__)
full_path = path.parent/'utf-8.file'
with self.assertRaises(ValueError):
with resources.open(data, str(full_path)) as file:
Expand Down Expand Up @@ -65,13 +65,13 @@ class OpenTests(unittest.TestCase):
def test_opened_for_reading(self):
# The file-like object is ready for reading.
with resources.open(data, 'utf-8.file') as file:
self.assertEqual(b"Hello, world!\n", file.read())
self.assertEqual(b"Hello, UTF-8 world!\n", file.read())

def test_wrap_for_text(self):
# The file-like object can be wrapped for text reading.
with resources.open(data, 'utf-8.file') as file:
text_file = io.TextIOWrapper(file, encoding='utf-8')
self.assertEqual('Hello, world!\n', text_file.read())
self.assertEqual('Hello, UTF-8 world!\n', text_file.read())


if __name__ == '__main__':
Expand Down
68 changes: 68 additions & 0 deletions importlib_resources/tests/test_read.py
@@ -0,0 +1,68 @@
import io
import os.path
import pathlib
import sys
import unittest

import importlib_resources as resources
from importlib_resources.tests import data


class CommonTests(unittest.TestCase):

def test_package_name(self):
# Passing in the package name should succeed.
resources.read(data.__name__, 'utf-8.file')

def test_package_object(self):
# Passing in the package itself should succeed.
resources.read(data, 'utf-8.file')

def test_string_path(self):
path = 'utf-8.file'
# Passing in a string for the path should succeed.
resources.read(data, path)

@unittest.skipIf(sys.version_info < (3, 6), 'requires os.PathLike support')
def test_pathlib_path(self):
# Passing in a pathlib.PurePath object for the path should succeed.
path = pathlib.PurePath('utf-8.file')
resources.read(data, path)

def test_absolute_path(self):
# An absolute path is a ValueError.
path = pathlib.Path(__file__)
full_path = path.parent/'utf-8.file'
with self.assertRaises(ValueError):
resources.read(data, str(full_path))

def test_relative_path(self):
# A reative path is a ValueError.
with self.assertRaises(ValueError):
resources.read(data, '../data/utf-8.file')

def test_importing_module_as_side_effect(self):
# The anchor package can already be imported.
del sys.modules[data.__name__]
resources.read(data.__name__, 'utf-8.file')

def test_non_package(self):
# The anchor package cannot be a module.
with self.assertRaises(TypeError):
resources.read(__spec__.name, 'utf-8.file')


class ReadTests(unittest.TestCase):

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

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

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

0 comments on commit be38279

Please sign in to comment.