blob: a4fd20dcf242c3d2803022bb4b7bac54740e4fe0 [file] [log] [blame]
Guido van Rossumde3bc7c2007-03-08 01:02:00 +00001# Adapted from test_file.py by Daniel Stutzbach
Guido van Rossuma9e20242007-03-08 00:43:48 +00002
3import sys
4import os
Eli Bendersky74c503b2012-01-03 06:26:13 +02005import io
Antoine Pitrou0ae29cf2009-03-13 22:33:17 +00006import errno
Guido van Rossuma9e20242007-03-08 00:43:48 +00007import unittest
8from array import array
9from weakref import proxy
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +000010from functools import wraps
Guido van Rossuma9e20242007-03-08 00:43:48 +000011
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +020012from test.support import TESTFN, check_warnings, run_unittest, make_bad_fd, cpython_only
Antoine Pitrou131a4892012-10-16 22:57:11 +020013from collections import UserList
Guido van Rossuma9e20242007-03-08 00:43:48 +000014
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000015from _io import FileIO as _FileIO
Guido van Rossuma9e20242007-03-08 00:43:48 +000016
17class AutoFileTests(unittest.TestCase):
18 # file tests for which a test file is automatically set up
19
20 def setUp(self):
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000021 self.f = _FileIO(TESTFN, 'w')
Guido van Rossuma9e20242007-03-08 00:43:48 +000022
23 def tearDown(self):
24 if self.f:
25 self.f.close()
26 os.remove(TESTFN)
27
28 def testWeakRefs(self):
29 # verify weak references
30 p = proxy(self.f)
31 p.write(bytes(range(10)))
Ezio Melottib3aedd42010-11-20 19:04:17 +000032 self.assertEqual(self.f.tell(), p.tell())
Guido van Rossuma9e20242007-03-08 00:43:48 +000033 self.f.close()
34 self.f = None
35 self.assertRaises(ReferenceError, getattr, p, 'tell')
36
37 def testSeekTell(self):
38 self.f.write(bytes(range(20)))
Ezio Melottib3aedd42010-11-20 19:04:17 +000039 self.assertEqual(self.f.tell(), 20)
Guido van Rossuma9e20242007-03-08 00:43:48 +000040 self.f.seek(0)
Ezio Melottib3aedd42010-11-20 19:04:17 +000041 self.assertEqual(self.f.tell(), 0)
Guido van Rossuma9e20242007-03-08 00:43:48 +000042 self.f.seek(10)
Ezio Melottib3aedd42010-11-20 19:04:17 +000043 self.assertEqual(self.f.tell(), 10)
Guido van Rossuma9e20242007-03-08 00:43:48 +000044 self.f.seek(5, 1)
Ezio Melottib3aedd42010-11-20 19:04:17 +000045 self.assertEqual(self.f.tell(), 15)
Guido van Rossuma9e20242007-03-08 00:43:48 +000046 self.f.seek(-5, 1)
Ezio Melottib3aedd42010-11-20 19:04:17 +000047 self.assertEqual(self.f.tell(), 10)
Guido van Rossuma9e20242007-03-08 00:43:48 +000048 self.f.seek(-5, 2)
Ezio Melottib3aedd42010-11-20 19:04:17 +000049 self.assertEqual(self.f.tell(), 15)
Guido van Rossuma9e20242007-03-08 00:43:48 +000050
51 def testAttributes(self):
52 # verify expected attributes exist
53 f = self.f
Guido van Rossuma9e20242007-03-08 00:43:48 +000054
Ezio Melottib3aedd42010-11-20 19:04:17 +000055 self.assertEqual(f.mode, "wb")
56 self.assertEqual(f.closed, False)
Guido van Rossum31c3a572007-04-12 14:51:49 +000057
58 # verify the attributes are readonly
59 for attr in 'mode', 'closed':
60 self.assertRaises((AttributeError, TypeError),
61 setattr, f, attr, 'oops')
Guido van Rossuma9e20242007-03-08 00:43:48 +000062
63 def testReadinto(self):
64 # verify readinto
65 self.f.write(bytes([1, 2]))
66 self.f.close()
Guido van Rossuma45ea582007-05-15 21:25:12 +000067 a = array('b', b'x'*10)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000068 self.f = _FileIO(TESTFN, 'r')
Guido van Rossuma9e20242007-03-08 00:43:48 +000069 n = self.f.readinto(a)
Ezio Melottib3aedd42010-11-20 19:04:17 +000070 self.assertEqual(array('b', [1, 2]), a[:n])
Guido van Rossuma9e20242007-03-08 00:43:48 +000071
Antoine Pitrou131a4892012-10-16 22:57:11 +020072 def testWritelinesList(self):
73 l = [b'123', b'456']
74 self.f.writelines(l)
75 self.f.close()
76 self.f = _FileIO(TESTFN, 'rb')
77 buf = self.f.read()
78 self.assertEqual(buf, b'123456')
79
80 def testWritelinesUserList(self):
81 l = UserList([b'123', b'456'])
82 self.f.writelines(l)
83 self.f.close()
84 self.f = _FileIO(TESTFN, 'rb')
85 buf = self.f.read()
86 self.assertEqual(buf, b'123456')
87
88 def testWritelinesError(self):
89 self.assertRaises(TypeError, self.f.writelines, [1, 2, 3])
90 self.assertRaises(TypeError, self.f.writelines, None)
91 self.assertRaises(TypeError, self.f.writelines, "abc")
92
Benjamin Petersonbf5ff762009-12-13 19:25:34 +000093 def test_none_args(self):
94 self.f.write(b"hi\nbye\nabc")
95 self.f.close()
96 self.f = _FileIO(TESTFN, 'r')
97 self.assertEqual(self.f.read(None), b"hi\nbye\nabc")
98 self.f.seek(0)
99 self.assertEqual(self.f.readline(None), b"hi\n")
100 self.assertEqual(self.f.readlines(None), [b"bye\n", b"abc"])
101
Benjamin Peterson255058f2010-01-27 01:47:14 +0000102 def test_reject(self):
103 self.assertRaises(TypeError, self.f.write, "Hello!")
104
Guido van Rossuma9e20242007-03-08 00:43:48 +0000105 def testRepr(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000106 self.assertEqual(repr(self.f), "<_io.FileIO name=%r mode=%r>"
Antoine Pitrou716c4442009-05-23 19:04:03 +0000107 % (self.f.name, self.f.mode))
108 del self.f.name
Ezio Melottib3aedd42010-11-20 19:04:17 +0000109 self.assertEqual(repr(self.f), "<_io.FileIO fd=%r mode=%r>"
Antoine Pitrou716c4442009-05-23 19:04:03 +0000110 % (self.f.fileno(), self.f.mode))
111 self.f.close()
Ezio Melottib3aedd42010-11-20 19:04:17 +0000112 self.assertEqual(repr(self.f), "<_io.FileIO [closed]>")
Guido van Rossuma9e20242007-03-08 00:43:48 +0000113
114 def testErrors(self):
115 f = self.f
Serhiy Storchaka0dcd80a2015-08-02 15:17:49 +0300116 self.assertFalse(f.isatty())
117 self.assertFalse(f.closed)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000118 #self.assertEqual(f.name, TESTFN)
Guido van Rossum31c3a572007-04-12 14:51:49 +0000119 self.assertRaises(ValueError, f.read, 10) # Open for reading
Guido van Rossuma9e20242007-03-08 00:43:48 +0000120 f.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000121 self.assertTrue(f.closed)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000122 f = _FileIO(TESTFN, 'r')
Guido van Rossum31c3a572007-04-12 14:51:49 +0000123 self.assertRaises(TypeError, f.readinto, "")
Serhiy Storchaka0dcd80a2015-08-02 15:17:49 +0300124 self.assertFalse(f.closed)
Guido van Rossum31c3a572007-04-12 14:51:49 +0000125 f.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000126 self.assertTrue(f.closed)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000127
128 def testMethods(self):
Serhiy Storchaka6a694662015-04-16 11:54:14 +0300129 methods = ['fileno', 'isatty', 'seekable', 'readable', 'writable',
130 'read', 'readall', 'readline', 'readlines',
131 'tell', 'truncate', 'flush']
Guido van Rossuma9e20242007-03-08 00:43:48 +0000132
Guido van Rossum31c3a572007-04-12 14:51:49 +0000133 self.f.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000134 self.assertTrue(self.f.closed)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000135
136 for methodname in methods:
137 method = getattr(self.f, methodname)
138 # should raise on closed file
139 self.assertRaises(ValueError, method)
140
Serhiy Storchaka6a694662015-04-16 11:54:14 +0300141 self.assertRaises(ValueError, self.f.readinto) # XXX should be TypeError?
142 self.assertRaises(ValueError, self.f.readinto, bytearray(1))
143 self.assertRaises(ValueError, self.f.seek)
144 self.assertRaises(ValueError, self.f.seek, 0)
145 self.assertRaises(ValueError, self.f.write)
146 self.assertRaises(ValueError, self.f.write, b'')
147 self.assertRaises(TypeError, self.f.writelines)
148 self.assertRaises(ValueError, self.f.writelines, b'')
149
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000150 def testOpendir(self):
151 # Issue 3703: opening a directory should fill the errno
152 # Windows always returns "[Errno 13]: Permission denied
153 # Unix calls dircheck() and returns "[Errno 21]: Is a directory"
154 try:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000155 _FileIO('.', 'r')
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200156 except OSError as e:
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000157 self.assertNotEqual(e.errno, 0)
Benjamin Peterson1efc23c2008-12-29 18:02:28 +0000158 self.assertEqual(e.filename, ".")
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000159 else:
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200160 self.fail("Should have raised OSError")
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000161
Antoine Pitrou9235b252012-07-06 18:48:24 +0200162 @unittest.skipIf(os.name == 'nt', "test only works on a POSIX-like system")
163 def testOpenDirFD(self):
164 fd = os.open('.', os.O_RDONLY)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200165 with self.assertRaises(OSError) as cm:
Antoine Pitrou9235b252012-07-06 18:48:24 +0200166 _FileIO(fd, 'r')
167 os.close(fd)
168 self.assertEqual(cm.exception.errno, errno.EISDIR)
169
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000170 #A set of functions testing that we get expected behaviour if someone has
171 #manually closed the internal file descriptor. First, a decorator:
172 def ClosedFD(func):
173 @wraps(func)
174 def wrapper(self):
175 #forcibly close the fd before invoking the problem function
176 f = self.f
177 os.close(f.fileno())
178 try:
179 func(self, f)
180 finally:
181 try:
182 self.f.close()
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200183 except OSError:
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000184 pass
185 return wrapper
Antoine Pitrou0ae29cf2009-03-13 22:33:17 +0000186
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000187 def ClosedFDRaises(func):
188 @wraps(func)
189 def wrapper(self):
190 #forcibly close the fd before invoking the problem function
191 f = self.f
192 os.close(f.fileno())
193 try:
194 func(self, f)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200195 except OSError as e:
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000196 self.assertEqual(e.errno, errno.EBADF)
197 else:
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200198 self.fail("Should have raised OSError")
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000199 finally:
200 try:
201 self.f.close()
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200202 except OSError:
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000203 pass
204 return wrapper
205
206 @ClosedFDRaises
207 def testErrnoOnClose(self, f):
208 f.close()
209
210 @ClosedFDRaises
211 def testErrnoOnClosedWrite(self, f):
Benjamin Peterson255058f2010-01-27 01:47:14 +0000212 f.write(b'a')
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000213
214 @ClosedFDRaises
215 def testErrnoOnClosedSeek(self, f):
216 f.seek(0)
217
218 @ClosedFDRaises
219 def testErrnoOnClosedTell(self, f):
220 f.tell()
221
222 @ClosedFDRaises
223 def testErrnoOnClosedTruncate(self, f):
224 f.truncate(0)
225
226 @ClosedFD
227 def testErrnoOnClosedSeekable(self, f):
228 f.seekable()
229
230 @ClosedFD
231 def testErrnoOnClosedReadable(self, f):
232 f.readable()
233
234 @ClosedFD
235 def testErrnoOnClosedWritable(self, f):
236 f.writable()
237
238 @ClosedFD
239 def testErrnoOnClosedFileno(self, f):
240 f.fileno()
241
242 @ClosedFD
243 def testErrnoOnClosedIsatty(self, f):
244 self.assertEqual(f.isatty(), False)
245
246 def ReopenForRead(self):
247 try:
248 self.f.close()
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200249 except OSError:
Kristján Valur Jónssona8abe862009-03-24 15:27:42 +0000250 pass
251 self.f = _FileIO(TESTFN, 'r')
252 os.close(self.f.fileno())
253 return self.f
254
255 @ClosedFDRaises
256 def testErrnoOnClosedRead(self, f):
257 f = self.ReopenForRead()
258 f.read(1)
259
260 @ClosedFDRaises
261 def testErrnoOnClosedReadall(self, f):
262 f = self.ReopenForRead()
263 f.readall()
264
265 @ClosedFDRaises
266 def testErrnoOnClosedReadinto(self, f):
267 f = self.ReopenForRead()
268 a = array('b', b'x'*10)
269 f.readinto(a)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000270
271class OtherFileTests(unittest.TestCase):
272
273 def testAbles(self):
274 try:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000275 f = _FileIO(TESTFN, "w")
Ezio Melottib3aedd42010-11-20 19:04:17 +0000276 self.assertEqual(f.readable(), False)
277 self.assertEqual(f.writable(), True)
278 self.assertEqual(f.seekable(), True)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000279 f.close()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000280
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000281 f = _FileIO(TESTFN, "r")
Ezio Melottib3aedd42010-11-20 19:04:17 +0000282 self.assertEqual(f.readable(), True)
283 self.assertEqual(f.writable(), False)
284 self.assertEqual(f.seekable(), True)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000285 f.close()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000286
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000287 f = _FileIO(TESTFN, "a+")
Ezio Melottib3aedd42010-11-20 19:04:17 +0000288 self.assertEqual(f.readable(), True)
289 self.assertEqual(f.writable(), True)
290 self.assertEqual(f.seekable(), True)
291 self.assertEqual(f.isatty(), False)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000292 f.close()
Guido van Rossum682faf82007-04-12 14:56:58 +0000293
Thomas Hellerb0f48ab2007-07-12 11:29:02 +0000294 if sys.platform != "win32":
295 try:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000296 f = _FileIO("/dev/tty", "a")
Andrew Svetlov3438fa42012-12-17 23:35:18 +0200297 except OSError:
Thomas Hellerb0f48ab2007-07-12 11:29:02 +0000298 # When run in a cron job there just aren't any
299 # ttys, so skip the test. This also handles other
300 # OS'es that don't support /dev/tty.
301 pass
302 else:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000303 self.assertEqual(f.readable(), False)
304 self.assertEqual(f.writable(), True)
Hye-Shik Changcaf871a2007-08-13 13:21:33 +0000305 if sys.platform != "darwin" and \
Antoine Pitroud7b30462009-05-23 16:34:50 +0000306 'bsd' not in sys.platform and \
Benjamin Peterson94fe10f2008-07-17 23:27:26 +0000307 not sys.platform.startswith('sunos'):
Hye-Shik Changcaf871a2007-08-13 13:21:33 +0000308 # Somehow /dev/tty appears seekable on some BSDs
Ezio Melottib3aedd42010-11-20 19:04:17 +0000309 self.assertEqual(f.seekable(), False)
310 self.assertEqual(f.isatty(), True)
Thomas Hellerb0f48ab2007-07-12 11:29:02 +0000311 f.close()
Guido van Rossuma9e20242007-03-08 00:43:48 +0000312 finally:
313 os.unlink(TESTFN)
314
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200315 def testInvalidModeStrings(self):
Guido van Rossuma9e20242007-03-08 00:43:48 +0000316 # check invalid mode strings
Benjamin Peterson44309e62008-11-22 00:41:45 +0000317 for mode in ("", "aU", "wU+", "rw", "rt"):
Guido van Rossuma9e20242007-03-08 00:43:48 +0000318 try:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000319 f = _FileIO(TESTFN, mode)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000320 except ValueError:
321 pass
322 else:
323 f.close()
324 self.fail('%r is an invalid file mode' % mode)
325
Antoine Pitroue93b63b2013-09-04 20:46:33 +0200326 def testModeStrings(self):
327 # test that the mode attribute is correct for various mode strings
328 # given as init args
329 try:
330 for modes in [('w', 'wb'), ('wb', 'wb'), ('wb+', 'rb+'),
331 ('w+b', 'rb+'), ('a', 'ab'), ('ab', 'ab'),
332 ('ab+', 'ab+'), ('a+b', 'ab+'), ('r', 'rb'),
333 ('rb', 'rb'), ('rb+', 'rb+'), ('r+b', 'rb+')]:
334 # read modes are last so that TESTFN will exist first
335 with _FileIO(TESTFN, modes[0]) as f:
336 self.assertEqual(f.mode, modes[1])
337 finally:
338 if os.path.exists(TESTFN):
339 os.unlink(TESTFN)
340
Guido van Rossuma9e20242007-03-08 00:43:48 +0000341 def testUnicodeOpen(self):
342 # verify repr works for unicode too
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000343 f = _FileIO(str(TESTFN), "w")
Guido van Rossuma9e20242007-03-08 00:43:48 +0000344 f.close()
345 os.unlink(TESTFN)
346
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000347 def testBytesOpen(self):
348 # Opening a bytes filename
349 try:
350 fn = TESTFN.encode("ascii")
351 except UnicodeEncodeError:
Zachary Ware9fe6d862013-12-08 00:20:35 -0600352 self.skipTest('could not encode %r to ascii' % TESTFN)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000353 f = _FileIO(fn, "w")
354 try:
355 f.write(b"abc")
356 f.close()
357 with open(TESTFN, "rb") as f:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000358 self.assertEqual(f.read(), b"abc")
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000359 finally:
360 os.unlink(TESTFN)
361
Antoine Pitrou13348842012-01-29 18:36:34 +0100362 def testConstructorHandlesNULChars(self):
363 fn_with_NUL = 'foo\0bar'
364 self.assertRaises(TypeError, _FileIO, fn_with_NUL, 'w')
365 self.assertRaises(TypeError, _FileIO, bytes(fn_with_NUL, 'ascii'), 'w')
366
Benjamin Peterson806d4022009-01-19 15:11:51 +0000367 def testInvalidFd(self):
Antoine Pitrou7fb111b2009-03-04 11:14:01 +0000368 self.assertRaises(ValueError, _FileIO, -10)
369 self.assertRaises(OSError, _FileIO, make_bad_fd())
Antoine Pitrou00492492010-09-04 20:53:29 +0000370 if sys.platform == 'win32':
371 import msvcrt
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200372 self.assertRaises(OSError, msvcrt.get_osfhandle, make_bad_fd())
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200373
374 @cpython_only
375 def testInvalidFd_overflow(self):
Serhiy Storchaka78980432013-01-15 01:12:17 +0200376 # Issue 15989
Serhiy Storchaka5cfc79d2014-02-07 10:06:39 +0200377 import _testcapi
Serhiy Storchaka78980432013-01-15 01:12:17 +0200378 self.assertRaises(TypeError, _FileIO, _testcapi.INT_MAX + 1)
379 self.assertRaises(TypeError, _FileIO, _testcapi.INT_MIN - 1)
Benjamin Peterson806d4022009-01-19 15:11:51 +0000380
Guido van Rossuma9e20242007-03-08 00:43:48 +0000381 def testBadModeArgument(self):
382 # verify that we get a sensible error message for bad mode argument
383 bad_mode = "qwerty"
384 try:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000385 f = _FileIO(TESTFN, bad_mode)
Guido van Rossuma9e20242007-03-08 00:43:48 +0000386 except ValueError as msg:
Guido van Rossum360e4b82007-05-14 22:51:27 +0000387 if msg.args[0] != 0:
Guido van Rossuma9e20242007-03-08 00:43:48 +0000388 s = str(msg)
Ezio Melotti7fb4da72010-03-18 12:29:13 +0000389 if TESTFN in s or bad_mode not in s:
Guido van Rossuma9e20242007-03-08 00:43:48 +0000390 self.fail("bad error message for invalid mode: %s" % s)
Georg Brandl50da60c2008-01-06 21:38:54 +0000391 # if msg.args[0] == 0, we're probably on Windows where there may be
Guido van Rossuma9e20242007-03-08 00:43:48 +0000392 # no obvious way to discover why open() failed.
393 else:
394 f.close()
395 self.fail("no error for invalid mode: %s" % bad_mode)
396
Antoine Pitrou905a2ff2010-01-31 22:47:27 +0000397 def testTruncate(self):
398 f = _FileIO(TESTFN, 'w')
399 f.write(bytes(bytearray(range(10))))
400 self.assertEqual(f.tell(), 10)
401 f.truncate(5)
402 self.assertEqual(f.tell(), 10)
Eli Bendersky74c503b2012-01-03 06:26:13 +0200403 self.assertEqual(f.seek(0, io.SEEK_END), 5)
Antoine Pitrou905a2ff2010-01-31 22:47:27 +0000404 f.truncate(15)
405 self.assertEqual(f.tell(), 5)
Eli Bendersky74c503b2012-01-03 06:26:13 +0200406 self.assertEqual(f.seek(0, io.SEEK_END), 15)
Antoine Pitrou8d2b51b2010-10-30 16:19:14 +0000407 f.close()
Antoine Pitrou905a2ff2010-01-31 22:47:27 +0000408
Guido van Rossuma9e20242007-03-08 00:43:48 +0000409 def testTruncateOnWindows(self):
410 def bug801631():
411 # SF bug <http://www.python.org/sf/801631>
412 # "file.truncate fault on windows"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000413 f = _FileIO(TESTFN, 'w')
Guido van Rossuma9e20242007-03-08 00:43:48 +0000414 f.write(bytes(range(11)))
415 f.close()
416
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000417 f = _FileIO(TESTFN,'r+')
Guido van Rossuma9e20242007-03-08 00:43:48 +0000418 data = f.read(5)
419 if data != bytes(range(5)):
420 self.fail("Read on file opened for update failed %r" % data)
421 if f.tell() != 5:
422 self.fail("File pos after read wrong %d" % f.tell())
423
424 f.truncate()
425 if f.tell() != 5:
426 self.fail("File pos after ftruncate wrong %d" % f.tell())
427
428 f.close()
429 size = os.path.getsize(TESTFN)
430 if size != 5:
431 self.fail("File size after ftruncate wrong %d" % size)
432
433 try:
434 bug801631()
435 finally:
436 os.unlink(TESTFN)
437
Walter Dörwald3a77c7a2007-06-06 16:31:14 +0000438 def testAppend(self):
439 try:
440 f = open(TESTFN, 'wb')
441 f.write(b'spam')
442 f.close()
443 f = open(TESTFN, 'ab')
444 f.write(b'eggs')
445 f.close()
446 f = open(TESTFN, 'rb')
447 d = f.read()
448 f.close()
449 self.assertEqual(d, b'spameggs')
450 finally:
451 try:
452 os.unlink(TESTFN)
453 except:
454 pass
455
Neal Norwitz6e0e0e62008-08-24 22:07:28 +0000456 def testInvalidInit(self):
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000457 self.assertRaises(TypeError, _FileIO, "1", 0, 0)
Neal Norwitz6e0e0e62008-08-24 22:07:28 +0000458
Benjamin Peterson65676e42008-11-05 21:42:45 +0000459 def testWarnings(self):
Florent Xiclunab14930c2010-03-13 15:26:44 +0000460 with check_warnings(quiet=True) as w:
Benjamin Peterson65676e42008-11-05 21:42:45 +0000461 self.assertEqual(w.warnings, [])
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000462 self.assertRaises(TypeError, _FileIO, [])
Benjamin Peterson65676e42008-11-05 21:42:45 +0000463 self.assertEqual(w.warnings, [])
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000464 self.assertRaises(ValueError, _FileIO, "/some/invalid/name", "rt")
Benjamin Peterson65676e42008-11-05 21:42:45 +0000465 self.assertEqual(w.warnings, [])
466
Hynek Schlawack9ed8b4e2012-06-21 20:20:25 +0200467 def testUnclosedFDOnException(self):
468 class MyException(Exception): pass
469 class MyFileIO(_FileIO):
470 def __setattr__(self, name, value):
471 if name == "name":
472 raise MyException("blocked setting name")
473 return super(MyFileIO, self).__setattr__(name, value)
474 fd = os.open(__file__, os.O_RDONLY)
475 self.assertRaises(MyException, MyFileIO, fd)
476 os.close(fd) # should not raise OSError(EBADF)
477
Neal Norwitz6e0e0e62008-08-24 22:07:28 +0000478
Guido van Rossuma9e20242007-03-08 00:43:48 +0000479def test_main():
480 # Historically, these tests have been sloppy about removing TESTFN.
481 # So get rid of it no matter what.
482 try:
483 run_unittest(AutoFileTests, OtherFileTests)
484 finally:
485 if os.path.exists(TESTFN):
486 os.unlink(TESTFN)
487
488if __name__ == '__main__':
489 test_main()