10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Adapted from test_file.py by Daniel Stutzbach
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom __future__ import unicode_literals
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport errno
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unittest
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom array import array
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom weakref import proxy
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom functools import wraps
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom UserList import UserList
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport _testcapi
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test.test_support import TESTFN, check_warnings, run_unittest, make_bad_fd
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test.test_support import py3k_bytes as bytes
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test.script_helper import run_python
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom _io import FileIO as _FileIO
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass AutoFileTests(unittest.TestCase):
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # file tests for which a test file is automatically set up
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def setUp(self):
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f = _FileIO(TESTFN, 'w')
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def tearDown(self):
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.f:
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.f.close()
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        os.remove(TESTFN)
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testWeakRefs(self):
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # verify weak references
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p = proxy(self.f)
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        p.write(bytes(range(10)))
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.f.tell(), p.tell())
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.close()
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f = None
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ReferenceError, getattr, p, 'tell')
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testSeekTell(self):
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.write(bytes(range(20)))
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.f.tell(), 20)
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.seek(0)
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.f.tell(), 0)
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.seek(10)
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.f.tell(), 10)
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.seek(5, 1)
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.f.tell(), 15)
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.seek(-5, 1)
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.f.tell(), 10)
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.seek(-5, 2)
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.f.tell(), 15)
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testAttributes(self):
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # verify expected attributes exist
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.f
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(f.mode, "wb")
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(f.closed, False)
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # verify the attributes are readonly
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for attr in 'mode', 'closed':
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises((AttributeError, TypeError),
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                              setattr, f, attr, 'oops')
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testReadinto(self):
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # verify readinto
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.write(b"\x01\x02")
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.close()
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = array(b'b', b'x'*10)
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f = _FileIO(TESTFN, 'r')
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        n = self.f.readinto(a)
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(array(b'b', [1, 2]), a[:n])
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testWritelinesList(self):
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        l = [b'123', b'456']
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.writelines(l)
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.close()
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f = _FileIO(TESTFN, 'rb')
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        buf = self.f.read()
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(buf, b'123456')
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testWritelinesUserList(self):
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        l = UserList([b'123', b'456'])
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.writelines(l)
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.close()
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f = _FileIO(TESTFN, 'rb')
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        buf = self.f.read()
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(buf, b'123456')
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testWritelinesError(self):
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, self.f.writelines, [1, 2, 3])
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, self.f.writelines, None)
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_none_args(self):
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.write(b"hi\nbye\nabc")
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.close()
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f = _FileIO(TESTFN, 'r')
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.f.read(None), b"hi\nbye\nabc")
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.seek(0)
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.f.readline(None), b"hi\n")
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(self.f.readlines(None), [b"bye\n", b"abc"])
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testRepr(self):
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(self.f), "<_io.FileIO name=%r mode='%s'>"
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                       % (self.f.name, self.f.mode))
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        del self.f.name
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(self.f), "<_io.FileIO fd=%r mode='%s'>"
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                       % (self.f.fileno(), self.f.mode))
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.close()
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(repr(self.f), "<_io.FileIO [closed]>")
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrors(self):
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.f
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not f.isatty())
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not f.closed)
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #self.assertEqual(f.name, TESTFN)
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, f.read, 10) # Open for reading
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.close()
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(f.closed)
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = _FileIO(TESTFN, 'r')
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, f.readinto, "")
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(not f.closed)
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.close()
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(f.closed)
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testMethods(self):
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        methods = ['fileno', 'isatty', 'read', 'readinto',
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                   'seek', 'tell', 'truncate', 'write', 'seekable',
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                   'readable', 'writable']
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if sys.platform.startswith('atheos'):
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            methods.remove('truncate')
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f.close()
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(self.f.closed)
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for methodname in methods:
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            method = getattr(self.f, methodname)
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # should raise on closed file
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(ValueError, method)
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testOpendir(self):
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Issue 3703: opening a directory should fill the errno
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Windows always returns "[Errno 13]: Permission denied
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Unix calls dircheck() and returns "[Errno 21]: Is a directory"
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _FileIO('.', 'r')
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except IOError as e:
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertNotEqual(e.errno, 0)
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(e.filename, ".")
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fail("Should have raised IOError")
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @unittest.skipIf(os.name == 'nt', "test only works on a POSIX-like system")
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testOpenDirFD(self):
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fd = os.open('.', os.O_RDONLY)
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        with self.assertRaises(IOError) as cm:
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _FileIO(fd, 'r')
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        os.close(fd)
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(cm.exception.errno, errno.EISDIR)
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #A set of functions testing that we get expected behaviour if someone has
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #manually closed the internal file descriptor.  First, a decorator:
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def ClosedFD(func):
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        @wraps(func)
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def wrapper(self):
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #forcibly close the fd before invoking the problem function
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f = self.f
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            os.close(f.fileno())
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                func(self, f)
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            finally:
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                try:
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.f.close()
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                except IOError:
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    pass
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return wrapper
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def ClosedFDRaises(func):
1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        @wraps(func)
1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def wrapper(self):
1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #forcibly close the fd before invoking the problem function
1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f = self.f
1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            os.close(f.fileno())
1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                func(self, f)
1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except IOError as e:
1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(e.errno, errno.EBADF)
1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fail("Should have raised IOError")
1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            finally:
1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                try:
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.f.close()
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                except IOError:
1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    pass
1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return wrapper
1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFDRaises
2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClose(self, f):
2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.close()
2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFDRaises
2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClosedWrite(self, f):
2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.write('a')
2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFDRaises
2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClosedSeek(self, f):
2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.seek(0)
2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFDRaises
2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClosedTell(self, f):
2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.tell()
2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFDRaises
2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClosedTruncate(self, f):
2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.truncate(0)
2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFD
2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClosedSeekable(self, f):
2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.seekable()
2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFD
2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClosedReadable(self, f):
2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.readable()
2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFD
2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClosedWritable(self, f):
2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.writable()
2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFD
2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClosedFileno(self, f):
2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.fileno()
2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFD
2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClosedIsatty(self, f):
2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(f.isatty(), False)
2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def ReopenForRead(self):
2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.f.close()
2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except IOError:
2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.f = _FileIO(TESTFN, 'r')
2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        os.close(self.f.fileno())
2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.f
2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFDRaises
2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClosedRead(self, f):
2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.ReopenForRead()
2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.read(1)
2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFDRaises
2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClosedReadall(self, f):
2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.ReopenForRead()
2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.readall()
2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @ClosedFDRaises
2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testErrnoOnClosedReadinto(self, f):
2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.ReopenForRead()
2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = array(b'b', b'x'*10)
2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.readinto(a)
2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass OtherFileTests(unittest.TestCase):
2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testAbles(self):
2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f = _FileIO(TESTFN, "w")
2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(f.readable(), False)
2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(f.writable(), True)
2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(f.seekable(), True)
2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.close()
2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f = _FileIO(TESTFN, "r")
2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(f.readable(), True)
2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(f.writable(), False)
2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(f.seekable(), True)
2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.close()
2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f = _FileIO(TESTFN, "a+")
2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(f.readable(), True)
2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(f.writable(), True)
2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(f.seekable(), True)
2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(f.isatty(), False)
2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.close()
2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if sys.platform != "win32":
2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                try:
2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    f = _FileIO("/dev/tty", "a")
2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                except EnvironmentError:
2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # When run in a cron job there just aren't any
2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # ttys, so skip the test.  This also handles other
2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # OS'es that don't support /dev/tty.
2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    pass
2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                else:
2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(f.readable(), False)
2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(f.writable(), True)
2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    if sys.platform != "darwin" and \
2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       'bsd' not in sys.platform and \
3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                       not sys.platform.startswith('sunos'):
3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        # Somehow /dev/tty appears seekable on some BSDs
3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        self.assertEqual(f.seekable(), False)
3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertEqual(f.isatty(), True)
3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    f.close()
3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            os.unlink(TESTFN)
3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testModeStrings(self):
3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # check invalid mode strings
3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for mode in ("", "aU", "wU+", "rw", "rt"):
3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                f = _FileIO(TESTFN, mode)
3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except ValueError:
3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass
3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                f.close()
3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fail('%r is an invalid file mode' % mode)
3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testUnicodeOpen(self):
3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # verify repr works for unicode too
3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = _FileIO(str(TESTFN), "w")
3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.close()
3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        os.unlink(TESTFN)
3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testBytesOpen(self):
3260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Opening a bytes filename
3270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fn = TESTFN.encode("ascii")
3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except UnicodeEncodeError:
3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Skip test
3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return
3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = _FileIO(fn, "w")
3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.write(b"abc")
3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.close()
3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            with open(TESTFN, "rb") as f:
3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(f.read(), b"abc")
3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            os.unlink(TESTFN)
3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testInvalidFd(self):
3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(ValueError, _FileIO, -10)
3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(OSError, _FileIO, make_bad_fd())
3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if sys.platform == 'win32':
3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            import msvcrt
3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(IOError, msvcrt.get_osfhandle, make_bad_fd())
3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Issue 15989
3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, _FileIO, _testcapi.INT_MAX + 1)
3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, _FileIO, _testcapi.INT_MIN - 1)
3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testBadModeArgument(self):
3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # verify that we get a sensible error message for bad mode argument
3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        bad_mode = "qwerty"
3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f = _FileIO(TESTFN, bad_mode)
3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except ValueError as msg:
3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if msg.args[0] != 0:
3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                s = str(msg)
3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if TESTFN in s or bad_mode not in s:
3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.fail("bad error message for invalid mode: %s" % s)
3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # if msg.args[0] == 0, we're probably on Windows where there may be
3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # no obvious way to discover why open() failed.
3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.close()
3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fail("no error for invalid mode: %s" % bad_mode)
3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testTruncate(self):
3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = _FileIO(TESTFN, 'w')
3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.write(bytes(bytearray(range(10))))
3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(f.tell(), 10)
3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.truncate(5)
3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(f.tell(), 10)
3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(f.seek(0, os.SEEK_END), 5)
3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.truncate(15)
3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(f.tell(), 5)
3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(f.seek(0, os.SEEK_END), 15)
3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f.close()
3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testTruncateOnWindows(self):
3800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def bug801631():
3810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # SF bug <http://www.python.org/sf/801631>
3820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # "file.truncate fault on windows"
3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f = _FileIO(TESTFN, 'w')
3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.write(bytes(range(11)))
3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.close()
3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f = _FileIO(TESTFN,'r+')
3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            data = f.read(5)
3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if data != bytes(range(5)):
3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fail("Read on file opened for update failed %r" % data)
3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if f.tell() != 5:
3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fail("File pos after read wrong %d" % f.tell())
3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.truncate()
3950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if f.tell() != 5:
3960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fail("File pos after ftruncate wrong %d" % f.tell())
3970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.close()
3990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            size = os.path.getsize(TESTFN)
4000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if size != 5:
4010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.fail("File size after ftruncate wrong %d" % size)
4020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
4040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            bug801631()
4050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
4060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            os.unlink(TESTFN)
4070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testAppend(self):
4090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
4100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f = open(TESTFN, 'wb')
4110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.write(b'spam')
4120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.close()
4130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f = open(TESTFN, 'ab')
4140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.write(b'eggs')
4150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.close()
4160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f = open(TESTFN, 'rb')
4170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d = f.read()
4180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f.close()
4190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(d, b'spameggs')
4200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
4210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
4220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                os.unlink(TESTFN)
4230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except:
4240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass
4250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testInvalidInit(self):
4270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(TypeError, _FileIO, "1", 0, 0)
4280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testWarnings(self):
4300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        with check_warnings(quiet=True) as w:
4310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(w.warnings, [])
4320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(TypeError, _FileIO, [])
4330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(w.warnings, [])
4340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(ValueError, _FileIO, "/some/invalid/name", "rt")
4350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(w.warnings, [])
4360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_surrogates(self):
4380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Issue #8438: try to open a filename containing surrogates.
4390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # It should either fail because the file doesn't exist or the filename
4400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # can't be represented using the filesystem encoding, but not because
4410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # of a LookupError for the error handler "surrogateescape".
4420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        filename = u'\udc80.txt'
4430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
4440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            with _FileIO(filename):
4450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass
4460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except (UnicodeEncodeError, IOError):
4470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
4480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Spawn a separate Python process with a different "file system
4490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # default encoding", to exercise this further.
4500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        env = dict(os.environ)
4510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        env[b'LC_CTYPE'] = b'C'
4520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _, out = run_python('-c', 'import _io; _io.FileIO(%r)' % filename, env=env)
4530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if ('UnicodeEncodeError' not in out and not
4540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ( ('IOError: [Errno 2] No such file or directory' in out) or
4550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                  ('IOError: [Errno 22] Invalid argument' in out) ) ):
4560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fail('Bad output: %r' % out)
4570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def testUnclosedFDOnException(self):
4590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class MyException(Exception): pass
4600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class MyFileIO(_FileIO):
4610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __setattr__(self, name, value):
4620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if name == "name":
4630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    raise MyException("blocked setting name")
4640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return super(MyFileIO, self).__setattr__(name, value)
4650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fd = os.open(__file__, os.O_RDONLY)
4660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(MyException, MyFileIO, fd)
4670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        os.close(fd)  # should not raise OSError(EBADF)
4680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4690a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef test_main():
4700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Historically, these tests have been sloppy about removing TESTFN.
4710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # So get rid of it no matter what.
4720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
4730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        run_unittest(AutoFileTests, OtherFileTests)
4740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    finally:
4750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if os.path.exists(TESTFN):
4760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            os.unlink(TESTFN)
4770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4780a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == '__main__':
4790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_main()
480