4
from array import array
5
from weakref import proxy
10
from test.support import TESTFN, run_unittest
11
from collections import UserList
14
# file tests for which a test file is automatically set up
17
self.f = self.open(TESTFN, 'wb')
24
def testWeakRefs(self):
25
# verify weak references
27
p.write(b'teststring')
28
self.assertEqual(self.f.tell(), p.tell())
31
self.assertRaises(ReferenceError, getattr, p, 'tell')
33
def testAttributes(self):
34
# verify expected attributes exist
36
f.name # merely shouldn't blow up
40
def testReadinto(self):
44
a = array('b', b'x'*10)
45
self.f = self.open(TESTFN, 'rb')
46
n = self.f.readinto(a)
47
self.assertEqual(b'12', a.tobytes()[:n])
49
def testReadinto_text(self):
50
# verify readinto refuses text files
51
a = array('b', b'x'*10)
53
self.f = self.open(TESTFN, 'r')
54
if hasattr(self.f, "readinto"):
55
self.assertRaises(TypeError, self.f.readinto, a)
57
def testWritelinesUserList(self):
58
# verify writelines with instance sequence
59
l = UserList([b'1', b'2'])
62
self.f = self.open(TESTFN, 'rb')
64
self.assertEqual(buf, b'12')
66
def testWritelinesIntegers(self):
67
# verify writelines with integers
68
self.assertRaises(TypeError, self.f.writelines, [1, 2, 3])
70
def testWritelinesIntegersUserList(self):
71
# verify writelines with integers in UserList
73
self.assertRaises(TypeError, self.f.writelines, l)
75
def testWritelinesNonString(self):
76
# verify writelines with non-string object
80
self.assertRaises(TypeError, self.f.writelines,
81
[NonString(), NonString()])
85
self.assertEqual(f.name, TESTFN)
86
self.assertTrue(not f.isatty())
87
self.assertTrue(not f.closed)
89
if hasattr(f, "readinto"):
90
self.assertRaises((OSError, TypeError), f.readinto, "")
92
self.assertTrue(f.closed)
94
def testMethods(self):
95
methods = [('fileno', ()),
106
('writelines', ([],)),
109
methods.append(('truncate', ()))
111
# __exit__ should close the file
112
self.f.__exit__(None, None, None)
113
self.assertTrue(self.f.closed)
115
for methodname, args in methods:
116
method = getattr(self.f, methodname)
117
# should raise on closed file
118
self.assertRaises(ValueError, method, *args)
120
# file is closed, __exit__ shouldn't do anything
121
self.assertEqual(self.f.__exit__(None, None, None), None)
122
# it must also return None if an exception was given
126
self.assertEqual(self.f.__exit__(*sys.exc_info()), None)
128
def testReadWhenWriting(self):
129
self.assertRaises(OSError, self.f.read)
131
class CAutoFileTests(AutoFileTests, unittest.TestCase):
134
class PyAutoFileTests(AutoFileTests, unittest.TestCase):
135
open = staticmethod(pyio.open)
138
class OtherFileTests:
140
def testModeStrings(self):
141
# check invalid mode strings
142
for mode in ("", "aU", "wU+"):
144
f = self.open(TESTFN, mode)
149
self.fail('%r is an invalid file mode' % mode)
151
def testBadModeArgument(self):
152
# verify that we get a sensible error message for bad mode argument
155
f = self.open(TESTFN, bad_mode)
156
except ValueError as msg:
159
if TESTFN in s or bad_mode not in s:
160
self.fail("bad error message for invalid mode: %s" % s)
161
# if msg.args[0] == 0, we're probably on Windows where there may be
162
# no obvious way to discover why open() failed.
165
self.fail("no error for invalid mode: %s" % bad_mode)
167
def testSetBufferSize(self):
168
# make sure that explicitly setting the buffer size doesn't cause
169
# misbehaviour especially with repeated close() calls
170
for s in (-1, 0, 1, 512):
172
f = self.open(TESTFN, 'wb', s)
173
f.write(str(s).encode("ascii"))
176
f = self.open(TESTFN, 'rb', s)
177
d = int(f.read().decode("ascii"))
180
except OSError as msg:
181
self.fail('error setting buffer size %d: %s' % (s, str(msg)))
182
self.assertEqual(d, s)
184
def testTruncateOnWindows(self):
185
# SF bug <http://www.python.org/sf/801631>
186
# "file.truncate fault on windows"
189
f = self.open(TESTFN, 'wb')
192
f.write(b'12345678901') # 11 bytes
195
f = self.open(TESTFN,'rb+')
198
self.fail("Read on file opened for update failed %r" % data)
200
self.fail("File pos after read wrong %d" % f.tell())
204
self.fail("File pos after ftruncate wrong %d" % f.tell())
207
size = os.path.getsize(TESTFN)
209
self.fail("File size after ftruncate wrong %d" % size)
214
def testIteration(self):
215
# Test the complex interaction when mixing file-iteration and the
216
# various read* methods.
219
assert not dataoffset % len(filler), \
220
"dataoffset must be multiple of len(filler)"
221
nchunks = dataoffset // len(filler)
223
b"spam, spam and eggs\n",
224
b"eggs, spam, ham and spam\n",
225
b"saussages, spam, spam and eggs\n",
226
b"spam, ham, spam and eggs\n",
227
b"spam, spam, spam, spam, spam, ham, spam\n",
228
b"wonderful spaaaaaam.\n"
230
methods = [("readline", ()), ("read", ()), ("readlines", ()),
231
("readinto", (array("b", b" "*100),))]
234
# Prepare the testfile
235
bag = self.open(TESTFN, "wb")
236
bag.write(filler * nchunks)
237
bag.writelines(testlines)
239
# Test for appropriate errors mixing read* and iteration
240
for methodname, args in methods:
241
f = self.open(TESTFN, 'rb')
242
if next(f) != filler:
243
self.fail, "Broken testfile"
244
meth = getattr(f, methodname)
245
meth(*args) # This simply shouldn't fail
248
# Test to see if harmless (by accident) mixing of read* and
249
# iteration still works. This depends on the size of the internal
250
# iteration buffer (currently 8192,) but we can test it in a
251
# flexible manner. Each line in the bag o' ham is 4 bytes
252
# ("h", "a", "m", "\n"), so 4096 lines of that should get us
253
# exactly on the buffer boundary for any power-of-2 buffersize
254
# between 4 and 16384 (inclusive).
255
f = self.open(TESTFN, 'rb')
256
for i in range(nchunks):
258
testline = testlines.pop(0)
262
self.fail("readline() after next() with supposedly empty "
263
"iteration-buffer failed anyway")
265
self.fail("readline() after next() with empty buffer "
266
"failed. Got %r, expected %r" % (line, testline))
267
testline = testlines.pop(0)
268
buf = array("b", b"\x00" * len(testline))
272
self.fail("readinto() after next() with supposedly empty "
273
"iteration-buffer failed anyway")
276
self.fail("readinto() after next() with empty buffer "
277
"failed. Got %r, expected %r" % (line, testline))
279
testline = testlines.pop(0)
281
line = f.read(len(testline))
283
self.fail("read() after next() with supposedly empty "
284
"iteration-buffer failed anyway")
286
self.fail("read() after next() with empty buffer "
287
"failed. Got %r, expected %r" % (line, testline))
289
lines = f.readlines()
291
self.fail("readlines() after next() with supposedly empty "
292
"iteration-buffer failed anyway")
293
if lines != testlines:
294
self.fail("readlines() after next() with empty buffer "
295
"failed. Got %r, expected %r" % (line, testline))
298
# Reading after iteration hit EOF shouldn't hurt either
299
f = self.open(TESTFN, 'rb')
309
self.fail("read* failed after next() consumed file")
315
class COtherFileTests(OtherFileTests, unittest.TestCase):
318
class PyOtherFileTests(OtherFileTests, unittest.TestCase):
319
open = staticmethod(pyio.open)
322
def tearDownModule():
323
# Historically, these tests have been sloppy about removing TESTFN.
324
# So get rid of it no matter what.
325
if os.path.exists(TESTFN):
328
if __name__ == '__main__':