blob: ca1c6ba12606cb7f21b1a5eeb29ba3d1b0f4c62a [file] [log] [blame]
Martin v. Löwisf90ae202002-06-11 06:22:31 +00001import sys
Fred Drake2ec80fa2000-10-23 16:59:35 +00002import os
Neal Norwitz62f5a9d2002-04-01 00:09:00 +00003from array import array
Raymond Hettingercb87bc82004-05-31 00:35:52 +00004from weakref import proxy
Fred Drake2ec80fa2000-10-23 16:59:35 +00005
Thomas Woutersc45251a2006-02-12 11:53:32 +00006from test.test_support import verify, TESTFN, TestFailed, findfile
Marc-André Lemburgfa44d792000-08-25 22:37:31 +00007from UserList import UserList
8
Raymond Hettingercb87bc82004-05-31 00:35:52 +00009# verify weak references
10f = file(TESTFN, 'w')
11p = proxy(f)
12p.write('teststring')
13verify(f.tell(), p.tell())
14f.close()
15f = None
16try:
17 p.tell()
18except ReferenceError:
19 pass
20else:
21 raise TestFailed('file proxy still exists when the file is gone')
22
Tim Peters015dd822003-05-04 04:16:52 +000023# verify expected attributes exist
24f = file(TESTFN, 'w')
25softspace = f.softspace
26f.name # merely shouldn't blow up
27f.mode # ditto
28f.closed # ditto
29
30# verify softspace is writable
31f.softspace = softspace # merely shouldn't blow up
32
33# verify the others aren't
34for attr in 'name', 'mode', 'closed':
35 try:
36 setattr(f, attr, 'oops')
Barry Warsawb180c062005-04-20 19:41:36 +000037 except (AttributeError, TypeError):
Tim Peters015dd822003-05-04 04:16:52 +000038 pass
39 else:
Barry Warsawb180c062005-04-20 19:41:36 +000040 raise TestFailed('expected exception setting file attr %r' % attr)
Tim Peters015dd822003-05-04 04:16:52 +000041f.close()
42
Skip Montanarobbf12ba2005-05-20 03:07:06 +000043# check invalid mode strings
44for mode in ("", "aU", "wU+"):
45 try:
46 f = file(TESTFN, mode)
47 except ValueError:
48 pass
49 else:
50 f.close()
51 raise TestFailed('%r is an invalid file mode' % mode)
52
Marc-André Lemburgfa44d792000-08-25 22:37:31 +000053# verify writelines with instance sequence
54l = UserList(['1', '2'])
55f = open(TESTFN, 'wb')
56f.writelines(l)
57f.close()
58f = open(TESTFN, 'rb')
59buf = f.read()
60f.close()
Marc-André Lemburg36619082001-01-17 19:11:13 +000061verify(buf == '12')
Marc-André Lemburgfa44d792000-08-25 22:37:31 +000062
Neal Norwitz62f5a9d2002-04-01 00:09:00 +000063# verify readinto
64a = array('c', 'x'*10)
65f = open(TESTFN, 'rb')
66n = f.readinto(a)
67f.close()
68verify(buf == a.tostring()[:n])
69
Guido van Rossumd624f182006-04-24 13:47:05 +000070# verify readinto refuses text files
71a = array('c', 'x'*10)
72f = open(TESTFN, 'r')
73try:
74 f.readinto(a)
75 raise TestFailed("readinto shouldn't work in text mode")
76except TypeError:
77 pass
78finally:
79 f.close()
80
Marc-André Lemburgfa44d792000-08-25 22:37:31 +000081# verify writelines with integers
82f = open(TESTFN, 'wb')
83try:
84 f.writelines([1, 2, 3])
85except TypeError:
86 pass
87else:
88 print "writelines accepted sequence of integers"
89f.close()
90
91# verify writelines with integers in UserList
92f = open(TESTFN, 'wb')
93l = UserList([1,2,3])
94try:
95 f.writelines(l)
96except TypeError:
97 pass
98else:
99 print "writelines accepted sequence of integers"
100f.close()
101
102# verify writelines with non-string object
103class NonString: pass
104
105f = open(TESTFN, 'wb')
106try:
107 f.writelines([NonString(), NonString()])
108except TypeError:
109 pass
110else:
111 print "writelines accepted sequence of non-string objects"
112f.close()
Fred Drake2ec80fa2000-10-23 16:59:35 +0000113
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000114# This causes the interpreter to exit on OSF1 v5.1.
115if sys.platform != 'osf1V5':
116 try:
117 sys.stdin.seek(-1)
118 except IOError:
119 pass
120 else:
121 print "should not be able to seek on sys.stdin"
Neal Norwitzfcf44352005-11-27 20:37:43 +0000122else:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000123 print >>sys.__stdout__, (
124 ' Skipping sys.stdin.seek(-1), it may crash the interpreter.'
125 ' Test manually.')
Neal Norwitzfcf44352005-11-27 20:37:43 +0000126
127try:
Neal Norwitzfcf44352005-11-27 20:37:43 +0000128 sys.stdin.truncate()
129except IOError:
130 pass
131else:
132 print "should not be able to truncate on sys.stdin"
133
134# verify repr works
135f = open(TESTFN)
136if not repr(f).startswith("<open file '" + TESTFN):
137 print "repr(file) failed"
138f.close()
139
140# verify repr works for unicode too
141f = open(unicode(TESTFN))
142if not repr(f).startswith("<open file u'" + TESTFN):
143 print "repr(file with unicode name) failed"
144f.close()
145
Jeremy Hylton734c7fb2001-11-09 19:34:43 +0000146# verify that we get a sensible error message for bad mode argument
Jeremy Hylton41c83212001-11-09 16:17:24 +0000147bad_mode = "qwerty"
148try:
149 open(TESTFN, bad_mode)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000150except ValueError, msg:
Jeremy Hylton734c7fb2001-11-09 19:34:43 +0000151 if msg[0] != 0:
152 s = str(msg)
153 if s.find(TESTFN) != -1 or s.find(bad_mode) == -1:
154 print "bad error message for invalid mode: %s" % s
155 # if msg[0] == 0, we're probably on Windows where there may be
156 # no obvious way to discover why open() failed.
Jeremy Hylton41c83212001-11-09 16:17:24 +0000157else:
158 print "no error for invalid mode: %s" % bad_mode
159
Neal Norwitz653d85f2002-01-01 19:11:13 +0000160f = open(TESTFN)
161if f.name != TESTFN:
Neal Norwitzb1295da2002-04-01 18:59:20 +0000162 raise TestFailed, 'file.name should be "%s"' % TESTFN
Neal Norwitz653d85f2002-01-01 19:11:13 +0000163if f.isatty():
Neal Norwitzb1295da2002-04-01 18:59:20 +0000164 raise TestFailed, 'file.isatty() should be false'
Neal Norwitz653d85f2002-01-01 19:11:13 +0000165
166if f.closed:
Neal Norwitzb1295da2002-04-01 18:59:20 +0000167 raise TestFailed, 'file.closed should be false'
Neal Norwitz653d85f2002-01-01 19:11:13 +0000168
Neal Norwitz62f5a9d2002-04-01 00:09:00 +0000169try:
170 f.readinto("")
171except TypeError:
172 pass
173else:
Neal Norwitzb1295da2002-04-01 18:59:20 +0000174 raise TestFailed, 'file.readinto("") should raise a TypeError'
Neal Norwitz62f5a9d2002-04-01 00:09:00 +0000175
Neal Norwitz653d85f2002-01-01 19:11:13 +0000176f.close()
177if not f.closed:
Neal Norwitzb1295da2002-04-01 18:59:20 +0000178 raise TestFailed, 'file.closed should be true'
Neal Norwitz653d85f2002-01-01 19:11:13 +0000179
Andrew MacIntyre4e10ed32004-04-04 07:01:35 +0000180# make sure that explicitly setting the buffer size doesn't cause
181# misbehaviour especially with repeated close() calls
182for s in (-1, 0, 1, 512):
183 try:
184 f = open(TESTFN, 'w', s)
185 f.write(str(s))
186 f.close()
187 f.close()
188 f = open(TESTFN, 'r', s)
189 d = int(f.read())
190 f.close()
191 f.close()
192 except IOError, msg:
193 raise TestFailed, 'error setting buffer size %d: %s' % (s, str(msg))
194 if d != s:
195 raise TestFailed, 'readback failure using buffer size %d'
196
Guido van Rossum3c668c12002-08-06 15:58:24 +0000197methods = ['fileno', 'flush', 'isatty', 'next', 'read', 'readinto',
198 'readline', 'readlines', 'seek', 'tell', 'truncate', 'write',
Neal Norwitz70967602006-03-17 08:29:44 +0000199 '__iter__']
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000200if sys.platform.startswith('atheos'):
201 methods.remove('truncate')
202
203for methodname in methods:
Neal Norwitz653d85f2002-01-01 19:11:13 +0000204 method = getattr(f, methodname)
205 try:
206 method()
207 except ValueError:
208 pass
209 else:
Neal Norwitzb1295da2002-04-01 18:59:20 +0000210 raise TestFailed, 'file.%s() on a closed file should raise a ValueError' % methodname
Neal Norwitz653d85f2002-01-01 19:11:13 +0000211
212try:
213 f.writelines([])
214except ValueError:
215 pass
216else:
Neal Norwitzb1295da2002-04-01 18:59:20 +0000217 raise TestFailed, 'file.writelines([]) on a closed file should raise a ValueError'
Neal Norwitz653d85f2002-01-01 19:11:13 +0000218
Fred Drake2ec80fa2000-10-23 16:59:35 +0000219os.unlink(TESTFN)
Tim Petersf1827cf2003-09-07 03:30:18 +0000220
221def bug801631():
222 # SF bug <http://www.python.org/sf/801631>
223 # "file.truncate fault on windows"
224 f = file(TESTFN, 'wb')
225 f.write('12345678901') # 11 bytes
226 f.close()
227
228 f = file(TESTFN,'rb+')
229 data = f.read(5)
230 if data != '12345':
231 raise TestFailed("Read on file opened for update failed %r" % data)
232 if f.tell() != 5:
233 raise TestFailed("File pos after read wrong %d" % f.tell())
234
235 f.truncate()
236 if f.tell() != 5:
237 raise TestFailed("File pos after ftruncate wrong %d" % f.tell())
238
239 f.close()
240 size = os.path.getsize(TESTFN)
241 if size != 5:
242 raise TestFailed("File size after ftruncate wrong %d" % size)
243
244try:
245 bug801631()
246finally:
247 os.unlink(TESTFN)
Thomas Woutersc45251a2006-02-12 11:53:32 +0000248
249# Test the complex interaction when mixing file-iteration and the various
250# read* methods. Ostensibly, the mixture could just be tested to work
251# when it should work according to the Python language, instead of fail
252# when it should fail according to the current CPython implementation.
253# People don't always program Python the way they should, though, and the
254# implemenation might change in subtle ways, so we explicitly test for
255# errors, too; the test will just have to be updated when the
256# implementation changes.
257dataoffset = 16384
258filler = "ham\n"
259assert not dataoffset % len(filler), \
260 "dataoffset must be multiple of len(filler)"
261nchunks = dataoffset // len(filler)
262testlines = [
263 "spam, spam and eggs\n",
264 "eggs, spam, ham and spam\n",
265 "saussages, spam, spam and eggs\n",
266 "spam, ham, spam and eggs\n",
267 "spam, spam, spam, spam, spam, ham, spam\n",
268 "wonderful spaaaaaam.\n"
269]
270methods = [("readline", ()), ("read", ()), ("readlines", ()),
271 ("readinto", (array("c", " "*100),))]
272
273try:
274 # Prepare the testfile
Guido van Rossumd624f182006-04-24 13:47:05 +0000275 bag = open(TESTFN, "wb")
Thomas Woutersc45251a2006-02-12 11:53:32 +0000276 bag.write(filler * nchunks)
277 bag.writelines(testlines)
278 bag.close()
279 # Test for appropriate errors mixing read* and iteration
280 for methodname, args in methods:
Guido van Rossumd624f182006-04-24 13:47:05 +0000281 f = open(TESTFN, 'rb')
Thomas Woutersc45251a2006-02-12 11:53:32 +0000282 if f.next() != filler:
283 raise TestFailed, "Broken testfile"
284 meth = getattr(f, methodname)
285 try:
286 meth(*args)
287 except ValueError:
288 pass
289 else:
290 raise TestFailed("%s%r after next() didn't raise ValueError" %
291 (methodname, args))
292 f.close()
293
294 # Test to see if harmless (by accident) mixing of read* and iteration
295 # still works. This depends on the size of the internal iteration
296 # buffer (currently 8192,) but we can test it in a flexible manner.
297 # Each line in the bag o' ham is 4 bytes ("h", "a", "m", "\n"), so
298 # 4096 lines of that should get us exactly on the buffer boundary for
299 # any power-of-2 buffersize between 4 and 16384 (inclusive).
Guido van Rossumd624f182006-04-24 13:47:05 +0000300 f = open(TESTFN, 'rb')
Thomas Woutersc45251a2006-02-12 11:53:32 +0000301 for i in range(nchunks):
302 f.next()
303 testline = testlines.pop(0)
304 try:
305 line = f.readline()
306 except ValueError:
307 raise TestFailed("readline() after next() with supposedly empty "
308 "iteration-buffer failed anyway")
309 if line != testline:
310 raise TestFailed("readline() after next() with empty buffer "
311 "failed. Got %r, expected %r" % (line, testline))
312 testline = testlines.pop(0)
313 buf = array("c", "\x00" * len(testline))
314 try:
315 f.readinto(buf)
316 except ValueError:
317 raise TestFailed("readinto() after next() with supposedly empty "
318 "iteration-buffer failed anyway")
319 line = buf.tostring()
320 if line != testline:
321 raise TestFailed("readinto() after next() with empty buffer "
322 "failed. Got %r, expected %r" % (line, testline))
323
324 testline = testlines.pop(0)
325 try:
326 line = f.read(len(testline))
327 except ValueError:
328 raise TestFailed("read() after next() with supposedly empty "
329 "iteration-buffer failed anyway")
330 if line != testline:
331 raise TestFailed("read() after next() with empty buffer "
332 "failed. Got %r, expected %r" % (line, testline))
333 try:
334 lines = f.readlines()
335 except ValueError:
336 raise TestFailed("readlines() after next() with supposedly empty "
337 "iteration-buffer failed anyway")
338 if lines != testlines:
339 raise TestFailed("readlines() after next() with empty buffer "
340 "failed. Got %r, expected %r" % (line, testline))
341 # Reading after iteration hit EOF shouldn't hurt either
Guido van Rossumd624f182006-04-24 13:47:05 +0000342 f = open(TESTFN, 'rb')
Thomas Woutersc45251a2006-02-12 11:53:32 +0000343 try:
Tim Peterscffcfed2006-02-14 17:41:18 +0000344 for line in f:
345 pass
346 try:
347 f.readline()
348 f.readinto(buf)
349 f.read()
350 f.readlines()
351 except ValueError:
352 raise TestFailed("read* failed after next() consumed file")
353 finally:
354 f.close()
Thomas Woutersc45251a2006-02-12 11:53:32 +0000355finally:
Tim Peterscffcfed2006-02-14 17:41:18 +0000356 os.unlink(TESTFN)