1ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh# Adapted from test_file.py by Daniel Stutzbach 2ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 3ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfrom __future__ import unicode_literals 4ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 5ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport sys 6ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport os 7ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport errno 8ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport unittest 9ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfrom array import array 10ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfrom weakref import proxy 11ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfrom functools import wraps 12ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfrom UserList import UserList 13ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehimport _testcapi 14ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 15ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfrom test.test_support import TESTFN, check_warnings, run_unittest, make_bad_fd 16ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfrom test.test_support import py3k_bytes as bytes 17ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfrom test.script_helper import run_python 18ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 19ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehfrom _io import FileIO as _FileIO 20ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 21ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehclass AutoFileTests(unittest.TestCase): 22ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # file tests for which a test file is automatically set up 23ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 24ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def setUp(self): 25ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f = _FileIO(TESTFN, 'w') 26ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 27ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def tearDown(self): 28ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if self.f: 29ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.close() 30ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh os.remove(TESTFN) 31ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 32ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testWeakRefs(self): 33ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # verify weak references 34ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh p = proxy(self.f) 35ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh p.write(bytes(range(10))) 36ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(self.f.tell(), p.tell()) 37ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.close() 38ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f = None 39ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(ReferenceError, getattr, p, 'tell') 40ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 41ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testSeekTell(self): 42ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.write(bytes(range(20))) 43ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(self.f.tell(), 20) 44ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.seek(0) 45ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(self.f.tell(), 0) 46ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.seek(10) 47ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(self.f.tell(), 10) 48ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.seek(5, 1) 49ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(self.f.tell(), 15) 50ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.seek(-5, 1) 51ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(self.f.tell(), 10) 52ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.seek(-5, 2) 53ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(self.f.tell(), 15) 54ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 55ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testAttributes(self): 56ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # verify expected attributes exist 57ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = self.f 58ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 59ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.mode, "wb") 60ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.closed, False) 61ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 62ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # verify the attributes are readonly 63ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for attr in 'mode', 'closed': 64ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises((AttributeError, TypeError), 65ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh setattr, f, attr, 'oops') 66ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 67ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testReadinto(self): 68ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # verify readinto 69ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.write(b"\x01\x02") 70ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.close() 71ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh a = array(b'b', b'x'*10) 72ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f = _FileIO(TESTFN, 'r') 73ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh n = self.f.readinto(a) 74ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(array(b'b', [1, 2]), a[:n]) 75ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 76ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testWritelinesList(self): 77ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh l = [b'123', b'456'] 78ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.writelines(l) 79ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.close() 80ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f = _FileIO(TESTFN, 'rb') 81ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh buf = self.f.read() 82ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(buf, b'123456') 83ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 84ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testWritelinesUserList(self): 85ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh l = UserList([b'123', b'456']) 86ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.writelines(l) 87ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.close() 88ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f = _FileIO(TESTFN, 'rb') 89ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh buf = self.f.read() 90ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(buf, b'123456') 91ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 92ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testWritelinesError(self): 93ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(TypeError, self.f.writelines, [1, 2, 3]) 94ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(TypeError, self.f.writelines, None) 95ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 96ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def test_none_args(self): 97ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.write(b"hi\nbye\nabc") 98ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.close() 99ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f = _FileIO(TESTFN, 'r') 100ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(self.f.read(None), b"hi\nbye\nabc") 101ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.seek(0) 102ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(self.f.readline(None), b"hi\n") 103ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(self.f.readlines(None), [b"bye\n", b"abc"]) 104ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 105ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testRepr(self): 106ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(repr(self.f), "<_io.FileIO name=%r mode='%s'>" 107ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh % (self.f.name, self.f.mode)) 108ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh del self.f.name 109ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(repr(self.f), "<_io.FileIO fd=%r mode='%s'>" 110ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh % (self.f.fileno(), self.f.mode)) 111ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.close() 112ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(repr(self.f), "<_io.FileIO [closed]>") 113ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 114ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrors(self): 115ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = self.f 116ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertTrue(not f.isatty()) 117ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertTrue(not f.closed) 118ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh #self.assertEqual(f.name, TESTFN) 119ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(ValueError, f.read, 10) # Open for reading 120ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 121ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertTrue(f.closed) 122ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = _FileIO(TESTFN, 'r') 123ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(TypeError, f.readinto, "") 124ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertTrue(not f.closed) 125ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 126ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertTrue(f.closed) 127ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 128ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testMethods(self): 129ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh methods = ['fileno', 'isatty', 'read', 'readinto', 130ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 'seek', 'tell', 'truncate', 'write', 'seekable', 131ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 'readable', 'writable'] 132ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if sys.platform.startswith('atheos'): 133ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh methods.remove('truncate') 134ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 135ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.close() 136ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertTrue(self.f.closed) 137ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 138ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for methodname in methods: 139ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh method = getattr(self.f, methodname) 140ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # should raise on closed file 141ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(ValueError, method) 142ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 143ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testOpendir(self): 144ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Issue 3703: opening a directory should fill the errno 145ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Windows always returns "[Errno 13]: Permission denied 146ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Unix calls dircheck() and returns "[Errno 21]: Is a directory" 147ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 148ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _FileIO('.', 'r') 149ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except IOError as e: 150ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertNotEqual(e.errno, 0) 151ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(e.filename, ".") 152ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 153ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.fail("Should have raised IOError") 154ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 155ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @unittest.skipIf(os.name == 'nt', "test only works on a POSIX-like system") 156ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testOpenDirFD(self): 157ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh fd = os.open('.', os.O_RDONLY) 158ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh with self.assertRaises(IOError) as cm: 159ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _FileIO(fd, 'r') 160ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh os.close(fd) 161ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(cm.exception.errno, errno.EISDIR) 162ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 163ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh #A set of functions testing that we get expected behaviour if someone has 164ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh #manually closed the internal file descriptor. First, a decorator: 165ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def ClosedFD(func): 166ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @wraps(func) 167ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def wrapper(self): 168ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh #forcibly close the fd before invoking the problem function 169ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = self.f 170ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh os.close(f.fileno()) 171ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 172ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh func(self, f) 173ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh finally: 174ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 175ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.close() 176ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except IOError: 177ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pass 178ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return wrapper 179ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 180ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def ClosedFDRaises(func): 181ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @wraps(func) 182ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def wrapper(self): 183ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh #forcibly close the fd before invoking the problem function 184ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = self.f 185ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh os.close(f.fileno()) 186ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 187ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh func(self, f) 188ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except IOError as e: 189ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(e.errno, errno.EBADF) 190ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 191ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.fail("Should have raised IOError") 192ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh finally: 193ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 194ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.close() 195ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except IOError: 196ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pass 197ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return wrapper 198ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 199ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFDRaises 200ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClose(self, f): 201ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 202ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 203ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFDRaises 204ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClosedWrite(self, f): 205ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.write('a') 206ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 207ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFDRaises 208ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClosedSeek(self, f): 209ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.seek(0) 210ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 211ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFDRaises 212ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClosedTell(self, f): 213ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.tell() 214ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 215ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFDRaises 216ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClosedTruncate(self, f): 217ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.truncate(0) 218ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 219ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFD 220ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClosedSeekable(self, f): 221ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.seekable() 222ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 223ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFD 224ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClosedReadable(self, f): 225ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.readable() 226ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 227ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFD 228ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClosedWritable(self, f): 229ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.writable() 230ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 231ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFD 232ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClosedFileno(self, f): 233ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.fileno() 234ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 235ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFD 236ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClosedIsatty(self, f): 237ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.isatty(), False) 238ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 239ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def ReopenForRead(self): 240ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 241ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f.close() 242ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except IOError: 243ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pass 244ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.f = _FileIO(TESTFN, 'r') 245ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh os.close(self.f.fileno()) 246ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return self.f 247ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 248ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFDRaises 249ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClosedRead(self, f): 250ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = self.ReopenForRead() 251ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.read(1) 252ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 253ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFDRaises 254ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClosedReadall(self, f): 255ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = self.ReopenForRead() 256ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.readall() 257ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 258ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh @ClosedFDRaises 259ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testErrnoOnClosedReadinto(self, f): 260ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = self.ReopenForRead() 261ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh a = array(b'b', b'x'*10) 262ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.readinto(a) 263ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 264ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehclass OtherFileTests(unittest.TestCase): 265ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 266ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testAbles(self): 267ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 268ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = _FileIO(TESTFN, "w") 269ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.readable(), False) 270ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.writable(), True) 271ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.seekable(), True) 272ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 273ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 274ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = _FileIO(TESTFN, "r") 275ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.readable(), True) 276ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.writable(), False) 277ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.seekable(), True) 278ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 279ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 280ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = _FileIO(TESTFN, "a+") 281ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.readable(), True) 282ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.writable(), True) 283ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.seekable(), True) 284ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.isatty(), False) 285ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 286ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 287ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if sys.platform != "win32": 288ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 289ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = _FileIO("/dev/tty", "a") 290ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except EnvironmentError: 291ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # When run in a cron job there just aren't any 292ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # ttys, so skip the test. This also handles other 293ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # OS'es that don't support /dev/tty. 294ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pass 295ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 296ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.readable(), False) 297ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.writable(), True) 298ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if sys.platform != "darwin" and \ 299ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 'bsd' not in sys.platform and \ 300ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh not sys.platform.startswith('sunos'): 301ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Somehow /dev/tty appears seekable on some BSDs 302ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.seekable(), False) 303ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.isatty(), True) 304ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 305ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh finally: 306ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh os.unlink(TESTFN) 307ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 308ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testModeStrings(self): 309ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # check invalid mode strings 310ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh for mode in ("", "aU", "wU+", "rw", "rt"): 311ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 312ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = _FileIO(TESTFN, mode) 313ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except ValueError: 314ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pass 315ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 316ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 317ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.fail('%r is an invalid file mode' % mode) 318ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 319ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testUnicodeOpen(self): 320ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # verify repr works for unicode too 321ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = _FileIO(str(TESTFN), "w") 322ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 323ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh os.unlink(TESTFN) 324ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 325ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testBytesOpen(self): 326ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Opening a bytes filename 327ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 328ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh fn = TESTFN.encode("ascii") 329ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except UnicodeEncodeError: 330ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Skip test 331ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return 332ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = _FileIO(fn, "w") 333ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 334ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.write(b"abc") 335ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 336ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh with open(TESTFN, "rb") as f: 337ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.read(), b"abc") 338ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh finally: 339ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh os.unlink(TESTFN) 340ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 341ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testInvalidFd(self): 342ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(ValueError, _FileIO, -10) 343ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(OSError, _FileIO, make_bad_fd()) 344ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if sys.platform == 'win32': 345ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh import msvcrt 346ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(IOError, msvcrt.get_osfhandle, make_bad_fd()) 347ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Issue 15989 348ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(TypeError, _FileIO, _testcapi.INT_MAX + 1) 349ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(TypeError, _FileIO, _testcapi.INT_MIN - 1) 350ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 351ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testBadModeArgument(self): 352ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # verify that we get a sensible error message for bad mode argument 353ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh bad_mode = "qwerty" 354ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 355ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = _FileIO(TESTFN, bad_mode) 356ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except ValueError as msg: 357ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if msg.args[0] != 0: 358ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh s = str(msg) 359ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if TESTFN in s or bad_mode not in s: 360ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.fail("bad error message for invalid mode: %s" % s) 361ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # if msg.args[0] == 0, we're probably on Windows where there may be 362ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # no obvious way to discover why open() failed. 363ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh else: 364ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 365ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.fail("no error for invalid mode: %s" % bad_mode) 366ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 367ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testTruncate(self): 368ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = _FileIO(TESTFN, 'w') 369ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.write(bytes(bytearray(range(10)))) 370ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.tell(), 10) 371ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.truncate(5) 372ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.tell(), 10) 373ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.seek(0, os.SEEK_END), 5) 374ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.truncate(15) 375ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.tell(), 5) 376ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(f.seek(0, os.SEEK_END), 15) 377ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 378ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 379ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testTruncateOnWindows(self): 380ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def bug801631(): 381ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # SF bug <http://www.python.org/sf/801631> 382ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # "file.truncate fault on windows" 383ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = _FileIO(TESTFN, 'w') 384ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.write(bytes(range(11))) 385ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 386ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 387ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = _FileIO(TESTFN,'r+') 388ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh data = f.read(5) 389ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if data != bytes(range(5)): 390ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.fail("Read on file opened for update failed %r" % data) 391ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if f.tell() != 5: 392ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.fail("File pos after read wrong %d" % f.tell()) 393ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 394ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.truncate() 395ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if f.tell() != 5: 396ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.fail("File pos after ftruncate wrong %d" % f.tell()) 397ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 398ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 399ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh size = os.path.getsize(TESTFN) 400ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if size != 5: 401ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.fail("File size after ftruncate wrong %d" % size) 402ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 403ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 404ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh bug801631() 405ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh finally: 406ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh os.unlink(TESTFN) 407ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 408ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testAppend(self): 409ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 410ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = open(TESTFN, 'wb') 411ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.write(b'spam') 412ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 413ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = open(TESTFN, 'ab') 414ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.write(b'eggs') 415ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 416ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f = open(TESTFN, 'rb') 417ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh d = f.read() 418ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh f.close() 419ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(d, b'spameggs') 420ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh finally: 421ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 422ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh os.unlink(TESTFN) 423ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except: 424ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pass 425ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 426ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testInvalidInit(self): 427ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(TypeError, _FileIO, "1", 0, 0) 428ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 429ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testWarnings(self): 430ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh with check_warnings(quiet=True) as w: 431ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(w.warnings, []) 432ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(TypeError, _FileIO, []) 433ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(w.warnings, []) 434ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(ValueError, _FileIO, "/some/invalid/name", "rt") 435ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertEqual(w.warnings, []) 436ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 437ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def test_surrogates(self): 438ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Issue #8438: try to open a filename containing surrogates. 439ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # It should either fail because the file doesn't exist or the filename 440ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # can't be represented using the filesystem encoding, but not because 441ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # of a LookupError for the error handler "surrogateescape". 442ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh filename = u'\udc80.txt' 443ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 444ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh with _FileIO(filename): 445ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pass 446ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh except (UnicodeEncodeError, IOError): 447ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh pass 448ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Spawn a separate Python process with a different "file system 449ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # default encoding", to exercise this further. 450ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh env = dict(os.environ) 451ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh env[b'LC_CTYPE'] = b'C' 452ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh _, out = run_python('-c', 'import _io; _io.FileIO(%r)' % filename, env=env) 453ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if ('UnicodeEncodeError' not in out and not 454ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh ( ('IOError: [Errno 2] No such file or directory' in out) or 455ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh ('IOError: [Errno 22] Invalid argument' in out) ) ): 456ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.fail('Bad output: %r' % out) 457ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 458ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def testUnclosedFDOnException(self): 459ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh class MyException(Exception): pass 460ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh class MyFileIO(_FileIO): 461ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh def __setattr__(self, name, value): 462ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if name == "name": 463ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh raise MyException("blocked setting name") 464ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh return super(MyFileIO, self).__setattr__(name, value) 465ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh fd = os.open(__file__, os.O_RDONLY) 466ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh self.assertRaises(MyException, MyFileIO, fd) 467ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh os.close(fd) # should not raise OSError(EBADF) 468ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 469ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehdef test_main(): 470ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # Historically, these tests have been sloppy about removing TESTFN. 471ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh # So get rid of it no matter what. 472ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh try: 473ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh run_unittest(AutoFileTests, OtherFileTests) 474ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh finally: 475ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh if os.path.exists(TESTFN): 476ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh os.unlink(TESTFN) 477ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh 478ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsiehif __name__ == '__main__': 479ffab958fd8d42ed7227d83007350e61555a1fa36Andrew Hsieh test_main() 480