blob: 744454832fa54ff5864c86a624cdfd9da5178ea4 [file] [log] [blame]
Martin v. Löwisf90ae202002-06-11 06:22:31 +00001import sys
Fred Drake2ec80fa2000-10-23 16:59:35 +00002import os
Georg Brandl442b49e2006-06-08 14:50:53 +00003import unittest
Gregory P. Smithaa63d0d2008-04-06 23:11:17 +00004import itertools
5import time
6import threading
Neal Norwitz62f5a9d2002-04-01 00:09:00 +00007from array import array
Raymond Hettingercb87bc82004-05-31 00:35:52 +00008from weakref import proxy
Fred Drake2ec80fa2000-10-23 16:59:35 +00009
Gregory P. Smithaa63d0d2008-04-06 23:11:17 +000010from test import test_support
Georg Brandl442b49e2006-06-08 14:50:53 +000011from test.test_support import TESTFN, findfile, run_unittest
Marc-André Lemburgfa44d792000-08-25 22:37:31 +000012from UserList import UserList
13
Georg Brandl442b49e2006-06-08 14:50:53 +000014class AutoFileTests(unittest.TestCase):
15 # file tests for which a test file is automatically set up
Raymond Hettingercb87bc82004-05-31 00:35:52 +000016
Georg Brandl442b49e2006-06-08 14:50:53 +000017 def setUp(self):
Tim Petersdbb82f62006-06-09 03:51:41 +000018 self.f = open(TESTFN, 'wb')
Tim Peters015dd822003-05-04 04:16:52 +000019
Georg Brandl442b49e2006-06-08 14:50:53 +000020 def tearDown(self):
Tim Petersdbb82f62006-06-09 03:51:41 +000021 if self.f:
22 self.f.close()
23 os.remove(TESTFN)
Georg Brandl442b49e2006-06-08 14:50:53 +000024
25 def testWeakRefs(self):
26 # verify weak references
27 p = proxy(self.f)
28 p.write('teststring')
29 self.assertEquals(self.f.tell(), p.tell())
30 self.f.close()
31 self.f = None
32 self.assertRaises(ReferenceError, getattr, p, 'tell')
33
34 def testAttributes(self):
35 # verify expected attributes exist
36 f = self.f
Ezio Melottidfe21072010-08-03 07:17:20 +000037
Georg Brandl442b49e2006-06-08 14:50:53 +000038 f.name # merely shouldn't blow up
39 f.mode # ditto
40 f.closed # ditto
41
Ezio Melottidfe21072010-08-03 07:17:20 +000042 with test_support._check_py3k_warnings(
43 ('file.softspace not supported in 3.x', DeprecationWarning)):
44 softspace = f.softspace
45 # verify softspace is writable
46 f.softspace = softspace # merely shouldn't blow up
Georg Brandl442b49e2006-06-08 14:50:53 +000047
48 # verify the others aren't
49 for attr in 'name', 'mode', 'closed':
50 self.assertRaises((AttributeError, TypeError), setattr, f, attr, 'oops')
51
52 def testReadinto(self):
53 # verify readinto
54 self.f.write('12')
55 self.f.close()
56 a = array('c', 'x'*10)
57 self.f = open(TESTFN, 'rb')
58 n = self.f.readinto(a)
59 self.assertEquals('12', a.tostring()[:n])
60
61 def testWritelinesUserList(self):
62 # verify writelines with instance sequence
63 l = UserList(['1', '2'])
64 self.f.writelines(l)
65 self.f.close()
66 self.f = open(TESTFN, 'rb')
67 buf = self.f.read()
68 self.assertEquals(buf, '12')
69
70 def testWritelinesIntegers(self):
71 # verify writelines with integers
72 self.assertRaises(TypeError, self.f.writelines, [1, 2, 3])
73
74 def testWritelinesIntegersUserList(self):
75 # verify writelines with integers in UserList
76 l = UserList([1,2,3])
77 self.assertRaises(TypeError, self.f.writelines, l)
78
79 def testWritelinesNonString(self):
80 # verify writelines with non-string object
Tim Petersdbb82f62006-06-09 03:51:41 +000081 class NonString:
82 pass
Georg Brandl442b49e2006-06-08 14:50:53 +000083
Tim Petersdbb82f62006-06-09 03:51:41 +000084 self.assertRaises(TypeError, self.f.writelines,
85 [NonString(), NonString()])
Georg Brandl442b49e2006-06-08 14:50:53 +000086
87 def testRepr(self):
88 # verify repr works
89 self.assert_(repr(self.f).startswith("<open file '" + TESTFN))
90
91 def testErrors(self):
Antoine Pitrou24837282010-02-05 17:11:32 +000092 self.f.close()
93 self.f = open(TESTFN, 'rb')
Georg Brandl442b49e2006-06-08 14:50:53 +000094 f = self.f
95 self.assertEquals(f.name, TESTFN)
96 self.assert_(not f.isatty())
97 self.assert_(not f.closed)
Tim Peters520d8dd2006-06-09 02:11:02 +000098
Georg Brandl442b49e2006-06-08 14:50:53 +000099 self.assertRaises(TypeError, f.readinto, "")
100 f.close()
101 self.assert_(f.closed)
102
103 def testMethods(self):
104 methods = ['fileno', 'flush', 'isatty', 'next', 'read', 'readinto',
Tim Petersdbb82f62006-06-09 03:51:41 +0000105 'readline', 'readlines', 'seek', 'tell', 'truncate',
106 'write', 'xreadlines', '__iter__']
Georg Brandl442b49e2006-06-08 14:50:53 +0000107 if sys.platform.startswith('atheos'):
108 methods.remove('truncate')
109
Georg Brandle7ec81f2006-06-09 18:29:52 +0000110 # __exit__ should close the file
111 self.f.__exit__(None, None, None)
112 self.assert_(self.f.closed)
Georg Brandl442b49e2006-06-08 14:50:53 +0000113
114 for methodname in methods:
115 method = getattr(self.f, methodname)
116 # should raise on closed file
Ezio Melottidfe21072010-08-03 07:17:20 +0000117 with test_support._check_py3k_warnings(quiet=True):
118 self.assertRaises(ValueError, method)
Georg Brandl442b49e2006-06-08 14:50:53 +0000119 self.assertRaises(ValueError, self.f.writelines, [])
120
Georg Brandle7ec81f2006-06-09 18:29:52 +0000121 # file is closed, __exit__ shouldn't do anything
122 self.assertEquals(self.f.__exit__(None, None, None), None)
123 # it must also return None if an exception was given
124 try:
Ezio Melotti3efafd72010-08-02 18:40:55 +0000125 1 // 0
Georg Brandle7ec81f2006-06-09 18:29:52 +0000126 except:
127 self.assertEquals(self.f.__exit__(*sys.exc_info()), None)
128
Skip Montanaro6a00c742008-12-23 03:35:04 +0000129 def testReadWhenWriting(self):
130 self.assertRaises(IOError, self.f.read)
Georg Brandl442b49e2006-06-08 14:50:53 +0000131
Antoine Pitrou24837282010-02-05 17:11:32 +0000132 def testIssue5677(self):
133 # Remark: Do not perform more than one test per open file,
134 # since that does NOT catch the readline error on Windows.
135 data = 'xxx'
136 for mode in ['w', 'wb', 'a', 'ab']:
137 for attr in ['read', 'readline', 'readlines']:
138 self.f = open(TESTFN, mode)
139 self.f.write(data)
140 self.assertRaises(IOError, getattr(self.f, attr))
141 self.f.close()
142
143 self.f = open(TESTFN, mode)
144 self.f.write(data)
145 self.assertRaises(IOError, lambda: [line for line in self.f])
146 self.f.close()
147
148 self.f = open(TESTFN, mode)
149 self.f.write(data)
150 self.assertRaises(IOError, self.f.readinto, bytearray(len(data)))
151 self.f.close()
152
153 for mode in ['r', 'rb', 'U', 'Ub', 'Ur', 'rU', 'rbU', 'rUb']:
154 self.f = open(TESTFN, mode)
155 self.assertRaises(IOError, self.f.write, data)
156 self.f.close()
157
158 self.f = open(TESTFN, mode)
159 self.assertRaises(IOError, self.f.writelines, [data, data])
160 self.f.close()
161
162 self.f = open(TESTFN, mode)
163 self.assertRaises(IOError, self.f.truncate)
164 self.f.close()
165
Georg Brandl442b49e2006-06-08 14:50:53 +0000166class OtherFileTests(unittest.TestCase):
167
Georg Brandl47fe9812009-01-01 15:46:10 +0000168 def testOpenDir(self):
169 this_dir = os.path.dirname(__file__)
170 for mode in (None, "w"):
171 try:
172 if mode:
173 f = open(this_dir, mode)
174 else:
175 f = open(this_dir)
176 except IOError as e:
177 self.assertEqual(e.filename, this_dir)
178 else:
179 self.fail("opening a directory didn't raise an IOError")
180
Georg Brandl442b49e2006-06-08 14:50:53 +0000181 def testModeStrings(self):
182 # check invalid mode strings
183 for mode in ("", "aU", "wU+"):
184 try:
Tim Petersdbb82f62006-06-09 03:51:41 +0000185 f = open(TESTFN, mode)
Georg Brandl442b49e2006-06-08 14:50:53 +0000186 except ValueError:
187 pass
188 else:
189 f.close()
190 self.fail('%r is an invalid file mode' % mode)
191
Amaury Forgeot d'Arc17617a02008-09-25 20:52:56 +0000192 # Some invalid modes fail on Windows, but pass on Unix
193 # Issue3965: avoid a crash on Windows when filename is unicode
194 for name in (TESTFN, unicode(TESTFN), unicode(TESTFN + '\t')):
195 try:
196 f = open(name, "rr")
197 except IOError:
198 pass
199 else:
200 f.close()
201
Georg Brandl442b49e2006-06-08 14:50:53 +0000202 def testStdin(self):
203 # This causes the interpreter to exit on OSF1 v5.1.
204 if sys.platform != 'osf1V5':
205 self.assertRaises(IOError, sys.stdin.seek, -1)
Thomas Woutersc45251a2006-02-12 11:53:32 +0000206 else:
Georg Brandl442b49e2006-06-08 14:50:53 +0000207 print >>sys.__stdout__, (
208 ' Skipping sys.stdin.seek(-1), it may crash the interpreter.'
209 ' Test manually.')
210 self.assertRaises(IOError, sys.stdin.truncate)
211
212 def testUnicodeOpen(self):
213 # verify repr works for unicode too
214 f = open(unicode(TESTFN), "w")
215 self.assert_(repr(f).startswith("<open file u'" + TESTFN))
Thomas Woutersc45251a2006-02-12 11:53:32 +0000216 f.close()
Tim Peters0556e9b2006-06-09 04:02:06 +0000217 os.unlink(TESTFN)
Thomas Woutersc45251a2006-02-12 11:53:32 +0000218
Georg Brandl442b49e2006-06-08 14:50:53 +0000219 def testBadModeArgument(self):
220 # verify that we get a sensible error message for bad mode argument
221 bad_mode = "qwerty"
Tim Peterscffcfed2006-02-14 17:41:18 +0000222 try:
Georg Brandl442b49e2006-06-08 14:50:53 +0000223 f = open(TESTFN, bad_mode)
224 except ValueError, msg:
Ezio Melottidfe21072010-08-03 07:17:20 +0000225 if msg.args[0] != 0:
Georg Brandl442b49e2006-06-08 14:50:53 +0000226 s = str(msg)
Ezio Melottic0fd6ff2010-03-23 13:20:39 +0000227 if TESTFN in s or bad_mode not in s:
Georg Brandl442b49e2006-06-08 14:50:53 +0000228 self.fail("bad error message for invalid mode: %s" % s)
229 # if msg[0] == 0, we're probably on Windows where there may be
230 # no obvious way to discover why open() failed.
231 else:
232 f.close()
233 self.fail("no error for invalid mode: %s" % bad_mode)
234
235 def testSetBufferSize(self):
236 # make sure that explicitly setting the buffer size doesn't cause
237 # misbehaviour especially with repeated close() calls
238 for s in (-1, 0, 1, 512):
239 try:
240 f = open(TESTFN, 'w', s)
241 f.write(str(s))
242 f.close()
243 f.close()
244 f = open(TESTFN, 'r', s)
245 d = int(f.read())
246 f.close()
247 f.close()
248 except IOError, msg:
249 self.fail('error setting buffer size %d: %s' % (s, str(msg)))
250 self.assertEquals(d, s)
251
252 def testTruncateOnWindows(self):
253 os.unlink(TESTFN)
254
255 def bug801631():
256 # SF bug <http://www.python.org/sf/801631>
257 # "file.truncate fault on windows"
Tim Petersdbb82f62006-06-09 03:51:41 +0000258 f = open(TESTFN, 'wb')
Georg Brandl442b49e2006-06-08 14:50:53 +0000259 f.write('12345678901') # 11 bytes
260 f.close()
261
Tim Petersdbb82f62006-06-09 03:51:41 +0000262 f = open(TESTFN,'rb+')
Georg Brandl442b49e2006-06-08 14:50:53 +0000263 data = f.read(5)
264 if data != '12345':
265 self.fail("Read on file opened for update failed %r" % data)
266 if f.tell() != 5:
267 self.fail("File pos after read wrong %d" % f.tell())
268
269 f.truncate()
270 if f.tell() != 5:
271 self.fail("File pos after ftruncate wrong %d" % f.tell())
272
273 f.close()
274 size = os.path.getsize(TESTFN)
275 if size != 5:
276 self.fail("File size after ftruncate wrong %d" % size)
277
278 try:
279 bug801631()
280 finally:
281 os.unlink(TESTFN)
282
283 def testIteration(self):
Tim Petersdbb82f62006-06-09 03:51:41 +0000284 # Test the complex interaction when mixing file-iteration and the
285 # various read* methods. Ostensibly, the mixture could just be tested
286 # to work when it should work according to the Python language,
287 # instead of fail when it should fail according to the current CPython
288 # implementation. People don't always program Python the way they
289 # should, though, and the implemenation might change in subtle ways,
290 # so we explicitly test for errors, too; the test will just have to
291 # be updated when the implementation changes.
Georg Brandl442b49e2006-06-08 14:50:53 +0000292 dataoffset = 16384
293 filler = "ham\n"
294 assert not dataoffset % len(filler), \
295 "dataoffset must be multiple of len(filler)"
296 nchunks = dataoffset // len(filler)
297 testlines = [
298 "spam, spam and eggs\n",
299 "eggs, spam, ham and spam\n",
300 "saussages, spam, spam and eggs\n",
301 "spam, ham, spam and eggs\n",
302 "spam, spam, spam, spam, spam, ham, spam\n",
303 "wonderful spaaaaaam.\n"
304 ]
305 methods = [("readline", ()), ("read", ()), ("readlines", ()),
306 ("readinto", (array("c", " "*100),))]
307
308 try:
309 # Prepare the testfile
310 bag = open(TESTFN, "w")
311 bag.write(filler * nchunks)
312 bag.writelines(testlines)
313 bag.close()
314 # Test for appropriate errors mixing read* and iteration
315 for methodname, args in methods:
316 f = open(TESTFN)
317 if f.next() != filler:
318 self.fail, "Broken testfile"
319 meth = getattr(f, methodname)
320 try:
321 meth(*args)
322 except ValueError:
323 pass
324 else:
325 self.fail("%s%r after next() didn't raise ValueError" %
326 (methodname, args))
327 f.close()
328
Tim Petersdbb82f62006-06-09 03:51:41 +0000329 # Test to see if harmless (by accident) mixing of read* and
330 # iteration still works. This depends on the size of the internal
331 # iteration buffer (currently 8192,) but we can test it in a
332 # flexible manner. Each line in the bag o' ham is 4 bytes
333 # ("h", "a", "m", "\n"), so 4096 lines of that should get us
334 # exactly on the buffer boundary for any power-of-2 buffersize
335 # between 4 and 16384 (inclusive).
Georg Brandl442b49e2006-06-08 14:50:53 +0000336 f = open(TESTFN)
337 for i in range(nchunks):
338 f.next()
339 testline = testlines.pop(0)
340 try:
341 line = f.readline()
342 except ValueError:
343 self.fail("readline() after next() with supposedly empty "
344 "iteration-buffer failed anyway")
345 if line != testline:
346 self.fail("readline() after next() with empty buffer "
347 "failed. Got %r, expected %r" % (line, testline))
348 testline = testlines.pop(0)
349 buf = array("c", "\x00" * len(testline))
350 try:
351 f.readinto(buf)
352 except ValueError:
353 self.fail("readinto() after next() with supposedly empty "
354 "iteration-buffer failed anyway")
355 line = buf.tostring()
356 if line != testline:
357 self.fail("readinto() after next() with empty buffer "
358 "failed. Got %r, expected %r" % (line, testline))
359
360 testline = testlines.pop(0)
361 try:
362 line = f.read(len(testline))
363 except ValueError:
364 self.fail("read() after next() with supposedly empty "
365 "iteration-buffer failed anyway")
366 if line != testline:
367 self.fail("read() after next() with empty buffer "
368 "failed. Got %r, expected %r" % (line, testline))
369 try:
370 lines = f.readlines()
371 except ValueError:
372 self.fail("readlines() after next() with supposedly empty "
373 "iteration-buffer failed anyway")
374 if lines != testlines:
375 self.fail("readlines() after next() with empty buffer "
376 "failed. Got %r, expected %r" % (line, testline))
377 # Reading after iteration hit EOF shouldn't hurt either
378 f = open(TESTFN)
379 try:
380 for line in f:
381 pass
382 try:
383 f.readline()
384 f.readinto(buf)
385 f.read()
386 f.readlines()
387 except ValueError:
388 self.fail("read* failed after next() consumed file")
389 finally:
390 f.close()
391 finally:
392 os.unlink(TESTFN)
393
Georg Brandlad61bc82008-02-23 15:11:18 +0000394class FileSubclassTests(unittest.TestCase):
395
396 def testExit(self):
397 # test that exiting with context calls subclass' close
398 class C(file):
399 def __init__(self, *args):
400 self.subclass_closed = False
401 file.__init__(self, *args)
402 def close(self):
403 self.subclass_closed = True
404 file.close(self)
405
406 with C(TESTFN, 'w') as f:
407 pass
408 self.failUnless(f.subclass_closed)
409
Georg Brandl442b49e2006-06-08 14:50:53 +0000410
Gregory P. Smithaa63d0d2008-04-06 23:11:17 +0000411class FileThreadingTests(unittest.TestCase):
412 # These tests check the ability to call various methods of file objects
413 # (including close()) concurrently without crashing the Python interpreter.
414 # See #815646, #595601
415
416 def setUp(self):
417 self.f = None
418 self.filename = TESTFN
419 with open(self.filename, "w") as f:
420 f.write("\n".join("0123456789"))
421 self._count_lock = threading.Lock()
422 self.close_count = 0
423 self.close_success_count = 0
Antoine Pitrou5de15942010-05-17 20:00:52 +0000424 self.use_buffering = False
Gregory P. Smithaa63d0d2008-04-06 23:11:17 +0000425
426 def tearDown(self):
427 if self.f:
428 try:
429 self.f.close()
430 except (EnvironmentError, ValueError):
431 pass
432 try:
433 os.remove(self.filename)
434 except EnvironmentError:
435 pass
436
437 def _create_file(self):
Antoine Pitrou5de15942010-05-17 20:00:52 +0000438 if self.use_buffering:
439 self.f = open(self.filename, "w+", buffering=1024*16)
440 else:
441 self.f = open(self.filename, "w+")
Gregory P. Smithaa63d0d2008-04-06 23:11:17 +0000442
443 def _close_file(self):
444 with self._count_lock:
445 self.close_count += 1
446 self.f.close()
447 with self._count_lock:
448 self.close_success_count += 1
449
450 def _close_and_reopen_file(self):
451 self._close_file()
452 # if close raises an exception thats fine, self.f remains valid so
453 # we don't need to reopen.
454 self._create_file()
455
456 def _run_workers(self, func, nb_workers, duration=0.2):
457 with self._count_lock:
458 self.close_count = 0
459 self.close_success_count = 0
460 self.do_continue = True
461 threads = []
462 try:
463 for i in range(nb_workers):
464 t = threading.Thread(target=func)
465 t.start()
466 threads.append(t)
467 for _ in xrange(100):
468 time.sleep(duration/100)
469 with self._count_lock:
470 if self.close_count-self.close_success_count > nb_workers+1:
471 if test_support.verbose:
472 print 'Q',
473 break
474 time.sleep(duration)
475 finally:
476 self.do_continue = False
477 for t in threads:
478 t.join()
479
480 def _test_close_open_io(self, io_func, nb_workers=5):
481 def worker():
482 self._create_file()
483 funcs = itertools.cycle((
484 lambda: io_func(),
485 lambda: self._close_and_reopen_file(),
486 ))
487 for f in funcs:
488 if not self.do_continue:
489 break
490 try:
491 f()
492 except (IOError, ValueError):
493 pass
494 self._run_workers(worker, nb_workers)
495 if test_support.verbose:
496 # Useful verbose statistics when tuning this test to take
497 # less time to run but still ensuring that its still useful.
498 #
499 # the percent of close calls that raised an error
500 percent = 100. - 100.*self.close_success_count/self.close_count
501 print self.close_count, ('%.4f ' % percent),
502
503 def test_close_open(self):
504 def io_func():
505 pass
506 self._test_close_open_io(io_func)
507
508 def test_close_open_flush(self):
509 def io_func():
510 self.f.flush()
511 self._test_close_open_io(io_func)
512
513 def test_close_open_iter(self):
514 def io_func():
515 list(iter(self.f))
516 self._test_close_open_io(io_func)
517
518 def test_close_open_isatty(self):
519 def io_func():
520 self.f.isatty()
521 self._test_close_open_io(io_func)
522
523 def test_close_open_print(self):
524 def io_func():
525 print >> self.f, ''
526 self._test_close_open_io(io_func)
527
Antoine Pitrou5de15942010-05-17 20:00:52 +0000528 def test_close_open_print_buffered(self):
529 self.use_buffering = True
530 def io_func():
531 print >> self.f, ''
532 self._test_close_open_io(io_func)
533
Gregory P. Smithaa63d0d2008-04-06 23:11:17 +0000534 def test_close_open_read(self):
535 def io_func():
536 self.f.read(0)
537 self._test_close_open_io(io_func)
538
539 def test_close_open_readinto(self):
540 def io_func():
541 a = array('c', 'xxxxx')
542 self.f.readinto(a)
543 self._test_close_open_io(io_func)
544
545 def test_close_open_readline(self):
546 def io_func():
547 self.f.readline()
548 self._test_close_open_io(io_func)
549
550 def test_close_open_readlines(self):
551 def io_func():
552 self.f.readlines()
553 self._test_close_open_io(io_func)
554
555 def test_close_open_seek(self):
556 def io_func():
557 self.f.seek(0, 0)
558 self._test_close_open_io(io_func)
559
560 def test_close_open_tell(self):
561 def io_func():
562 self.f.tell()
563 self._test_close_open_io(io_func)
564
565 def test_close_open_truncate(self):
566 def io_func():
567 self.f.truncate()
568 self._test_close_open_io(io_func)
569
570 def test_close_open_write(self):
571 def io_func():
572 self.f.write('')
573 self._test_close_open_io(io_func)
574
575 def test_close_open_writelines(self):
576 def io_func():
577 self.f.writelines('')
578 self._test_close_open_io(io_func)
579
580
Amaury Forgeot d'Arcbdd941f2008-07-01 20:38:04 +0000581class StdoutTests(unittest.TestCase):
582
583 def test_move_stdout_on_write(self):
584 # Issue 3242: sys.stdout can be replaced (and freed) during a
585 # print statement; prevent a segfault in this case
586 save_stdout = sys.stdout
587
588 class File:
589 def write(self, data):
590 if '\n' in data:
591 sys.stdout = save_stdout
592
593 try:
594 sys.stdout = File()
595 print "some text"
596 finally:
597 sys.stdout = save_stdout
598
Jeffrey Yasskin69614982008-12-11 05:21:18 +0000599 def test_del_stdout_before_print(self):
600 # Issue 4597: 'print' with no argument wasn't reporting when
601 # sys.stdout was deleted.
602 save_stdout = sys.stdout
603 del sys.stdout
604 try:
605 print
606 except RuntimeError as e:
607 self.assertEquals(str(e), "lost sys.stdout")
608 else:
609 self.fail("Expected RuntimeError")
610 finally:
611 sys.stdout = save_stdout
612
Gregory P. Smithaa63d0d2008-04-06 23:11:17 +0000613
Georg Brandl442b49e2006-06-08 14:50:53 +0000614def test_main():
Neal Norwitzc9778a82006-06-09 05:54:18 +0000615 # Historically, these tests have been sloppy about removing TESTFN.
616 # So get rid of it no matter what.
Tim Peters0556e9b2006-06-09 04:02:06 +0000617 try:
Gregory P. Smithaa63d0d2008-04-06 23:11:17 +0000618 run_unittest(AutoFileTests, OtherFileTests, FileSubclassTests,
Amaury Forgeot d'Arcbdd941f2008-07-01 20:38:04 +0000619 FileThreadingTests, StdoutTests)
Tim Peters0556e9b2006-06-09 04:02:06 +0000620 finally:
621 if os.path.exists(TESTFN):
622 os.unlink(TESTFN)
Georg Brandl442b49e2006-06-08 14:50:53 +0000623
624if __name__ == '__main__':
625 test_main()