14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Adapted from test_file.py by Daniel Stutzbach
24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom __future__ import unicode_literals
44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport sys
64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport os
74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport errno
84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport unittest
94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom array import array
104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom weakref import proxy
114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom functools import wraps
124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom UserList import UserList
134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport _testcapi
144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom test.test_support import TESTFN, check_warnings, run_unittest, make_bad_fd
164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom test.test_support import py3k_bytes as bytes
174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom test.script_helper import run_python
184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom _io import FileIO as _FileIO
204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass AutoFileTests(unittest.TestCase):
224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # file tests for which a test file is automatically set up
234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def setUp(self):
254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f = _FileIO(TESTFN, 'w')
264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def tearDown(self):
284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.f:
294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.f.close()
304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        os.remove(TESTFN)
314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testWeakRefs(self):
334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # verify weak references
344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        p = proxy(self.f)
354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        p.write(bytes(range(10)))
364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(self.f.tell(), p.tell())
374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.close()
384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f = None
394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(ReferenceError, getattr, p, 'tell')
404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testSeekTell(self):
424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.write(bytes(range(20)))
434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(self.f.tell(), 20)
444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.seek(0)
454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(self.f.tell(), 0)
464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.seek(10)
474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(self.f.tell(), 10)
484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.seek(5, 1)
494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(self.f.tell(), 15)
504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.seek(-5, 1)
514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(self.f.tell(), 10)
524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.seek(-5, 2)
534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(self.f.tell(), 15)
544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testAttributes(self):
564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # verify expected attributes exist
574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f = self.f
584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(f.mode, "wb")
604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(f.closed, False)
614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # verify the attributes are readonly
634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for attr in 'mode', 'closed':
644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises((AttributeError, TypeError),
654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                              setattr, f, attr, 'oops')
664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testReadinto(self):
684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # verify readinto
694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.write(b"\x01\x02")
704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.close()
714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        a = array(b'b', b'x'*10)
724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f = _FileIO(TESTFN, 'r')
734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        n = self.f.readinto(a)
744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(array(b'b', [1, 2]), a[:n])
754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testWritelinesList(self):
774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        l = [b'123', b'456']
784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.writelines(l)
794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.close()
804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f = _FileIO(TESTFN, 'rb')
814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        buf = self.f.read()
824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(buf, b'123456')
834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testWritelinesUserList(self):
854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        l = UserList([b'123', b'456'])
864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.writelines(l)
874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.close()
884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f = _FileIO(TESTFN, 'rb')
894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        buf = self.f.read()
904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(buf, b'123456')
914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testWritelinesError(self):
934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(TypeError, self.f.writelines, [1, 2, 3])
944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(TypeError, self.f.writelines, None)
954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_none_args(self):
974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.write(b"hi\nbye\nabc")
984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.close()
994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f = _FileIO(TESTFN, 'r')
1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(self.f.read(None), b"hi\nbye\nabc")
1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.seek(0)
1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(self.f.readline(None), b"hi\n")
1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(self.f.readlines(None), [b"bye\n", b"abc"])
1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testRepr(self):
1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(repr(self.f), "<_io.FileIO name=%r mode='%s'>"
1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                       % (self.f.name, self.f.mode))
1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        del self.f.name
1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(repr(self.f), "<_io.FileIO fd=%r mode='%s'>"
1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                       % (self.f.fileno(), self.f.mode))
1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.close()
1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(repr(self.f), "<_io.FileIO [closed]>")
1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrors(self):
1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f = self.f
1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertTrue(not f.isatty())
1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertTrue(not f.closed)
1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        #self.assertEqual(f.name, TESTFN)
1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(ValueError, f.read, 10) # Open for reading
1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.close()
1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertTrue(f.closed)
1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f = _FileIO(TESTFN, 'r')
1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(TypeError, f.readinto, "")
1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertTrue(not f.closed)
1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.close()
1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertTrue(f.closed)
1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testMethods(self):
1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        methods = ['fileno', 'isatty', 'read', 'readinto',
1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                   'seek', 'tell', 'truncate', 'write', 'seekable',
1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                   'readable', 'writable']
1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if sys.platform.startswith('atheos'):
1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            methods.remove('truncate')
1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f.close()
1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertTrue(self.f.closed)
1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for methodname in methods:
1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            method = getattr(self.f, methodname)
1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # should raise on closed file
1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises(ValueError, method)
1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testOpendir(self):
1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Issue 3703: opening a directory should fill the errno
1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Windows always returns "[Errno 13]: Permission denied
1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Unix calls dircheck() and returns "[Errno 21]: Is a directory"
1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        try:
1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            _FileIO('.', 'r')
1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        except IOError as e:
1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertNotEqual(e.errno, 0)
1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(e.filename, ".")
1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.fail("Should have raised IOError")
1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @unittest.skipIf(os.name == 'nt', "test only works on a POSIX-like system")
1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testOpenDirFD(self):
1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        fd = os.open('.', os.O_RDONLY)
1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        with self.assertRaises(IOError) as cm:
1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            _FileIO(fd, 'r')
1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        os.close(fd)
1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(cm.exception.errno, errno.EISDIR)
1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #A set of functions testing that we get expected behaviour if someone has
1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #manually closed the internal file descriptor.  First, a decorator:
1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def ClosedFD(func):
1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        @wraps(func)
1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def wrapper(self):
1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            #forcibly close the fd before invoking the problem function
1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f = self.f
1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            os.close(f.fileno())
1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            try:
1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                func(self, f)
1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            finally:
1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                try:
1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    self.f.close()
1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                except IOError:
1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    pass
1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return wrapper
1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def ClosedFDRaises(func):
1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        @wraps(func)
1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def wrapper(self):
1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            #forcibly close the fd before invoking the problem function
1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f = self.f
1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            os.close(f.fileno())
1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            try:
1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                func(self, f)
1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            except IOError as e:
1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.assertEqual(e.errno, errno.EBADF)
1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.fail("Should have raised IOError")
1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            finally:
1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                try:
1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    self.f.close()
1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                except IOError:
1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    pass
1974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return wrapper
1984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFDRaises
2004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClose(self, f):
2014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.close()
2024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFDRaises
2044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClosedWrite(self, f):
2054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.write('a')
2064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFDRaises
2084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClosedSeek(self, f):
2094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.seek(0)
2104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFDRaises
2124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClosedTell(self, f):
2134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.tell()
2144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFDRaises
2164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClosedTruncate(self, f):
2174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.truncate(0)
2184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFD
2204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClosedSeekable(self, f):
2214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.seekable()
2224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFD
2244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClosedReadable(self, f):
2254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.readable()
2264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFD
2284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClosedWritable(self, f):
2294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.writable()
2304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFD
2324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClosedFileno(self, f):
2334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.fileno()
2344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFD
2364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClosedIsatty(self, f):
2374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(f.isatty(), False)
2384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def ReopenForRead(self):
2404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        try:
2414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.f.close()
2424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        except IOError:
2434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            pass
2444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.f = _FileIO(TESTFN, 'r')
2454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        os.close(self.f.fileno())
2464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return self.f
2474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFDRaises
2494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClosedRead(self, f):
2504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f = self.ReopenForRead()
2514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.read(1)
2524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFDRaises
2544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClosedReadall(self, f):
2554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f = self.ReopenForRead()
2564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.readall()
2574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    @ClosedFDRaises
2594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testErrnoOnClosedReadinto(self, f):
2604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f = self.ReopenForRead()
2614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        a = array(b'b', b'x'*10)
2624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.readinto(a)
2634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass OtherFileTests(unittest.TestCase):
2654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testAbles(self):
2674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        try:
2684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f = _FileIO(TESTFN, "w")
2694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(f.readable(), False)
2704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(f.writable(), True)
2714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(f.seekable(), True)
2724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.close()
2734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f = _FileIO(TESTFN, "r")
2754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(f.readable(), True)
2764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(f.writable(), False)
2774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(f.seekable(), True)
2784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.close()
2794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f = _FileIO(TESTFN, "a+")
2814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(f.readable(), True)
2824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(f.writable(), True)
2834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(f.seekable(), True)
2844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(f.isatty(), False)
2854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.close()
2864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if sys.platform != "win32":
2884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                try:
2894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    f = _FileIO("/dev/tty", "a")
2904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                except EnvironmentError:
2914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    # When run in a cron job there just aren't any
2924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    # ttys, so skip the test.  This also handles other
2934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    # OS'es that don't support /dev/tty.
2944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    pass
2954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                else:
2964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    self.assertEqual(f.readable(), False)
2974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    self.assertEqual(f.writable(), True)
2984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    if sys.platform != "darwin" and \
2994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                       'bsd' not in sys.platform and \
3004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                       not sys.platform.startswith('sunos'):
3014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        # Somehow /dev/tty appears seekable on some BSDs
3024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        self.assertEqual(f.seekable(), False)
3034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    self.assertEqual(f.isatty(), True)
3044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    f.close()
3054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        finally:
3064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            os.unlink(TESTFN)
3074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testModeStrings(self):
3094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # check invalid mode strings
3104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for mode in ("", "aU", "wU+", "rw", "rt"):
3114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            try:
3124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                f = _FileIO(TESTFN, mode)
3134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            except ValueError:
3144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                pass
3154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
3164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                f.close()
3174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.fail('%r is an invalid file mode' % mode)
3184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testUnicodeOpen(self):
3204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # verify repr works for unicode too
3214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f = _FileIO(str(TESTFN), "w")
3224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.close()
3234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        os.unlink(TESTFN)
3244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testBytesOpen(self):
3264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Opening a bytes filename
3274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        try:
3284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            fn = TESTFN.encode("ascii")
3294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        except UnicodeEncodeError:
3304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Skip test
3314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return
3324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f = _FileIO(fn, "w")
3334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        try:
3344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.write(b"abc")
3354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.close()
3364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            with open(TESTFN, "rb") as f:
3374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.assertEqual(f.read(), b"abc")
3384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        finally:
3394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            os.unlink(TESTFN)
3404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testInvalidFd(self):
3424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(ValueError, _FileIO, -10)
3434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(OSError, _FileIO, make_bad_fd())
3444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if sys.platform == 'win32':
3454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            import msvcrt
3464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises(IOError, msvcrt.get_osfhandle, make_bad_fd())
3474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Issue 15989
3484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(TypeError, _FileIO, _testcapi.INT_MAX + 1)
3494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(TypeError, _FileIO, _testcapi.INT_MIN - 1)
3504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testBadModeArgument(self):
3524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # verify that we get a sensible error message for bad mode argument
3534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        bad_mode = "qwerty"
3544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        try:
3554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f = _FileIO(TESTFN, bad_mode)
3564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        except ValueError as msg:
3574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if msg.args[0] != 0:
3584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                s = str(msg)
3594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                if TESTFN in s or bad_mode not in s:
3604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    self.fail("bad error message for invalid mode: %s" % s)
3614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # if msg.args[0] == 0, we're probably on Windows where there may be
3624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # no obvious way to discover why open() failed.
3634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
3644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.close()
3654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.fail("no error for invalid mode: %s" % bad_mode)
3664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testTruncate(self):
3684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f = _FileIO(TESTFN, 'w')
3694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.write(bytes(bytearray(range(10))))
3704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(f.tell(), 10)
3714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.truncate(5)
3724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(f.tell(), 10)
3734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(f.seek(0, os.SEEK_END), 5)
3744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.truncate(15)
3754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(f.tell(), 5)
3764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertEqual(f.seek(0, os.SEEK_END), 15)
3774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        f.close()
3784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testTruncateOnWindows(self):
3804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def bug801631():
3814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # SF bug <http://www.python.org/sf/801631>
3824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # "file.truncate fault on windows"
3834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f = _FileIO(TESTFN, 'w')
3844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.write(bytes(range(11)))
3854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.close()
3864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f = _FileIO(TESTFN,'r+')
3884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            data = f.read(5)
3894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if data != bytes(range(5)):
3904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.fail("Read on file opened for update failed %r" % data)
3914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if f.tell() != 5:
3924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.fail("File pos after read wrong %d" % f.tell())
3934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.truncate()
3954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if f.tell() != 5:
3964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.fail("File pos after ftruncate wrong %d" % f.tell())
3974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.close()
3994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            size = os.path.getsize(TESTFN)
4004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if size != 5:
4014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.fail("File size after ftruncate wrong %d" % size)
4024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        try:
4044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            bug801631()
4054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        finally:
4064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            os.unlink(TESTFN)
4074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testAppend(self):
4094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        try:
4104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f = open(TESTFN, 'wb')
4114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.write(b'spam')
4124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.close()
4134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f = open(TESTFN, 'ab')
4144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.write(b'eggs')
4154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.close()
4164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f = open(TESTFN, 'rb')
4174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            d = f.read()
4184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            f.close()
4194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(d, b'spameggs')
4204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        finally:
4214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            try:
4224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                os.unlink(TESTFN)
4234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            except:
4244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                pass
4254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testInvalidInit(self):
4274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(TypeError, _FileIO, "1", 0, 0)
4284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testWarnings(self):
4304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        with check_warnings(quiet=True) as w:
4314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(w.warnings, [])
4324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises(TypeError, _FileIO, [])
4334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(w.warnings, [])
4344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertRaises(ValueError, _FileIO, "/some/invalid/name", "rt")
4354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.assertEqual(w.warnings, [])
4364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def test_surrogates(self):
4384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Issue #8438: try to open a filename containing surrogates.
4394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # It should either fail because the file doesn't exist or the filename
4404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # can't be represented using the filesystem encoding, but not because
4414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # of a LookupError for the error handler "surrogateescape".
4424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        filename = u'\udc80.txt'
4434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        try:
4444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            with _FileIO(filename):
4454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                pass
4464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        except (UnicodeEncodeError, IOError):
4474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            pass
4484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Spawn a separate Python process with a different "file system
4494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # default encoding", to exercise this further.
4504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        env = dict(os.environ)
4514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        env[b'LC_CTYPE'] = b'C'
4524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        _, out = run_python('-c', 'import _io; _io.FileIO(%r)' % filename, env=env)
4534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if ('UnicodeEncodeError' not in out and not
4544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                ( ('IOError: [Errno 2] No such file or directory' in out) or
4554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                  ('IOError: [Errno 22] Invalid argument' in out) ) ):
4564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.fail('Bad output: %r' % out)
4574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def testUnclosedFDOnException(self):
4594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        class MyException(Exception): pass
4604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        class MyFileIO(_FileIO):
4614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            def __setattr__(self, name, value):
4624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                if name == "name":
4634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    raise MyException("blocked setting name")
4644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                return super(MyFileIO, self).__setattr__(name, value)
4654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        fd = os.open(__file__, os.O_RDONLY)
4664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.assertRaises(MyException, MyFileIO, fd)
4674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        os.close(fd)  # should not raise OSError(EBADF)
4684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef test_main():
4704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # Historically, these tests have been sloppy about removing TESTFN.
4714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # So get rid of it no matter what.
4724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    try:
4734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        run_unittest(AutoFileTests, OtherFileTests)
4744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    finally:
4754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if os.path.exists(TESTFN):
4764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            os.unlink(TESTFN)
4774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif __name__ == '__main__':
4794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    test_main()
480