17db96d56Sopenharmony_ci# Adapted from test_file.py by Daniel Stutzbach 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ciimport sys 47db96d56Sopenharmony_ciimport os 57db96d56Sopenharmony_ciimport io 67db96d56Sopenharmony_ciimport errno 77db96d56Sopenharmony_ciimport unittest 87db96d56Sopenharmony_cifrom array import array 97db96d56Sopenharmony_cifrom weakref import proxy 107db96d56Sopenharmony_cifrom functools import wraps 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_cifrom test.support import ( 137db96d56Sopenharmony_ci cpython_only, swap_attr, gc_collect, is_emscripten, is_wasi 147db96d56Sopenharmony_ci) 157db96d56Sopenharmony_cifrom test.support.os_helper import ( 167db96d56Sopenharmony_ci TESTFN, TESTFN_ASCII, TESTFN_UNICODE, make_bad_fd, 177db96d56Sopenharmony_ci ) 187db96d56Sopenharmony_cifrom test.support.warnings_helper import check_warnings 197db96d56Sopenharmony_cifrom collections import UserList 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ciimport _io # C implementation of io 227db96d56Sopenharmony_ciimport _pyio # Python implementation of io 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ciclass AutoFileTests: 267db96d56Sopenharmony_ci # file tests for which a test file is automatically set up 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ci def setUp(self): 297db96d56Sopenharmony_ci self.f = self.FileIO(TESTFN, 'w') 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ci def tearDown(self): 327db96d56Sopenharmony_ci if self.f: 337db96d56Sopenharmony_ci self.f.close() 347db96d56Sopenharmony_ci os.remove(TESTFN) 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ci def testWeakRefs(self): 377db96d56Sopenharmony_ci # verify weak references 387db96d56Sopenharmony_ci p = proxy(self.f) 397db96d56Sopenharmony_ci p.write(bytes(range(10))) 407db96d56Sopenharmony_ci self.assertEqual(self.f.tell(), p.tell()) 417db96d56Sopenharmony_ci self.f.close() 427db96d56Sopenharmony_ci self.f = None 437db96d56Sopenharmony_ci gc_collect() # For PyPy or other GCs. 447db96d56Sopenharmony_ci self.assertRaises(ReferenceError, getattr, p, 'tell') 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci def testSeekTell(self): 477db96d56Sopenharmony_ci self.f.write(bytes(range(20))) 487db96d56Sopenharmony_ci self.assertEqual(self.f.tell(), 20) 497db96d56Sopenharmony_ci self.f.seek(0) 507db96d56Sopenharmony_ci self.assertEqual(self.f.tell(), 0) 517db96d56Sopenharmony_ci self.f.seek(10) 527db96d56Sopenharmony_ci self.assertEqual(self.f.tell(), 10) 537db96d56Sopenharmony_ci self.f.seek(5, 1) 547db96d56Sopenharmony_ci self.assertEqual(self.f.tell(), 15) 557db96d56Sopenharmony_ci self.f.seek(-5, 1) 567db96d56Sopenharmony_ci self.assertEqual(self.f.tell(), 10) 577db96d56Sopenharmony_ci self.f.seek(-5, 2) 587db96d56Sopenharmony_ci self.assertEqual(self.f.tell(), 15) 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci def testAttributes(self): 617db96d56Sopenharmony_ci # verify expected attributes exist 627db96d56Sopenharmony_ci f = self.f 637db96d56Sopenharmony_ci 647db96d56Sopenharmony_ci self.assertEqual(f.mode, "wb") 657db96d56Sopenharmony_ci self.assertEqual(f.closed, False) 667db96d56Sopenharmony_ci 677db96d56Sopenharmony_ci # verify the attributes are readonly 687db96d56Sopenharmony_ci for attr in 'mode', 'closed': 697db96d56Sopenharmony_ci self.assertRaises((AttributeError, TypeError), 707db96d56Sopenharmony_ci setattr, f, attr, 'oops') 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci @unittest.skipIf(is_wasi, "WASI does not expose st_blksize.") 737db96d56Sopenharmony_ci def testBlksize(self): 747db96d56Sopenharmony_ci # test private _blksize attribute 757db96d56Sopenharmony_ci blksize = io.DEFAULT_BUFFER_SIZE 767db96d56Sopenharmony_ci # try to get preferred blksize from stat.st_blksize, if available 777db96d56Sopenharmony_ci if hasattr(os, 'fstat'): 787db96d56Sopenharmony_ci fst = os.fstat(self.f.fileno()) 797db96d56Sopenharmony_ci blksize = getattr(fst, 'st_blksize', blksize) 807db96d56Sopenharmony_ci self.assertEqual(self.f._blksize, blksize) 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci # verify readinto 837db96d56Sopenharmony_ci def testReadintoByteArray(self): 847db96d56Sopenharmony_ci self.f.write(bytes([1, 2, 0, 255])) 857db96d56Sopenharmony_ci self.f.close() 867db96d56Sopenharmony_ci 877db96d56Sopenharmony_ci ba = bytearray(b'abcdefgh') 887db96d56Sopenharmony_ci with self.FileIO(TESTFN, 'r') as f: 897db96d56Sopenharmony_ci n = f.readinto(ba) 907db96d56Sopenharmony_ci self.assertEqual(ba, b'\x01\x02\x00\xffefgh') 917db96d56Sopenharmony_ci self.assertEqual(n, 4) 927db96d56Sopenharmony_ci 937db96d56Sopenharmony_ci def _testReadintoMemoryview(self): 947db96d56Sopenharmony_ci self.f.write(bytes([1, 2, 0, 255])) 957db96d56Sopenharmony_ci self.f.close() 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci m = memoryview(bytearray(b'abcdefgh')) 987db96d56Sopenharmony_ci with self.FileIO(TESTFN, 'r') as f: 997db96d56Sopenharmony_ci n = f.readinto(m) 1007db96d56Sopenharmony_ci self.assertEqual(m, b'\x01\x02\x00\xffefgh') 1017db96d56Sopenharmony_ci self.assertEqual(n, 4) 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci m = memoryview(bytearray(b'abcdefgh')).cast('H', shape=[2, 2]) 1047db96d56Sopenharmony_ci with self.FileIO(TESTFN, 'r') as f: 1057db96d56Sopenharmony_ci n = f.readinto(m) 1067db96d56Sopenharmony_ci self.assertEqual(bytes(m), b'\x01\x02\x00\xffefgh') 1077db96d56Sopenharmony_ci self.assertEqual(n, 4) 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ci def _testReadintoArray(self): 1107db96d56Sopenharmony_ci self.f.write(bytes([1, 2, 0, 255])) 1117db96d56Sopenharmony_ci self.f.close() 1127db96d56Sopenharmony_ci 1137db96d56Sopenharmony_ci a = array('B', b'abcdefgh') 1147db96d56Sopenharmony_ci with self.FileIO(TESTFN, 'r') as f: 1157db96d56Sopenharmony_ci n = f.readinto(a) 1167db96d56Sopenharmony_ci self.assertEqual(a, array('B', [1, 2, 0, 255, 101, 102, 103, 104])) 1177db96d56Sopenharmony_ci self.assertEqual(n, 4) 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci a = array('b', b'abcdefgh') 1207db96d56Sopenharmony_ci with self.FileIO(TESTFN, 'r') as f: 1217db96d56Sopenharmony_ci n = f.readinto(a) 1227db96d56Sopenharmony_ci self.assertEqual(a, array('b', [1, 2, 0, -1, 101, 102, 103, 104])) 1237db96d56Sopenharmony_ci self.assertEqual(n, 4) 1247db96d56Sopenharmony_ci 1257db96d56Sopenharmony_ci a = array('I', b'abcdefgh') 1267db96d56Sopenharmony_ci with self.FileIO(TESTFN, 'r') as f: 1277db96d56Sopenharmony_ci n = f.readinto(a) 1287db96d56Sopenharmony_ci self.assertEqual(a, array('I', b'\x01\x02\x00\xffefgh')) 1297db96d56Sopenharmony_ci self.assertEqual(n, 4) 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_ci def testWritelinesList(self): 1327db96d56Sopenharmony_ci l = [b'123', b'456'] 1337db96d56Sopenharmony_ci self.f.writelines(l) 1347db96d56Sopenharmony_ci self.f.close() 1357db96d56Sopenharmony_ci self.f = self.FileIO(TESTFN, 'rb') 1367db96d56Sopenharmony_ci buf = self.f.read() 1377db96d56Sopenharmony_ci self.assertEqual(buf, b'123456') 1387db96d56Sopenharmony_ci 1397db96d56Sopenharmony_ci def testWritelinesUserList(self): 1407db96d56Sopenharmony_ci l = UserList([b'123', b'456']) 1417db96d56Sopenharmony_ci self.f.writelines(l) 1427db96d56Sopenharmony_ci self.f.close() 1437db96d56Sopenharmony_ci self.f = self.FileIO(TESTFN, 'rb') 1447db96d56Sopenharmony_ci buf = self.f.read() 1457db96d56Sopenharmony_ci self.assertEqual(buf, b'123456') 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_ci def testWritelinesError(self): 1487db96d56Sopenharmony_ci self.assertRaises(TypeError, self.f.writelines, [1, 2, 3]) 1497db96d56Sopenharmony_ci self.assertRaises(TypeError, self.f.writelines, None) 1507db96d56Sopenharmony_ci self.assertRaises(TypeError, self.f.writelines, "abc") 1517db96d56Sopenharmony_ci 1527db96d56Sopenharmony_ci def test_none_args(self): 1537db96d56Sopenharmony_ci self.f.write(b"hi\nbye\nabc") 1547db96d56Sopenharmony_ci self.f.close() 1557db96d56Sopenharmony_ci self.f = self.FileIO(TESTFN, 'r') 1567db96d56Sopenharmony_ci self.assertEqual(self.f.read(None), b"hi\nbye\nabc") 1577db96d56Sopenharmony_ci self.f.seek(0) 1587db96d56Sopenharmony_ci self.assertEqual(self.f.readline(None), b"hi\n") 1597db96d56Sopenharmony_ci self.assertEqual(self.f.readlines(None), [b"bye\n", b"abc"]) 1607db96d56Sopenharmony_ci 1617db96d56Sopenharmony_ci def test_reject(self): 1627db96d56Sopenharmony_ci self.assertRaises(TypeError, self.f.write, "Hello!") 1637db96d56Sopenharmony_ci 1647db96d56Sopenharmony_ci def testRepr(self): 1657db96d56Sopenharmony_ci self.assertEqual(repr(self.f), 1667db96d56Sopenharmony_ci "<%s.FileIO name=%r mode=%r closefd=True>" % 1677db96d56Sopenharmony_ci (self.modulename, self.f.name, self.f.mode)) 1687db96d56Sopenharmony_ci del self.f.name 1697db96d56Sopenharmony_ci self.assertEqual(repr(self.f), 1707db96d56Sopenharmony_ci "<%s.FileIO fd=%r mode=%r closefd=True>" % 1717db96d56Sopenharmony_ci (self.modulename, self.f.fileno(), self.f.mode)) 1727db96d56Sopenharmony_ci self.f.close() 1737db96d56Sopenharmony_ci self.assertEqual(repr(self.f), 1747db96d56Sopenharmony_ci "<%s.FileIO [closed]>" % (self.modulename,)) 1757db96d56Sopenharmony_ci 1767db96d56Sopenharmony_ci def testReprNoCloseFD(self): 1777db96d56Sopenharmony_ci fd = os.open(TESTFN, os.O_RDONLY) 1787db96d56Sopenharmony_ci try: 1797db96d56Sopenharmony_ci with self.FileIO(fd, 'r', closefd=False) as f: 1807db96d56Sopenharmony_ci self.assertEqual(repr(f), 1817db96d56Sopenharmony_ci "<%s.FileIO name=%r mode=%r closefd=False>" % 1827db96d56Sopenharmony_ci (self.modulename, f.name, f.mode)) 1837db96d56Sopenharmony_ci finally: 1847db96d56Sopenharmony_ci os.close(fd) 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_ci def testRecursiveRepr(self): 1877db96d56Sopenharmony_ci # Issue #25455 1887db96d56Sopenharmony_ci with swap_attr(self.f, 'name', self.f): 1897db96d56Sopenharmony_ci with self.assertRaises(RuntimeError): 1907db96d56Sopenharmony_ci repr(self.f) # Should not crash 1917db96d56Sopenharmony_ci 1927db96d56Sopenharmony_ci def testErrors(self): 1937db96d56Sopenharmony_ci f = self.f 1947db96d56Sopenharmony_ci self.assertFalse(f.isatty()) 1957db96d56Sopenharmony_ci self.assertFalse(f.closed) 1967db96d56Sopenharmony_ci #self.assertEqual(f.name, TESTFN) 1977db96d56Sopenharmony_ci self.assertRaises(ValueError, f.read, 10) # Open for reading 1987db96d56Sopenharmony_ci f.close() 1997db96d56Sopenharmony_ci self.assertTrue(f.closed) 2007db96d56Sopenharmony_ci f = self.FileIO(TESTFN, 'r') 2017db96d56Sopenharmony_ci self.assertRaises(TypeError, f.readinto, "") 2027db96d56Sopenharmony_ci self.assertFalse(f.closed) 2037db96d56Sopenharmony_ci f.close() 2047db96d56Sopenharmony_ci self.assertTrue(f.closed) 2057db96d56Sopenharmony_ci 2067db96d56Sopenharmony_ci def testMethods(self): 2077db96d56Sopenharmony_ci methods = ['fileno', 'isatty', 'seekable', 'readable', 'writable', 2087db96d56Sopenharmony_ci 'read', 'readall', 'readline', 'readlines', 2097db96d56Sopenharmony_ci 'tell', 'truncate', 'flush'] 2107db96d56Sopenharmony_ci 2117db96d56Sopenharmony_ci self.f.close() 2127db96d56Sopenharmony_ci self.assertTrue(self.f.closed) 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ci for methodname in methods: 2157db96d56Sopenharmony_ci method = getattr(self.f, methodname) 2167db96d56Sopenharmony_ci # should raise on closed file 2177db96d56Sopenharmony_ci self.assertRaises(ValueError, method) 2187db96d56Sopenharmony_ci 2197db96d56Sopenharmony_ci self.assertRaises(TypeError, self.f.readinto) 2207db96d56Sopenharmony_ci self.assertRaises(ValueError, self.f.readinto, bytearray(1)) 2217db96d56Sopenharmony_ci self.assertRaises(TypeError, self.f.seek) 2227db96d56Sopenharmony_ci self.assertRaises(ValueError, self.f.seek, 0) 2237db96d56Sopenharmony_ci self.assertRaises(TypeError, self.f.write) 2247db96d56Sopenharmony_ci self.assertRaises(ValueError, self.f.write, b'') 2257db96d56Sopenharmony_ci self.assertRaises(TypeError, self.f.writelines) 2267db96d56Sopenharmony_ci self.assertRaises(ValueError, self.f.writelines, b'') 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ci def testOpendir(self): 2297db96d56Sopenharmony_ci # Issue 3703: opening a directory should fill the errno 2307db96d56Sopenharmony_ci # Windows always returns "[Errno 13]: Permission denied 2317db96d56Sopenharmony_ci # Unix uses fstat and returns "[Errno 21]: Is a directory" 2327db96d56Sopenharmony_ci try: 2337db96d56Sopenharmony_ci self.FileIO('.', 'r') 2347db96d56Sopenharmony_ci except OSError as e: 2357db96d56Sopenharmony_ci self.assertNotEqual(e.errno, 0) 2367db96d56Sopenharmony_ci self.assertEqual(e.filename, ".") 2377db96d56Sopenharmony_ci else: 2387db96d56Sopenharmony_ci self.fail("Should have raised OSError") 2397db96d56Sopenharmony_ci 2407db96d56Sopenharmony_ci @unittest.skipIf(os.name == 'nt', "test only works on a POSIX-like system") 2417db96d56Sopenharmony_ci def testOpenDirFD(self): 2427db96d56Sopenharmony_ci fd = os.open('.', os.O_RDONLY) 2437db96d56Sopenharmony_ci with self.assertRaises(OSError) as cm: 2447db96d56Sopenharmony_ci self.FileIO(fd, 'r') 2457db96d56Sopenharmony_ci os.close(fd) 2467db96d56Sopenharmony_ci self.assertEqual(cm.exception.errno, errno.EISDIR) 2477db96d56Sopenharmony_ci 2487db96d56Sopenharmony_ci #A set of functions testing that we get expected behaviour if someone has 2497db96d56Sopenharmony_ci #manually closed the internal file descriptor. First, a decorator: 2507db96d56Sopenharmony_ci def ClosedFD(func): 2517db96d56Sopenharmony_ci @wraps(func) 2527db96d56Sopenharmony_ci def wrapper(self): 2537db96d56Sopenharmony_ci #forcibly close the fd before invoking the problem function 2547db96d56Sopenharmony_ci f = self.f 2557db96d56Sopenharmony_ci os.close(f.fileno()) 2567db96d56Sopenharmony_ci try: 2577db96d56Sopenharmony_ci func(self, f) 2587db96d56Sopenharmony_ci finally: 2597db96d56Sopenharmony_ci try: 2607db96d56Sopenharmony_ci self.f.close() 2617db96d56Sopenharmony_ci except OSError: 2627db96d56Sopenharmony_ci pass 2637db96d56Sopenharmony_ci return wrapper 2647db96d56Sopenharmony_ci 2657db96d56Sopenharmony_ci def ClosedFDRaises(func): 2667db96d56Sopenharmony_ci @wraps(func) 2677db96d56Sopenharmony_ci def wrapper(self): 2687db96d56Sopenharmony_ci #forcibly close the fd before invoking the problem function 2697db96d56Sopenharmony_ci f = self.f 2707db96d56Sopenharmony_ci os.close(f.fileno()) 2717db96d56Sopenharmony_ci try: 2727db96d56Sopenharmony_ci func(self, f) 2737db96d56Sopenharmony_ci except OSError as e: 2747db96d56Sopenharmony_ci self.assertEqual(e.errno, errno.EBADF) 2757db96d56Sopenharmony_ci else: 2767db96d56Sopenharmony_ci self.fail("Should have raised OSError") 2777db96d56Sopenharmony_ci finally: 2787db96d56Sopenharmony_ci try: 2797db96d56Sopenharmony_ci self.f.close() 2807db96d56Sopenharmony_ci except OSError: 2817db96d56Sopenharmony_ci pass 2827db96d56Sopenharmony_ci return wrapper 2837db96d56Sopenharmony_ci 2847db96d56Sopenharmony_ci @ClosedFDRaises 2857db96d56Sopenharmony_ci def testErrnoOnClose(self, f): 2867db96d56Sopenharmony_ci f.close() 2877db96d56Sopenharmony_ci 2887db96d56Sopenharmony_ci @ClosedFDRaises 2897db96d56Sopenharmony_ci def testErrnoOnClosedWrite(self, f): 2907db96d56Sopenharmony_ci f.write(b'a') 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci @ClosedFDRaises 2937db96d56Sopenharmony_ci def testErrnoOnClosedSeek(self, f): 2947db96d56Sopenharmony_ci f.seek(0) 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ci @ClosedFDRaises 2977db96d56Sopenharmony_ci def testErrnoOnClosedTell(self, f): 2987db96d56Sopenharmony_ci f.tell() 2997db96d56Sopenharmony_ci 3007db96d56Sopenharmony_ci @ClosedFDRaises 3017db96d56Sopenharmony_ci def testErrnoOnClosedTruncate(self, f): 3027db96d56Sopenharmony_ci f.truncate(0) 3037db96d56Sopenharmony_ci 3047db96d56Sopenharmony_ci @ClosedFD 3057db96d56Sopenharmony_ci def testErrnoOnClosedSeekable(self, f): 3067db96d56Sopenharmony_ci f.seekable() 3077db96d56Sopenharmony_ci 3087db96d56Sopenharmony_ci @ClosedFD 3097db96d56Sopenharmony_ci def testErrnoOnClosedReadable(self, f): 3107db96d56Sopenharmony_ci f.readable() 3117db96d56Sopenharmony_ci 3127db96d56Sopenharmony_ci @ClosedFD 3137db96d56Sopenharmony_ci def testErrnoOnClosedWritable(self, f): 3147db96d56Sopenharmony_ci f.writable() 3157db96d56Sopenharmony_ci 3167db96d56Sopenharmony_ci @ClosedFD 3177db96d56Sopenharmony_ci def testErrnoOnClosedFileno(self, f): 3187db96d56Sopenharmony_ci f.fileno() 3197db96d56Sopenharmony_ci 3207db96d56Sopenharmony_ci @ClosedFD 3217db96d56Sopenharmony_ci def testErrnoOnClosedIsatty(self, f): 3227db96d56Sopenharmony_ci self.assertEqual(f.isatty(), False) 3237db96d56Sopenharmony_ci 3247db96d56Sopenharmony_ci def ReopenForRead(self): 3257db96d56Sopenharmony_ci try: 3267db96d56Sopenharmony_ci self.f.close() 3277db96d56Sopenharmony_ci except OSError: 3287db96d56Sopenharmony_ci pass 3297db96d56Sopenharmony_ci self.f = self.FileIO(TESTFN, 'r') 3307db96d56Sopenharmony_ci os.close(self.f.fileno()) 3317db96d56Sopenharmony_ci return self.f 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ci @ClosedFDRaises 3347db96d56Sopenharmony_ci def testErrnoOnClosedRead(self, f): 3357db96d56Sopenharmony_ci f = self.ReopenForRead() 3367db96d56Sopenharmony_ci f.read(1) 3377db96d56Sopenharmony_ci 3387db96d56Sopenharmony_ci @ClosedFDRaises 3397db96d56Sopenharmony_ci def testErrnoOnClosedReadall(self, f): 3407db96d56Sopenharmony_ci f = self.ReopenForRead() 3417db96d56Sopenharmony_ci f.readall() 3427db96d56Sopenharmony_ci 3437db96d56Sopenharmony_ci @ClosedFDRaises 3447db96d56Sopenharmony_ci def testErrnoOnClosedReadinto(self, f): 3457db96d56Sopenharmony_ci f = self.ReopenForRead() 3467db96d56Sopenharmony_ci a = array('b', b'x'*10) 3477db96d56Sopenharmony_ci f.readinto(a) 3487db96d56Sopenharmony_ci 3497db96d56Sopenharmony_ciclass CAutoFileTests(AutoFileTests, unittest.TestCase): 3507db96d56Sopenharmony_ci FileIO = _io.FileIO 3517db96d56Sopenharmony_ci modulename = '_io' 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ciclass PyAutoFileTests(AutoFileTests, unittest.TestCase): 3547db96d56Sopenharmony_ci FileIO = _pyio.FileIO 3557db96d56Sopenharmony_ci modulename = '_pyio' 3567db96d56Sopenharmony_ci 3577db96d56Sopenharmony_ci 3587db96d56Sopenharmony_ciclass OtherFileTests: 3597db96d56Sopenharmony_ci 3607db96d56Sopenharmony_ci def testAbles(self): 3617db96d56Sopenharmony_ci try: 3627db96d56Sopenharmony_ci f = self.FileIO(TESTFN, "w") 3637db96d56Sopenharmony_ci self.assertEqual(f.readable(), False) 3647db96d56Sopenharmony_ci self.assertEqual(f.writable(), True) 3657db96d56Sopenharmony_ci self.assertEqual(f.seekable(), True) 3667db96d56Sopenharmony_ci f.close() 3677db96d56Sopenharmony_ci 3687db96d56Sopenharmony_ci f = self.FileIO(TESTFN, "r") 3697db96d56Sopenharmony_ci self.assertEqual(f.readable(), True) 3707db96d56Sopenharmony_ci self.assertEqual(f.writable(), False) 3717db96d56Sopenharmony_ci self.assertEqual(f.seekable(), True) 3727db96d56Sopenharmony_ci f.close() 3737db96d56Sopenharmony_ci 3747db96d56Sopenharmony_ci f = self.FileIO(TESTFN, "a+") 3757db96d56Sopenharmony_ci self.assertEqual(f.readable(), True) 3767db96d56Sopenharmony_ci self.assertEqual(f.writable(), True) 3777db96d56Sopenharmony_ci self.assertEqual(f.seekable(), True) 3787db96d56Sopenharmony_ci self.assertEqual(f.isatty(), False) 3797db96d56Sopenharmony_ci f.close() 3807db96d56Sopenharmony_ci 3817db96d56Sopenharmony_ci if sys.platform != "win32" and not is_emscripten: 3827db96d56Sopenharmony_ci try: 3837db96d56Sopenharmony_ci f = self.FileIO("/dev/tty", "a") 3847db96d56Sopenharmony_ci except OSError: 3857db96d56Sopenharmony_ci # When run in a cron job there just aren't any 3867db96d56Sopenharmony_ci # ttys, so skip the test. This also handles other 3877db96d56Sopenharmony_ci # OS'es that don't support /dev/tty. 3887db96d56Sopenharmony_ci pass 3897db96d56Sopenharmony_ci else: 3907db96d56Sopenharmony_ci self.assertEqual(f.readable(), False) 3917db96d56Sopenharmony_ci self.assertEqual(f.writable(), True) 3927db96d56Sopenharmony_ci if sys.platform != "darwin" and \ 3937db96d56Sopenharmony_ci 'bsd' not in sys.platform and \ 3947db96d56Sopenharmony_ci not sys.platform.startswith(('sunos', 'aix')): 3957db96d56Sopenharmony_ci # Somehow /dev/tty appears seekable on some BSDs 3967db96d56Sopenharmony_ci self.assertEqual(f.seekable(), False) 3977db96d56Sopenharmony_ci self.assertEqual(f.isatty(), True) 3987db96d56Sopenharmony_ci f.close() 3997db96d56Sopenharmony_ci finally: 4007db96d56Sopenharmony_ci os.unlink(TESTFN) 4017db96d56Sopenharmony_ci 4027db96d56Sopenharmony_ci def testInvalidModeStrings(self): 4037db96d56Sopenharmony_ci # check invalid mode strings 4047db96d56Sopenharmony_ci for mode in ("", "aU", "wU+", "rw", "rt"): 4057db96d56Sopenharmony_ci try: 4067db96d56Sopenharmony_ci f = self.FileIO(TESTFN, mode) 4077db96d56Sopenharmony_ci except ValueError: 4087db96d56Sopenharmony_ci pass 4097db96d56Sopenharmony_ci else: 4107db96d56Sopenharmony_ci f.close() 4117db96d56Sopenharmony_ci self.fail('%r is an invalid file mode' % mode) 4127db96d56Sopenharmony_ci 4137db96d56Sopenharmony_ci def testModeStrings(self): 4147db96d56Sopenharmony_ci # test that the mode attribute is correct for various mode strings 4157db96d56Sopenharmony_ci # given as init args 4167db96d56Sopenharmony_ci try: 4177db96d56Sopenharmony_ci for modes in [('w', 'wb'), ('wb', 'wb'), ('wb+', 'rb+'), 4187db96d56Sopenharmony_ci ('w+b', 'rb+'), ('a', 'ab'), ('ab', 'ab'), 4197db96d56Sopenharmony_ci ('ab+', 'ab+'), ('a+b', 'ab+'), ('r', 'rb'), 4207db96d56Sopenharmony_ci ('rb', 'rb'), ('rb+', 'rb+'), ('r+b', 'rb+')]: 4217db96d56Sopenharmony_ci # read modes are last so that TESTFN will exist first 4227db96d56Sopenharmony_ci with self.FileIO(TESTFN, modes[0]) as f: 4237db96d56Sopenharmony_ci self.assertEqual(f.mode, modes[1]) 4247db96d56Sopenharmony_ci finally: 4257db96d56Sopenharmony_ci if os.path.exists(TESTFN): 4267db96d56Sopenharmony_ci os.unlink(TESTFN) 4277db96d56Sopenharmony_ci 4287db96d56Sopenharmony_ci def testUnicodeOpen(self): 4297db96d56Sopenharmony_ci # verify repr works for unicode too 4307db96d56Sopenharmony_ci f = self.FileIO(str(TESTFN), "w") 4317db96d56Sopenharmony_ci f.close() 4327db96d56Sopenharmony_ci os.unlink(TESTFN) 4337db96d56Sopenharmony_ci 4347db96d56Sopenharmony_ci def testBytesOpen(self): 4357db96d56Sopenharmony_ci # Opening a bytes filename 4367db96d56Sopenharmony_ci fn = TESTFN_ASCII.encode("ascii") 4377db96d56Sopenharmony_ci f = self.FileIO(fn, "w") 4387db96d56Sopenharmony_ci try: 4397db96d56Sopenharmony_ci f.write(b"abc") 4407db96d56Sopenharmony_ci f.close() 4417db96d56Sopenharmony_ci with open(TESTFN_ASCII, "rb") as f: 4427db96d56Sopenharmony_ci self.assertEqual(f.read(), b"abc") 4437db96d56Sopenharmony_ci finally: 4447db96d56Sopenharmony_ci os.unlink(TESTFN_ASCII) 4457db96d56Sopenharmony_ci 4467db96d56Sopenharmony_ci @unittest.skipIf(sys.getfilesystemencoding() != 'utf-8', 4477db96d56Sopenharmony_ci "test only works for utf-8 filesystems") 4487db96d56Sopenharmony_ci def testUtf8BytesOpen(self): 4497db96d56Sopenharmony_ci # Opening a UTF-8 bytes filename 4507db96d56Sopenharmony_ci try: 4517db96d56Sopenharmony_ci fn = TESTFN_UNICODE.encode("utf-8") 4527db96d56Sopenharmony_ci except UnicodeEncodeError: 4537db96d56Sopenharmony_ci self.skipTest('could not encode %r to utf-8' % TESTFN_UNICODE) 4547db96d56Sopenharmony_ci f = self.FileIO(fn, "w") 4557db96d56Sopenharmony_ci try: 4567db96d56Sopenharmony_ci f.write(b"abc") 4577db96d56Sopenharmony_ci f.close() 4587db96d56Sopenharmony_ci with open(TESTFN_UNICODE, "rb") as f: 4597db96d56Sopenharmony_ci self.assertEqual(f.read(), b"abc") 4607db96d56Sopenharmony_ci finally: 4617db96d56Sopenharmony_ci os.unlink(TESTFN_UNICODE) 4627db96d56Sopenharmony_ci 4637db96d56Sopenharmony_ci def testConstructorHandlesNULChars(self): 4647db96d56Sopenharmony_ci fn_with_NUL = 'foo\0bar' 4657db96d56Sopenharmony_ci self.assertRaises(ValueError, self.FileIO, fn_with_NUL, 'w') 4667db96d56Sopenharmony_ci self.assertRaises(ValueError, self.FileIO, bytes(fn_with_NUL, 'ascii'), 'w') 4677db96d56Sopenharmony_ci 4687db96d56Sopenharmony_ci def testInvalidFd(self): 4697db96d56Sopenharmony_ci self.assertRaises(ValueError, self.FileIO, -10) 4707db96d56Sopenharmony_ci self.assertRaises(OSError, self.FileIO, make_bad_fd()) 4717db96d56Sopenharmony_ci if sys.platform == 'win32': 4727db96d56Sopenharmony_ci import msvcrt 4737db96d56Sopenharmony_ci self.assertRaises(OSError, msvcrt.get_osfhandle, make_bad_fd()) 4747db96d56Sopenharmony_ci 4757db96d56Sopenharmony_ci def testBadModeArgument(self): 4767db96d56Sopenharmony_ci # verify that we get a sensible error message for bad mode argument 4777db96d56Sopenharmony_ci bad_mode = "qwerty" 4787db96d56Sopenharmony_ci try: 4797db96d56Sopenharmony_ci f = self.FileIO(TESTFN, bad_mode) 4807db96d56Sopenharmony_ci except ValueError as msg: 4817db96d56Sopenharmony_ci if msg.args[0] != 0: 4827db96d56Sopenharmony_ci s = str(msg) 4837db96d56Sopenharmony_ci if TESTFN in s or bad_mode not in s: 4847db96d56Sopenharmony_ci self.fail("bad error message for invalid mode: %s" % s) 4857db96d56Sopenharmony_ci # if msg.args[0] == 0, we're probably on Windows where there may be 4867db96d56Sopenharmony_ci # no obvious way to discover why open() failed. 4877db96d56Sopenharmony_ci else: 4887db96d56Sopenharmony_ci f.close() 4897db96d56Sopenharmony_ci self.fail("no error for invalid mode: %s" % bad_mode) 4907db96d56Sopenharmony_ci 4917db96d56Sopenharmony_ci def testTruncate(self): 4927db96d56Sopenharmony_ci f = self.FileIO(TESTFN, 'w') 4937db96d56Sopenharmony_ci f.write(bytes(bytearray(range(10)))) 4947db96d56Sopenharmony_ci self.assertEqual(f.tell(), 10) 4957db96d56Sopenharmony_ci f.truncate(5) 4967db96d56Sopenharmony_ci self.assertEqual(f.tell(), 10) 4977db96d56Sopenharmony_ci self.assertEqual(f.seek(0, io.SEEK_END), 5) 4987db96d56Sopenharmony_ci f.truncate(15) 4997db96d56Sopenharmony_ci self.assertEqual(f.tell(), 5) 5007db96d56Sopenharmony_ci self.assertEqual(f.seek(0, io.SEEK_END), 15) 5017db96d56Sopenharmony_ci f.close() 5027db96d56Sopenharmony_ci 5037db96d56Sopenharmony_ci def testTruncateOnWindows(self): 5047db96d56Sopenharmony_ci def bug801631(): 5057db96d56Sopenharmony_ci # SF bug <http://www.python.org/sf/801631> 5067db96d56Sopenharmony_ci # "file.truncate fault on windows" 5077db96d56Sopenharmony_ci f = self.FileIO(TESTFN, 'w') 5087db96d56Sopenharmony_ci f.write(bytes(range(11))) 5097db96d56Sopenharmony_ci f.close() 5107db96d56Sopenharmony_ci 5117db96d56Sopenharmony_ci f = self.FileIO(TESTFN,'r+') 5127db96d56Sopenharmony_ci data = f.read(5) 5137db96d56Sopenharmony_ci if data != bytes(range(5)): 5147db96d56Sopenharmony_ci self.fail("Read on file opened for update failed %r" % data) 5157db96d56Sopenharmony_ci if f.tell() != 5: 5167db96d56Sopenharmony_ci self.fail("File pos after read wrong %d" % f.tell()) 5177db96d56Sopenharmony_ci 5187db96d56Sopenharmony_ci f.truncate() 5197db96d56Sopenharmony_ci if f.tell() != 5: 5207db96d56Sopenharmony_ci self.fail("File pos after ftruncate wrong %d" % f.tell()) 5217db96d56Sopenharmony_ci 5227db96d56Sopenharmony_ci f.close() 5237db96d56Sopenharmony_ci size = os.path.getsize(TESTFN) 5247db96d56Sopenharmony_ci if size != 5: 5257db96d56Sopenharmony_ci self.fail("File size after ftruncate wrong %d" % size) 5267db96d56Sopenharmony_ci 5277db96d56Sopenharmony_ci try: 5287db96d56Sopenharmony_ci bug801631() 5297db96d56Sopenharmony_ci finally: 5307db96d56Sopenharmony_ci os.unlink(TESTFN) 5317db96d56Sopenharmony_ci 5327db96d56Sopenharmony_ci def testAppend(self): 5337db96d56Sopenharmony_ci try: 5347db96d56Sopenharmony_ci f = open(TESTFN, 'wb') 5357db96d56Sopenharmony_ci f.write(b'spam') 5367db96d56Sopenharmony_ci f.close() 5377db96d56Sopenharmony_ci f = open(TESTFN, 'ab') 5387db96d56Sopenharmony_ci f.write(b'eggs') 5397db96d56Sopenharmony_ci f.close() 5407db96d56Sopenharmony_ci f = open(TESTFN, 'rb') 5417db96d56Sopenharmony_ci d = f.read() 5427db96d56Sopenharmony_ci f.close() 5437db96d56Sopenharmony_ci self.assertEqual(d, b'spameggs') 5447db96d56Sopenharmony_ci finally: 5457db96d56Sopenharmony_ci try: 5467db96d56Sopenharmony_ci os.unlink(TESTFN) 5477db96d56Sopenharmony_ci except: 5487db96d56Sopenharmony_ci pass 5497db96d56Sopenharmony_ci 5507db96d56Sopenharmony_ci def testInvalidInit(self): 5517db96d56Sopenharmony_ci self.assertRaises(TypeError, self.FileIO, "1", 0, 0) 5527db96d56Sopenharmony_ci 5537db96d56Sopenharmony_ci def testWarnings(self): 5547db96d56Sopenharmony_ci with check_warnings(quiet=True) as w: 5557db96d56Sopenharmony_ci self.assertEqual(w.warnings, []) 5567db96d56Sopenharmony_ci self.assertRaises(TypeError, self.FileIO, []) 5577db96d56Sopenharmony_ci self.assertEqual(w.warnings, []) 5587db96d56Sopenharmony_ci self.assertRaises(ValueError, self.FileIO, "/some/invalid/name", "rt") 5597db96d56Sopenharmony_ci self.assertEqual(w.warnings, []) 5607db96d56Sopenharmony_ci 5617db96d56Sopenharmony_ci def testUnclosedFDOnException(self): 5627db96d56Sopenharmony_ci class MyException(Exception): pass 5637db96d56Sopenharmony_ci class MyFileIO(self.FileIO): 5647db96d56Sopenharmony_ci def __setattr__(self, name, value): 5657db96d56Sopenharmony_ci if name == "name": 5667db96d56Sopenharmony_ci raise MyException("blocked setting name") 5677db96d56Sopenharmony_ci return super(MyFileIO, self).__setattr__(name, value) 5687db96d56Sopenharmony_ci fd = os.open(__file__, os.O_RDONLY) 5697db96d56Sopenharmony_ci self.assertRaises(MyException, MyFileIO, fd) 5707db96d56Sopenharmony_ci os.close(fd) # should not raise OSError(EBADF) 5717db96d56Sopenharmony_ci 5727db96d56Sopenharmony_ci 5737db96d56Sopenharmony_ciclass COtherFileTests(OtherFileTests, unittest.TestCase): 5747db96d56Sopenharmony_ci FileIO = _io.FileIO 5757db96d56Sopenharmony_ci modulename = '_io' 5767db96d56Sopenharmony_ci 5777db96d56Sopenharmony_ci @cpython_only 5787db96d56Sopenharmony_ci def testInvalidFd_overflow(self): 5797db96d56Sopenharmony_ci # Issue 15989 5807db96d56Sopenharmony_ci import _testcapi 5817db96d56Sopenharmony_ci self.assertRaises(TypeError, self.FileIO, _testcapi.INT_MAX + 1) 5827db96d56Sopenharmony_ci self.assertRaises(TypeError, self.FileIO, _testcapi.INT_MIN - 1) 5837db96d56Sopenharmony_ci 5847db96d56Sopenharmony_ci def test_open_code(self): 5857db96d56Sopenharmony_ci # Check that the default behaviour of open_code matches 5867db96d56Sopenharmony_ci # open("rb") 5877db96d56Sopenharmony_ci with self.FileIO(__file__, "rb") as f: 5887db96d56Sopenharmony_ci expected = f.read() 5897db96d56Sopenharmony_ci with _io.open_code(__file__) as f: 5907db96d56Sopenharmony_ci actual = f.read() 5917db96d56Sopenharmony_ci self.assertEqual(expected, actual) 5927db96d56Sopenharmony_ci 5937db96d56Sopenharmony_ci 5947db96d56Sopenharmony_ciclass PyOtherFileTests(OtherFileTests, unittest.TestCase): 5957db96d56Sopenharmony_ci FileIO = _pyio.FileIO 5967db96d56Sopenharmony_ci modulename = '_pyio' 5977db96d56Sopenharmony_ci 5987db96d56Sopenharmony_ci def test_open_code(self): 5997db96d56Sopenharmony_ci # Check that the default behaviour of open_code matches 6007db96d56Sopenharmony_ci # open("rb") 6017db96d56Sopenharmony_ci with self.FileIO(__file__, "rb") as f: 6027db96d56Sopenharmony_ci expected = f.read() 6037db96d56Sopenharmony_ci with check_warnings(quiet=True) as w: 6047db96d56Sopenharmony_ci # Always test _open_code_with_warning 6057db96d56Sopenharmony_ci with _pyio._open_code_with_warning(__file__) as f: 6067db96d56Sopenharmony_ci actual = f.read() 6077db96d56Sopenharmony_ci self.assertEqual(expected, actual) 6087db96d56Sopenharmony_ci self.assertNotEqual(w.warnings, []) 6097db96d56Sopenharmony_ci 6107db96d56Sopenharmony_ci 6117db96d56Sopenharmony_cidef tearDownModule(): 6127db96d56Sopenharmony_ci # Historically, these tests have been sloppy about removing TESTFN. 6137db96d56Sopenharmony_ci # So get rid of it no matter what. 6147db96d56Sopenharmony_ci if os.path.exists(TESTFN): 6157db96d56Sopenharmony_ci os.unlink(TESTFN) 6167db96d56Sopenharmony_ci 6177db96d56Sopenharmony_ci 6187db96d56Sopenharmony_ciif __name__ == '__main__': 6197db96d56Sopenharmony_ci unittest.main() 620