Exceptions raised during renaming in rotating file handlers are now passed to handleE...
[python.git] / Lib / test / test_file.py
blobbde3202e8c0bdc6130b2ad496a5c1b6f8d8c280d
1 import sys
2 import os
3 from array import array
4 from weakref import proxy
6 from test.test_support import verify, TESTFN, TestFailed
7 from UserList import UserList
9 # verify weak references
10 f = file(TESTFN, 'w')
11 p = proxy(f)
12 p.write('teststring')
13 verify(f.tell(), p.tell())
14 f.close()
15 f = None
16 try:
17 p.tell()
18 except ReferenceError:
19 pass
20 else:
21 raise TestFailed('file proxy still exists when the file is gone')
23 # verify expected attributes exist
24 f = file(TESTFN, 'w')
25 softspace = f.softspace
26 f.name # merely shouldn't blow up
27 f.mode # ditto
28 f.closed # ditto
30 # verify softspace is writable
31 f.softspace = softspace # merely shouldn't blow up
33 # verify the others aren't
34 for attr in 'name', 'mode', 'closed':
35 try:
36 setattr(f, attr, 'oops')
37 except (AttributeError, TypeError):
38 pass
39 else:
40 raise TestFailed('expected exception setting file attr %r' % attr)
41 f.close()
43 # check invalid mode strings
44 for 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)
53 # verify writelines with instance sequence
54 l = UserList(['1', '2'])
55 f = open(TESTFN, 'wb')
56 f.writelines(l)
57 f.close()
58 f = open(TESTFN, 'rb')
59 buf = f.read()
60 f.close()
61 verify(buf == '12')
63 # verify readinto
64 a = array('c', 'x'*10)
65 f = open(TESTFN, 'rb')
66 n = f.readinto(a)
67 f.close()
68 verify(buf == a.tostring()[:n])
70 # verify writelines with integers
71 f = open(TESTFN, 'wb')
72 try:
73 f.writelines([1, 2, 3])
74 except TypeError:
75 pass
76 else:
77 print "writelines accepted sequence of integers"
78 f.close()
80 # verify writelines with integers in UserList
81 f = open(TESTFN, 'wb')
82 l = UserList([1,2,3])
83 try:
84 f.writelines(l)
85 except TypeError:
86 pass
87 else:
88 print "writelines accepted sequence of integers"
89 f.close()
91 # verify writelines with non-string object
92 class NonString: pass
94 f = open(TESTFN, 'wb')
95 try:
96 f.writelines([NonString(), NonString()])
97 except TypeError:
98 pass
99 else:
100 print "writelines accepted sequence of non-string objects"
101 f.close()
103 try:
104 sys.stdin.seek(-1)
105 except IOError:
106 pass
107 else:
108 print "should not be able to seek on sys.stdin"
110 try:
111 sys.stdin.truncate()
112 except IOError:
113 pass
114 else:
115 print "should not be able to truncate on sys.stdin"
117 # verify repr works
118 f = open(TESTFN)
119 if not repr(f).startswith("<open file '" + TESTFN):
120 print "repr(file) failed"
121 f.close()
123 # verify repr works for unicode too
124 f = open(unicode(TESTFN))
125 if not repr(f).startswith("<open file u'" + TESTFN):
126 print "repr(file with unicode name) failed"
127 f.close()
129 # verify that we get a sensible error message for bad mode argument
130 bad_mode = "qwerty"
131 try:
132 open(TESTFN, bad_mode)
133 except IOError, msg:
134 if msg[0] != 0:
135 s = str(msg)
136 if s.find(TESTFN) != -1 or s.find(bad_mode) == -1:
137 print "bad error message for invalid mode: %s" % s
138 # if msg[0] == 0, we're probably on Windows where there may be
139 # no obvious way to discover why open() failed.
140 else:
141 print "no error for invalid mode: %s" % bad_mode
143 f = open(TESTFN)
144 if f.name != TESTFN:
145 raise TestFailed, 'file.name should be "%s"' % TESTFN
146 if f.isatty():
147 raise TestFailed, 'file.isatty() should be false'
149 if f.closed:
150 raise TestFailed, 'file.closed should be false'
152 try:
153 f.readinto("")
154 except TypeError:
155 pass
156 else:
157 raise TestFailed, 'file.readinto("") should raise a TypeError'
159 f.close()
160 if not f.closed:
161 raise TestFailed, 'file.closed should be true'
163 # make sure that explicitly setting the buffer size doesn't cause
164 # misbehaviour especially with repeated close() calls
165 for s in (-1, 0, 1, 512):
166 try:
167 f = open(TESTFN, 'w', s)
168 f.write(str(s))
169 f.close()
170 f.close()
171 f = open(TESTFN, 'r', s)
172 d = int(f.read())
173 f.close()
174 f.close()
175 except IOError, msg:
176 raise TestFailed, 'error setting buffer size %d: %s' % (s, str(msg))
177 if d != s:
178 raise TestFailed, 'readback failure using buffer size %d'
180 methods = ['fileno', 'flush', 'isatty', 'next', 'read', 'readinto',
181 'readline', 'readlines', 'seek', 'tell', 'truncate', 'write',
182 'xreadlines', '__iter__']
183 if sys.platform.startswith('atheos'):
184 methods.remove('truncate')
186 for methodname in methods:
187 method = getattr(f, methodname)
188 try:
189 method()
190 except ValueError:
191 pass
192 else:
193 raise TestFailed, 'file.%s() on a closed file should raise a ValueError' % methodname
195 try:
196 f.writelines([])
197 except ValueError:
198 pass
199 else:
200 raise TestFailed, 'file.writelines([]) on a closed file should raise a ValueError'
202 os.unlink(TESTFN)
204 def bug801631():
205 # SF bug <http://www.python.org/sf/801631>
206 # "file.truncate fault on windows"
207 f = file(TESTFN, 'wb')
208 f.write('12345678901') # 11 bytes
209 f.close()
211 f = file(TESTFN,'rb+')
212 data = f.read(5)
213 if data != '12345':
214 raise TestFailed("Read on file opened for update failed %r" % data)
215 if f.tell() != 5:
216 raise TestFailed("File pos after read wrong %d" % f.tell())
218 f.truncate()
219 if f.tell() != 5:
220 raise TestFailed("File pos after ftruncate wrong %d" % f.tell())
222 f.close()
223 size = os.path.getsize(TESTFN)
224 if size != 5:
225 raise TestFailed("File size after ftruncate wrong %d" % size)
227 try:
228 bug801631()
229 finally:
230 os.unlink(TESTFN)