blob: ab29932e8f8ee0e9bea0b4ec6c556b1d846e6b59 [file] [log] [blame]
Martin v. Löwisf90ae202002-06-11 06:22:31 +00001import sys
Fred Drake2ec80fa2000-10-23 16:59:35 +00002import os
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00003import unittest
Neal Norwitz62f5a9d2002-04-01 00:09:00 +00004from array import array
Raymond Hettingercb87bc82004-05-31 00:35:52 +00005from weakref import proxy
Fred Drake2ec80fa2000-10-23 16:59:35 +00006
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00007from test.test_support import TESTFN, findfile, run_unittest
Marc-André Lemburgfa44d792000-08-25 22:37:31 +00008from UserList import UserList
9
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000010class AutoFileTests(unittest.TestCase):
11 # file tests for which a test file is automatically set up
Raymond Hettingercb87bc82004-05-31 00:35:52 +000012
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000013 def setUp(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +000014 self.f = open(TESTFN, 'wb')
Tim Peters015dd822003-05-04 04:16:52 +000015
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000016 def tearDown(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +000017 if self.f:
18 self.f.close()
19 os.remove(TESTFN)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000020
21 def testWeakRefs(self):
22 # verify weak references
23 p = proxy(self.f)
Guido van Rossume22905a2007-08-27 23:09:25 +000024 p.write(b'teststring')
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000025 self.assertEquals(self.f.tell(), p.tell())
26 self.f.close()
27 self.f = None
28 self.assertRaises(ReferenceError, getattr, p, 'tell')
29
30 def testAttributes(self):
31 # verify expected attributes exist
32 f = self.f
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000033 f.name # merely shouldn't blow up
34 f.mode # ditto
35 f.closed # ditto
36
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000037 def testReadinto(self):
38 # verify readinto
Guido van Rossume22905a2007-08-27 23:09:25 +000039 self.f.write(b'12')
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000040 self.f.close()
Guido van Rossum7165cb12007-07-10 06:54:34 +000041 a = array('b', b'x'*10)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000042 self.f = open(TESTFN, 'rb')
43 n = self.f.readinto(a)
Guido van Rossum7165cb12007-07-10 06:54:34 +000044 self.assertEquals(b'12', a.tostring()[:n])
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000045
46 def testReadinto_text(self):
47 # verify readinto refuses text files
Guido van Rossum7165cb12007-07-10 06:54:34 +000048 a = array('b', b'x'*10)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000049 self.f.close()
50 self.f = open(TESTFN, 'r')
Guido van Rossum7165cb12007-07-10 06:54:34 +000051 if hasattr(self.f, "readinto"):
52 self.assertRaises(TypeError, self.f.readinto, a)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000053
54 def testWritelinesUserList(self):
55 # verify writelines with instance sequence
Guido van Rossum7165cb12007-07-10 06:54:34 +000056 l = UserList([b'1', b'2'])
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000057 self.f.writelines(l)
58 self.f.close()
59 self.f = open(TESTFN, 'rb')
60 buf = self.f.read()
Guido van Rossum7165cb12007-07-10 06:54:34 +000061 self.assertEquals(buf, b'12')
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000062
63 def testWritelinesIntegers(self):
64 # verify writelines with integers
65 self.assertRaises(TypeError, self.f.writelines, [1, 2, 3])
66
67 def testWritelinesIntegersUserList(self):
68 # verify writelines with integers in UserList
69 l = UserList([1,2,3])
70 self.assertRaises(TypeError, self.f.writelines, l)
71
72 def testWritelinesNonString(self):
73 # verify writelines with non-string object
Thomas Wouters0e3f5912006-08-11 14:57:12 +000074 class NonString:
75 pass
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000076
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077 self.assertRaises(TypeError, self.f.writelines,
78 [NonString(), NonString()])
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000079
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000080 def testErrors(self):
81 f = self.f
82 self.assertEquals(f.name, TESTFN)
83 self.assert_(not f.isatty())
84 self.assert_(not f.closed)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000085
Guido van Rossum7165cb12007-07-10 06:54:34 +000086 if hasattr(f, "readinto"):
87 self.assertRaises((IOError, TypeError), f.readinto, "")
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000088 f.close()
89 self.assert_(f.closed)
90
91 def testMethods(self):
Guido van Rossum4b5386f2007-07-10 09:12:49 +000092 methods = [('fileno', ()),
93 ('flush', ()),
94 ('isatty', ()),
95 ('__next__', ()),
96 ('read', ()),
97 ('write', (b"",)),
98 ('readline', ()),
99 ('readlines', ()),
100 ('seek', (0,)),
101 ('tell', ()),
102 ('write', (b"",)),
103 ('writelines', ([],)),
104 ('__iter__', ()),
105 ]
106 if not sys.platform.startswith('atheos'):
107 methods.append(('truncate', ()))
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000108
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000109 # __exit__ should close the file
110 self.f.__exit__(None, None, None)
111 self.assert_(self.f.closed)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000112
Guido van Rossum4b5386f2007-07-10 09:12:49 +0000113 for methodname, args in methods:
114 method = getattr(self.f, methodname)
115 # should raise on closed file
116 self.assertRaises(ValueError, method, *args)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000117
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000118 # file is closed, __exit__ shouldn't do anything
119 self.assertEquals(self.f.__exit__(None, None, None), None)
120 # it must also return None if an exception was given
121 try:
122 1/0
123 except:
124 self.assertEquals(self.f.__exit__(*sys.exc_info()), None)
125
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000126
127class OtherFileTests(unittest.TestCase):
128
129 def testModeStrings(self):
130 # check invalid mode strings
131 for mode in ("", "aU", "wU+"):
132 try:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000133 f = open(TESTFN, mode)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000134 except ValueError:
135 pass
136 else:
137 f.close()
138 self.fail('%r is an invalid file mode' % mode)
139
140 def testStdin(self):
141 # This causes the interpreter to exit on OSF1 v5.1.
142 if sys.platform != 'osf1V5':
Guido van Rossum535a5ef2007-07-10 20:59:22 +0000143 self.assertRaises((IOError, ValueError), sys.stdin.seek, -1)
Thomas Woutersc45251a2006-02-12 11:53:32 +0000144 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000145 print((
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000146 ' Skipping sys.stdin.seek(-1), it may crash the interpreter.'
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000147 ' Test manually.'), file=sys.__stdout__)
Guido van Rossum535a5ef2007-07-10 20:59:22 +0000148 self.assertRaises((IOError, ValueError), sys.stdin.truncate)
Thomas Woutersc45251a2006-02-12 11:53:32 +0000149
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000150 def testBadModeArgument(self):
151 # verify that we get a sensible error message for bad mode argument
152 bad_mode = "qwerty"
Tim Peterscffcfed2006-02-14 17:41:18 +0000153 try:
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000154 f = open(TESTFN, bad_mode)
Guido van Rossumb940e112007-01-10 16:19:56 +0000155 except ValueError as msg:
Brett Cannonca477b22007-03-21 22:26:20 +0000156 if msg.args[0] != 0:
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000157 s = str(msg)
158 if s.find(TESTFN) != -1 or s.find(bad_mode) == -1:
159 self.fail("bad error message for invalid mode: %s" % s)
160 # if msg[0] == 0, we're probably on Windows where there may be
161 # no obvious way to discover why open() failed.
162 else:
163 f.close()
164 self.fail("no error for invalid mode: %s" % bad_mode)
165
166 def testSetBufferSize(self):
167 # make sure that explicitly setting the buffer size doesn't cause
168 # misbehaviour especially with repeated close() calls
169 for s in (-1, 0, 1, 512):
170 try:
Guido van Rossum7165cb12007-07-10 06:54:34 +0000171 f = open(TESTFN, 'wb', s)
172 f.write(str(s).encode("ascii"))
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000173 f.close()
174 f.close()
Guido van Rossum7165cb12007-07-10 06:54:34 +0000175 f = open(TESTFN, 'rb', s)
176 d = int(f.read().decode("ascii"))
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000177 f.close()
178 f.close()
Guido van Rossumb940e112007-01-10 16:19:56 +0000179 except IOError as msg:
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000180 self.fail('error setting buffer size %d: %s' % (s, str(msg)))
181 self.assertEquals(d, s)
182
183 def testTruncateOnWindows(self):
Guido van Rossum79b79ee2007-10-25 23:21:03 +0000184 # SF bug <http://www.python.org/sf/801631>
185 # "file.truncate fault on windows"
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000186
Guido van Rossum79b79ee2007-10-25 23:21:03 +0000187 os.unlink(TESTFN)
188 f = open(TESTFN, 'wb')
189
190 try:
Guido van Rossum7165cb12007-07-10 06:54:34 +0000191 f.write(b'12345678901') # 11 bytes
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000192 f.close()
193
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000194 f = open(TESTFN,'rb+')
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000195 data = f.read(5)
Guido van Rossum7165cb12007-07-10 06:54:34 +0000196 if data != b'12345':
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000197 self.fail("Read on file opened for update failed %r" % data)
198 if f.tell() != 5:
199 self.fail("File pos after read wrong %d" % f.tell())
200
201 f.truncate()
202 if f.tell() != 5:
203 self.fail("File pos after ftruncate wrong %d" % f.tell())
204
205 f.close()
206 size = os.path.getsize(TESTFN)
207 if size != 5:
208 self.fail("File size after ftruncate wrong %d" % size)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000209 finally:
Guido van Rossum79b79ee2007-10-25 23:21:03 +0000210 f.close()
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000211 os.unlink(TESTFN)
212
213 def testIteration(self):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000214 # Test the complex interaction when mixing file-iteration and the
Guido van Rossum7165cb12007-07-10 06:54:34 +0000215 # various read* methods.
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000216 dataoffset = 16384
Guido van Rossume22905a2007-08-27 23:09:25 +0000217 filler = b"ham\n"
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000218 assert not dataoffset % len(filler), \
219 "dataoffset must be multiple of len(filler)"
220 nchunks = dataoffset // len(filler)
221 testlines = [
Guido van Rossum7165cb12007-07-10 06:54:34 +0000222 b"spam, spam and eggs\n",
223 b"eggs, spam, ham and spam\n",
224 b"saussages, spam, spam and eggs\n",
225 b"spam, ham, spam and eggs\n",
226 b"spam, spam, spam, spam, spam, ham, spam\n",
227 b"wonderful spaaaaaam.\n"
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000228 ]
229 methods = [("readline", ()), ("read", ()), ("readlines", ()),
Guido van Rossum7165cb12007-07-10 06:54:34 +0000230 ("readinto", (array("b", b" "*100),))]
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000231
232 try:
233 # Prepare the testfile
234 bag = open(TESTFN, "wb")
235 bag.write(filler * nchunks)
236 bag.writelines(testlines)
237 bag.close()
238 # Test for appropriate errors mixing read* and iteration
239 for methodname, args in methods:
240 f = open(TESTFN, 'rb')
Georg Brandla18af4e2007-04-21 15:47:16 +0000241 if next(f) != filler:
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000242 self.fail, "Broken testfile"
243 meth = getattr(f, methodname)
Guido van Rossum7165cb12007-07-10 06:54:34 +0000244 meth(*args) # This simply shouldn't fail
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000245 f.close()
246
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000247 # Test to see if harmless (by accident) mixing of read* and
248 # iteration still works. This depends on the size of the internal
249 # iteration buffer (currently 8192,) but we can test it in a
250 # flexible manner. Each line in the bag o' ham is 4 bytes
251 # ("h", "a", "m", "\n"), so 4096 lines of that should get us
252 # exactly on the buffer boundary for any power-of-2 buffersize
253 # between 4 and 16384 (inclusive).
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000254 f = open(TESTFN, 'rb')
255 for i in range(nchunks):
Georg Brandla18af4e2007-04-21 15:47:16 +0000256 next(f)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000257 testline = testlines.pop(0)
258 try:
259 line = f.readline()
260 except ValueError:
261 self.fail("readline() after next() with supposedly empty "
262 "iteration-buffer failed anyway")
263 if line != testline:
264 self.fail("readline() after next() with empty buffer "
265 "failed. Got %r, expected %r" % (line, testline))
266 testline = testlines.pop(0)
Guido van Rossum7165cb12007-07-10 06:54:34 +0000267 buf = array("b", b"\x00" * len(testline))
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000268 try:
269 f.readinto(buf)
270 except ValueError:
271 self.fail("readinto() after next() with supposedly empty "
272 "iteration-buffer failed anyway")
273 line = buf.tostring()
274 if line != testline:
275 self.fail("readinto() after next() with empty buffer "
276 "failed. Got %r, expected %r" % (line, testline))
277
278 testline = testlines.pop(0)
279 try:
280 line = f.read(len(testline))
281 except ValueError:
282 self.fail("read() after next() with supposedly empty "
283 "iteration-buffer failed anyway")
284 if line != testline:
285 self.fail("read() after next() with empty buffer "
286 "failed. Got %r, expected %r" % (line, testline))
287 try:
288 lines = f.readlines()
289 except ValueError:
290 self.fail("readlines() after next() with supposedly empty "
291 "iteration-buffer failed anyway")
292 if lines != testlines:
293 self.fail("readlines() after next() with empty buffer "
294 "failed. Got %r, expected %r" % (line, testline))
295 # Reading after iteration hit EOF shouldn't hurt either
296 f = open(TESTFN, 'rb')
297 try:
298 for line in f:
299 pass
300 try:
301 f.readline()
302 f.readinto(buf)
303 f.read()
304 f.readlines()
305 except ValueError:
306 self.fail("read* failed after next() consumed file")
307 finally:
308 f.close()
309 finally:
310 os.unlink(TESTFN)
311
312
313def test_main():
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000314 # Historically, these tests have been sloppy about removing TESTFN.
315 # So get rid of it no matter what.
316 try:
317 run_unittest(AutoFileTests, OtherFileTests)
318 finally:
319 if os.path.exists(TESTFN):
320 os.unlink(TESTFN)
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000321
322if __name__ == '__main__':
323 test_main()