import sys
is_monty = sys.platform == 'monty'
is_windows = sys.platform == 'win32'
text_file = open(root / 'hello.txt')
assert str(type(text_file)) == "<class '_io.TextIOWrapper'>"
assert text_file.mode == 'r'
assert text_file.readable() == True
assert text_file.writable() == False
assert text_file.read() == 'hello world\n'
assert text_file.read() == ''
assert text_file.read() == ''
assert text_file.seekable() == True
text_file.close()
assert text_file.closed == True
binary_file = open(root / 'data.bin', 'rb')
assert str(type(binary_file)) == "<class '_io.BufferedReader'>"
assert binary_file.mode == 'rb'
assert binary_file.read() == b'\x00\x01\x02\x03'
assert binary_file.read() == b''
binary_file.close()
writer = open(root / 'open_write.txt', 'w')
assert str(type(writer)) == "<class '_io.TextIOWrapper'>"
assert writer.readable() == False
assert writer.writable() == True
assert writer.write('alpha') == 5
assert writer.write('\nβ') == 2
writer.flush()
writer.close()
assert (root / 'open_write.txt').read_text() == 'alpha\nβ'
append_writer = open(root / 'open_write.txt', 'a')
assert append_writer.write('!') == 1
append_writer.close()
assert (root / 'open_write.txt').read_text() == 'alpha\nβ!'
new_append_writer = open(root / 'open_new_append.txt', 'a')
assert new_append_writer.write('created') == 7
new_append_writer.close()
assert (root / 'open_new_append.txt').read_text() == 'created'
binary_writer = open(root / 'open_bytes.bin', 'wb')
assert str(type(binary_writer)) == "<class '_io.BufferedWriter'>"
assert binary_writer.write(b'\x10\x11') == 2
assert binary_writer.write(b'\x12') == 1
binary_writer.close()
assert (root / 'open_bytes.bin').read_bytes() == b'\x10\x11\x12'
binary_append = open(root / 'open_bytes.bin', 'ab')
assert binary_append.write(b'\x13') == 1
binary_append.close()
assert (root / 'open_bytes.bin').read_bytes() == b'\x10\x11\x12\x13'
f = open(root / 'hello.txt')
assert f == f
g = open(root / 'hello.txt')
assert f != g
f.close()
g.close()
if is_monty:
for mode in ('r+', 'rb+', 'r+b', 'w+', 'wb+', 'a+', 'ab+'):
try:
open(root / 'open_bytes.bin', mode)
assert False, f'expected ValueError for + mode {mode!r}'
except ValueError as exc:
assert str(exc) == "update modes ('+') are not yet supported", (
f'unexpected + mode rejection for {mode!r}: {exc}'
)
keyword_file = open(file=root / 'hello.txt', mode='r', encoding='utf-8')
assert keyword_file.read() == 'hello world\n'
keyword_file.close()
hello_bytes = str(root / 'hello.txt').encode('utf-8')
bytes_path_file = open(hello_bytes)
assert bytes_path_file.read() == 'hello world\n'
bytes_path_file.close()
positional = open(root / 'hello.txt', 'r', -1, 'utf-8', None, None, True, None)
assert positional.read() == 'hello world\n'
positional.close()
kw_closefd = open(root / 'hello.txt', closefd=True, opener=None)
kw_closefd.close()
if is_monty:
for kwarg_name, kwarg_value in (
('buffering', 0),
('encoding', 'latin-1'),
('errors', 'strict'),
('newline', ''),
('closefd', False),
):
try:
open(root / 'hello.txt', **{kwarg_name: kwarg_value})
assert False, f'expected non-default {kwarg_name}={kwarg_value!r} to fail'
except TypeError as exc:
assert str(exc) == f"'{kwarg_name}' argument is not yet supported", (
f'unexpected message for {kwarg_name}={kwarg_value!r}: {exc}'
)
(root / 'open_trunc.txt').write_text('previous contents')
trunc = open(root / 'open_trunc.txt', 'w')
assert (root / 'open_trunc.txt').read_text() == ''
trunc.close()
assert (root / 'open_trunc.txt').read_text() == ''
opened_w = open(root / 'open_created_w.txt', 'w')
opened_w.close()
assert (root / 'open_created_w.txt').read_text() == ''
opened_a = open(root / 'open_created_a.txt', 'a')
opened_a.close()
assert (root / 'open_created_a.txt').read_text() == ''
(root / 'open_keep_a.txt').write_text('keep me')
keep = open(root / 'open_keep_a.txt', 'a')
assert (root / 'open_keep_a.txt').read_text() == 'keep me'
keep.write('!')
keep.close()
assert (root / 'open_keep_a.txt').read_text() == 'keep me!'
(root / 'open_trunc.bin').write_bytes(b'\xff\xfe')
btrunc = open(root / 'open_trunc.bin', 'wb')
assert (root / 'open_trunc.bin').read_bytes() == b''
btrunc.close()
try:
open(root / 'open_missing.txt', 'r')
assert False, 'expected FileNotFoundError opening a missing file for read'
except FileNotFoundError as exc:
if is_monty:
assert str(exc) == "[Errno 2] No such file or directory: '/mnt/open_missing.txt'", (
f'unexpected missing-file message: {exc}'
)
elif not is_windows:
assert str(exc).startswith("[Errno 2] No such file or directory: '"), f'exc message: {exc}'
try:
open(root, 'r')
assert False, 'expected IsADirectoryError opening a directory for read'
except IsADirectoryError as exc:
if is_monty:
assert str(exc) == "[Errno 21] Is a directory: '/mnt'", f'unexpected is-a-directory message: {exc}'
elif not is_windows:
assert str(exc).startswith('[Errno 21] Is a directory: '), f'exc message: {exc}'
try:
text_file.read()
assert False, 'expected read after close to fail'
except ValueError as exc:
assert str(exc) == 'I/O operation on closed file.', f'unexpected closed-file message: {exc}'
closed_writer = open(root / 'open_closed.txt', 'w')
closed_writer.close()
try:
closed_writer.write('payload' + str(1))
assert False, 'expected write after close to fail'
except ValueError as exc:
assert str(exc) == 'I/O operation on closed file.', f'unexpected closed-write message: {exc}'
try:
open(root / 'hello.txt', encoding=123)
assert False, 'expected non-str encoding to fail'
except TypeError as exc:
assert str(exc) == "open() argument 'encoding' must be str or None, not int", (
f'unexpected encoding type message: {exc}'
)
for bad, expected_type in ((42, 'int'), (None, 'None'), (b'r', 'bytes')):
try:
open(root / 'hello.txt', bad)
assert False, f'open(mode={bad!r}) should error'
except TypeError as exc:
assert str(exc) == f"open() argument 'mode' must be str, not {expected_type}", (
f'open(mode={bad!r}) wrong type: {exc}'
)
try:
open(root / 'hello.txt', mode=bad)
assert False, f'open(mode={bad!r} kwarg) should error'
except TypeError as exc:
assert str(exc) == f"open() argument 'mode' must be str, not {expected_type}", (
f'open(mode={bad!r} kwarg) wrong type: {exc}'
)
try:
open(root / 'hello.txt', 'r').write('x')
assert False, 'expected writing to read-only file to fail'
except OSError as exc:
assert str(exc) == 'not writable', f'unexpected not-writable message: {exc}'
expected_name = 'io.UnsupportedOperation' if is_monty else 'UnsupportedOperation'
assert type(exc).__name__ == expected_name, f'expected {expected_name}, got {type(exc).__name__}'
try:
open(root / 'hello.txt', 'rb').write(b'x')
assert False, 'expected writing to rb file to fail'
except OSError as exc:
assert str(exc) == 'write', f'unexpected binary not-writable message: {exc}'
try:
open(root / 'hello.txt', 'w').read()
assert False, 'expected reading from write-only file to fail'
except OSError as exc:
assert str(exc) == 'not readable', f'unexpected not-readable message: {exc}'
try:
open(root / 'hello.txt', 'w').read()
assert False, 'expected reading from write-only file to fail'
except ValueError as exc:
assert str(exc) == 'not readable', f'unexpected not-readable message: {exc}'
try:
open(root / 'bad.txt', 'w').write(b'bytes')
assert False, 'expected bytes write to text file to fail'
except TypeError as exc:
assert str(exc) == 'write() argument must be str, not bytes', f'unexpected text write type message: {exc}'
try:
open(root / 'bad.bin', 'wb').write('text')
assert False, 'expected str write to binary file to fail'
except TypeError as exc:
assert str(exc) == "a bytes-like object is required, not 'str'", f'unexpected binary write type message: {exc}'
try:
open(root / 'bad.txt', 'rw')
assert False, 'expected invalid mode to fail'
except ValueError as exc:
assert str(exc) == 'must have exactly one of create/read/write/append mode', (
f'unexpected invalid mode message: {exc}'
)
try:
open(root / 'hello.txt', '')
assert False, 'expected empty mode to fail'
except ValueError as exc:
assert str(exc) == 'Must have exactly one of create/read/write/append mode and at most one plus', (
f'unexpected empty mode message: {exc}'
)
try:
open(root / 'hello.txt', 'z')
assert False, 'expected unknown mode character to fail'
except ValueError as exc:
assert str(exc) == "invalid mode: 'z'", f'unexpected unknown mode message: {exc}'
try:
open(root / 'hello.txt', 'b')
assert False, 'expected action-less binary mode to fail'
except ValueError as exc:
assert str(exc) == 'Must have exactly one of create/read/write/append mode and at most one plus', (
f'unexpected action-less mode message: {exc}'
)
try:
open(root / 'hello.txt', 't')
assert False, 'expected action-less text mode to fail'
except ValueError as exc:
assert str(exc) == 'Must have exactly one of create/read/write/append mode and at most one plus', (
f'unexpected action-less mode message: {exc}'
)
(root / 'sized.txt').write_text('hello world')
sized = open(root / 'sized.txt')
assert sized.read(5) == 'hello'
assert sized.read(100) == ' world'
assert sized.read(1) == ''
assert sized.read(0) == ''
sized.close()
read_none = open(root / 'sized.txt')
assert read_none.read(None) == 'hello world'
read_none.close()
read_bool = open(root / 'sized.txt')
assert read_bool.read(True) == 'h'
assert read_bool.read(False) == ''
assert read_bool.read(1) == 'e'
read_bool.close()
mixed = open(root / 'sized.txt')
assert mixed.read(5) == 'hello'
assert mixed.read(-1) == ' world'
mixed.close()
mixed2 = open(root / 'sized.txt')
assert mixed2.read(5) == 'hello'
assert mixed2.read() == ' world'
mixed2.close()
zero = open(root / 'sized.txt')
assert zero.read(0) == ''
assert zero.read(5) == 'hello'
zero.close()
(root / 'sized.bin').write_bytes(b'\x10\x11\x12\x13\x14')
sized_b = open(root / 'sized.bin', 'rb')
assert sized_b.read(3) == b'\x10\x11\x12'
assert sized_b.read(10) == b'\x13\x14'
assert sized_b.read(1) == b''
sized_b.close()
(root / 'lines.txt').write_text('first\nsecond\nthird')
lf = open(root / 'lines.txt')
assert lf.readline() == 'first\n'
assert lf.readline() == 'second\n'
assert lf.readline() == 'third'
assert lf.readline() == ''
lf.close()
(root / 'empty_lines.txt').write_text('')
empty_lf = open(root / 'empty_lines.txt')
assert empty_lf.readline() == ''
empty_lf.close()
all_lines = open(root / 'lines.txt')
assert all_lines.readlines() == ['first\n', 'second\n', 'third']
assert all_lines.readlines() == []
all_lines.close()
(root / 'lines.bin').write_bytes(b'a\nb\nc')
bin_lf = open(root / 'lines.bin', 'rb')
assert bin_lf.readline() == b'a\n'
assert bin_lf.readlines() == [b'b\n', b'c']
bin_lf.close()
t = open(root / 'sized.txt')
assert t.tell() == 0
t.read(5)
assert t.tell() == 5
t.read(2)
assert t.tell() == 7
t.close()
s = open(root / 'sized.txt')
assert s.read(11) == 'hello world'
assert s.tell() == 11
assert s.seek(0) == 0
assert s.tell() == 0
assert s.read(5) == 'hello'
assert s.seek(0, 2) == 11
assert s.read(1) == ''
assert s.seek(6) == 6
assert s.read(5) == 'world'
s.close()
fresh_seek = open(root / 'sized.txt')
assert fresh_seek.seek(0, 2) == 11
assert fresh_seek.tell() == 11
assert fresh_seek.read(1) == ''
fresh_seek.close()
cur_t = open(root / 'sized.txt')
assert cur_t.read(4) == 'hell'
assert cur_t.seek(0, 1) == 4
assert cur_t.read(2) == 'o '
cur_t.close()
cur_b = open(root / 'sized.bin', 'rb')
assert cur_b.read(2) == b'\x10\x11'
assert cur_b.seek(1, 1) == 3
assert cur_b.read(2) == b'\x13\x14'
assert cur_b.seek(-3, 1) == 2
assert cur_b.read(2) == b'\x12\x13'
cur_b.close()
ns = open(root / 'sized.bin', 'rb')
ns.read(0) try:
ns.seek(-1)
assert False, 'expected OSError for negative seek'
except OSError as exc:
assert str(exc) == '[Errno 22] Invalid argument', f'unexpected negative seek message: {exc}'
ns.close()
iw = open(root / 'sized.bin', 'rb')
iw.read(0)
try:
iw.seek(0, 99)
assert False, 'expected ValueError for invalid whence'
except ValueError as exc:
assert str(exc) == 'whence value 99 unsupported', f'unexpected invalid whence message: {exc}'
try:
iw.seek(0, -1)
assert False, 'expected ValueError for negative whence'
except ValueError as exc:
assert str(exc) == 'whence value -1 unsupported', f'unexpected negative whence message: {exc}'
try:
iw.seek(0, 256)
assert False, 'expected ValueError for large whence'
except ValueError as exc:
assert str(exc) == 'whence value 256 unsupported', f'unexpected large whence message: {exc}'
iw.close()
closed_t = open(root / 'sized.txt')
closed_t.close()
try:
closed_t.tell()
assert False, 'expected tell on closed file to fail'
except ValueError as exc:
assert str(exc) == 'I/O operation on closed file.'
try:
closed_t.seek(0)
assert False, 'expected seek on closed file to fail'
except ValueError as exc:
assert str(exc) == 'I/O operation on closed file.'
(root / 'utf8.txt').write_text('aβc')
utf = open(root / 'utf8.txt')
assert utf.read(2) == 'aβ'
if is_monty:
assert utf.tell() == 2
assert utf.read(1) == 'c'
utf.close()
rt = open(root / 'lines.txt')
rt.read(3)
captured = rt.tell()
assert captured == 3
rt.read(5)
assert rt.seek(captured) == 3
assert rt.read(2) == 'st'
rt.close()
mixed_rl = open(root / 'lines.txt')
assert mixed_rl.read(2) == 'fi'
assert mixed_rl.readline() == 'rst\n'
assert mixed_rl.read() == 'second\nthird'
mixed_rl.close()
try:
open(root / 'open_write.txt', 'w').read(5)
assert False, 'expected read on w to fail'
except OSError as exc:
assert str(exc) == 'not readable'
try:
open(root / 'open_write.txt', 'w').read(0)
assert False, 'expected read(0) on w to fail'
except OSError as exc:
assert str(exc) == 'not readable'
closed_w = open(root / 'open_write.txt', 'w')
closed_w.close()
try:
closed_w.read(0)
assert False, 'expected read(0) on closed file to fail'
except ValueError as exc:
assert str(exc) == 'I/O operation on closed file.'
write_pos = open(root / 'write_position.txt', 'w')
assert write_pos.seekable() == True
assert write_pos.tell() == 0
assert write_pos.write('abc') == 3
assert write_pos.tell() == 3
assert write_pos.seek(0) == 0
assert write_pos.tell() == 0
assert write_pos.seek(0, 2) == 3
write_pos.close()
write_pos_b = open(root / 'write_position.bin', 'wb')
assert write_pos_b.write(b'\x00\x01\x02\x03') == 4
assert write_pos_b.tell() == 4
write_pos_b.close()
(root / 'past_end.bin').write_bytes(b'12345')
pe = open(root / 'past_end.bin', 'rb')
assert pe.seek(100) == 100
assert pe.tell() == 100
assert pe.read(5) == b''
assert pe.tell() == 100
assert pe.readline() == b''
assert pe.tell() == 100
assert pe.readlines() == []
assert pe.tell() == 100
assert pe.read() == b''
assert pe.tell() == 100
pe.close()
(root / 'past_end.txt').write_text('hello')
pet = open(root / 'past_end.txt')
assert pet.seek(100) == 100
assert pet.read(5) == ''
assert pet.tell() == 100
assert pet.readline() == ''
assert pet.tell() == 100
assert pet.readlines() == []
assert pet.tell() == 100
assert pet.read() == ''
assert pet.tell() == 100
pet.close()
nt = open(root / 'sized.txt')
try:
nt.read('5')
assert False, 'expected TypeError for non-int read size'
except TypeError as exc:
msg = str(exc)
if is_monty:
assert msg == "'str' object cannot be interpreted as an integer", f'unexpected message: {msg}'
else:
assert msg == "argument should be integer or None, not 'str'", f'unexpected CPython message: {msg}'
nt.close()
(root / 'path_open_text.txt').write_text('hello via Path.open\n')
(root / 'path_open_bytes.bin').write_bytes(b'\x10\x20\x30')
path_read = (root / 'path_open_text.txt').open()
assert path_read.read() == 'hello via Path.open\n'
path_read.close()
binary_via_path = (root / 'path_open_bytes.bin').open('rb')
assert str(type(binary_via_path)) == "<class '_io.BufferedReader'>"
assert binary_via_path.read() == b'\x10\x20\x30'
binary_via_path.close()
kw_mode = (root / 'path_open_text.txt').open(mode='r')
assert kw_mode.read() == 'hello via Path.open\n'
kw_mode.close()
enc = (root / 'path_open_text.txt').open('r', encoding='utf-8')
assert enc.read() == 'hello via Path.open\n'
enc.close()
with (root / 'path_open_text.txt').open() as f:
assert f.read() == 'hello via Path.open\n'
assert f.closed
(root / 'path_open_write.txt').open('w').write('written via Path.open\n')
assert (root / 'path_open_write.txt').read_text() == 'written via Path.open\n'
if is_monty:
try:
(root / 'path_open_text.txt').open('r+')
assert False, "expected ValueError for Path.open('r+')"
except ValueError as exc:
assert str(exc) == "update modes ('+') are not yet supported", f'unexpected Path.open r+ rejection: {exc}'
try:
(root / 'path_open_text.txt').open(buffering=0)
assert False, 'expected TypeError for Path.open(buffering=0)'
except TypeError as exc:
assert str(exc) == "'buffering' argument is not yet supported", (
f'unexpected Path.open buffering rejection: {exc}'
)
try:
(root / 'path_open_missing.txt').open()
assert False, 'expected FileNotFoundError opening a missing file via Path.open'
except FileNotFoundError as exc:
assert str(exc).startswith("[Errno 2] No such file or directory: '")