Issue #23004: mock_open() now reads binary data correctly when the type of read_data is bytes.

Initial patch by Aaron Hill.
This commit is contained in:
Berker Peksag 2015-08-06 13:15:51 +03:00
parent 0b2833eaf2
commit 86b34da5ef
3 changed files with 35 additions and 3 deletions

View file

@ -2250,9 +2250,10 @@ def _iterate_read_data(read_data):
# Helper for mock_open: # Helper for mock_open:
# Retrieve lines from read_data via a generator so that separate calls to # Retrieve lines from read_data via a generator so that separate calls to
# readline, read, and readlines are properly interleaved # readline, read, and readlines are properly interleaved
data_as_list = ['{}\n'.format(l) for l in read_data.split('\n')] sep = b'\n' if isinstance(read_data, bytes) else '\n'
data_as_list = [l + sep for l in read_data.split(sep)]
if data_as_list[-1] == '\n': if data_as_list[-1] == sep:
# If the last line ended in a newline, the list comprehension will have an # If the last line ended in a newline, the list comprehension will have an
# extra entry that's just a newline. Remove this. # extra entry that's just a newline. Remove this.
data_as_list = data_as_list[:-1] data_as_list = data_as_list[:-1]
@ -2286,7 +2287,7 @@ def mock_open(mock=None, read_data=''):
def _read_side_effect(*args, **kwargs): def _read_side_effect(*args, **kwargs):
if handle.read.return_value is not None: if handle.read.return_value is not None:
return handle.read.return_value return handle.read.return_value
return ''.join(_state[0]) return type(read_data)().join(_state[0])
def _readline_side_effect(): def _readline_side_effect():
if handle.readline.return_value is not None: if handle.readline.return_value is not None:

View file

@ -224,6 +224,34 @@ class TestMockOpen(unittest.TestCase):
self.assertEqual(result, ['foo\n', 'bar\n', 'baz']) self.assertEqual(result, ['foo\n', 'bar\n', 'baz'])
def test_read_bytes(self):
mock = mock_open(read_data=b'\xc6')
with patch('%s.open' % __name__, mock, create=True):
with open('abc', 'rb') as f:
result = f.read()
self.assertEqual(result, b'\xc6')
def test_readline_bytes(self):
m = mock_open(read_data=b'abc\ndef\nghi\n')
with patch('%s.open' % __name__, m, create=True):
with open('abc', 'rb') as f:
line1 = f.readline()
line2 = f.readline()
line3 = f.readline()
self.assertEqual(line1, b'abc\n')
self.assertEqual(line2, b'def\n')
self.assertEqual(line3, b'ghi\n')
def test_readlines_bytes(self):
m = mock_open(read_data=b'abc\ndef\nghi\n')
with patch('%s.open' % __name__, m, create=True):
with open('abc', 'rb') as f:
result = f.readlines()
self.assertEqual(result, [b'abc\n', b'def\n', b'ghi\n'])
def test_mock_open_read_with_argument(self): def test_mock_open_read_with_argument(self):
# At one point calling read with an argument was broken # At one point calling read with an argument was broken
# for mocks returned by mock_open # for mocks returned by mock_open

View file

@ -71,6 +71,9 @@ Library
- Issue #23888: Handle fractional time in cookie expiry. Patch by ssh. - Issue #23888: Handle fractional time in cookie expiry. Patch by ssh.
- Issue #23004: mock_open() now reads binary data correctly when the type of
read_data is bytes. Initial patch by Aaron Hill.
- Issue #23652: Make it possible to compile the select module against the - Issue #23652: Make it possible to compile the select module against the
libc headers from the Linux Standard Base, which do not include some libc headers from the Linux Standard Base, which do not include some
EPOLL macros. Patch by Matt Frank. EPOLL macros. Patch by Matt Frank.