17db96d56Sopenharmony_ci"""Unit tests for the io module."""
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci# Tests of io are scattered over the test suite:
47db96d56Sopenharmony_ci# * test_bufio - tests file buffering
57db96d56Sopenharmony_ci# * test_memoryio - tests BytesIO and StringIO
67db96d56Sopenharmony_ci# * test_fileio - tests FileIO
77db96d56Sopenharmony_ci# * test_file - tests the file interface
87db96d56Sopenharmony_ci# * test_io - tests everything else in the io module
97db96d56Sopenharmony_ci# * test_univnewlines - tests universal newline support
107db96d56Sopenharmony_ci# * test_largefile - tests operations on a file greater than 2**32 bytes
117db96d56Sopenharmony_ci#     (only enabled with -ulargefile)
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ci################################################################################
147db96d56Sopenharmony_ci# ATTENTION TEST WRITERS!!!
157db96d56Sopenharmony_ci################################################################################
167db96d56Sopenharmony_ci# When writing tests for io, it's important to test both the C and Python
177db96d56Sopenharmony_ci# implementations. This is usually done by writing a base test that refers to
187db96d56Sopenharmony_ci# the type it is testing as an attribute. Then it provides custom subclasses to
197db96d56Sopenharmony_ci# test both implementations. This file has lots of examples.
207db96d56Sopenharmony_ci################################################################################
217db96d56Sopenharmony_ci
227db96d56Sopenharmony_ciimport abc
237db96d56Sopenharmony_ciimport array
247db96d56Sopenharmony_ciimport errno
257db96d56Sopenharmony_ciimport locale
267db96d56Sopenharmony_ciimport os
277db96d56Sopenharmony_ciimport pickle
287db96d56Sopenharmony_ciimport random
297db96d56Sopenharmony_ciimport signal
307db96d56Sopenharmony_ciimport sys
317db96d56Sopenharmony_ciimport textwrap
327db96d56Sopenharmony_ciimport threading
337db96d56Sopenharmony_ciimport time
347db96d56Sopenharmony_ciimport unittest
357db96d56Sopenharmony_ciimport warnings
367db96d56Sopenharmony_ciimport weakref
377db96d56Sopenharmony_cifrom collections import deque, UserList
387db96d56Sopenharmony_cifrom itertools import cycle, count
397db96d56Sopenharmony_cifrom test import support
407db96d56Sopenharmony_cifrom test.support.script_helper import (
417db96d56Sopenharmony_ci    assert_python_ok, assert_python_failure, run_python_until_end)
427db96d56Sopenharmony_cifrom test.support import import_helper
437db96d56Sopenharmony_cifrom test.support import os_helper
447db96d56Sopenharmony_cifrom test.support import threading_helper
457db96d56Sopenharmony_cifrom test.support import warnings_helper
467db96d56Sopenharmony_cifrom test.support import skip_if_sanitizer
477db96d56Sopenharmony_cifrom test.support.os_helper import FakePath
487db96d56Sopenharmony_ci
497db96d56Sopenharmony_ciimport codecs
507db96d56Sopenharmony_ciimport io  # C implementation of io
517db96d56Sopenharmony_ciimport _pyio as pyio # Python implementation of io
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_citry:
547db96d56Sopenharmony_ci    import ctypes
557db96d56Sopenharmony_ciexcept ImportError:
567db96d56Sopenharmony_ci    def byteslike(*pos, **kw):
577db96d56Sopenharmony_ci        return array.array("b", bytes(*pos, **kw))
587db96d56Sopenharmony_cielse:
597db96d56Sopenharmony_ci    def byteslike(*pos, **kw):
607db96d56Sopenharmony_ci        """Create a bytes-like object having no string or sequence methods"""
617db96d56Sopenharmony_ci        data = bytes(*pos, **kw)
627db96d56Sopenharmony_ci        obj = EmptyStruct()
637db96d56Sopenharmony_ci        ctypes.resize(obj, len(data))
647db96d56Sopenharmony_ci        memoryview(obj).cast("B")[:] = data
657db96d56Sopenharmony_ci        return obj
667db96d56Sopenharmony_ci    class EmptyStruct(ctypes.Structure):
677db96d56Sopenharmony_ci        pass
687db96d56Sopenharmony_ci
697db96d56Sopenharmony_ci# Does io.IOBase finalizer log the exception if the close() method fails?
707db96d56Sopenharmony_ci# The exception is ignored silently by default in release build.
717db96d56Sopenharmony_ciIOBASE_EMITS_UNRAISABLE = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode)
727db96d56Sopenharmony_ci
737db96d56Sopenharmony_ci
747db96d56Sopenharmony_cidef _default_chunk_size():
757db96d56Sopenharmony_ci    """Get the default TextIOWrapper chunk size"""
767db96d56Sopenharmony_ci    with open(__file__, "r", encoding="latin-1") as f:
777db96d56Sopenharmony_ci        return f._CHUNK_SIZE
787db96d56Sopenharmony_ci
797db96d56Sopenharmony_cirequires_alarm = unittest.skipUnless(
807db96d56Sopenharmony_ci    hasattr(signal, "alarm"), "test requires signal.alarm()"
817db96d56Sopenharmony_ci)
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ciclass MockRawIOWithoutRead:
857db96d56Sopenharmony_ci    """A RawIO implementation without read(), so as to exercise the default
867db96d56Sopenharmony_ci    RawIO.read() which calls readinto()."""
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_ci    def __init__(self, read_stack=()):
897db96d56Sopenharmony_ci        self._read_stack = list(read_stack)
907db96d56Sopenharmony_ci        self._write_stack = []
917db96d56Sopenharmony_ci        self._reads = 0
927db96d56Sopenharmony_ci        self._extraneous_reads = 0
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_ci    def write(self, b):
957db96d56Sopenharmony_ci        self._write_stack.append(bytes(b))
967db96d56Sopenharmony_ci        return len(b)
977db96d56Sopenharmony_ci
987db96d56Sopenharmony_ci    def writable(self):
997db96d56Sopenharmony_ci        return True
1007db96d56Sopenharmony_ci
1017db96d56Sopenharmony_ci    def fileno(self):
1027db96d56Sopenharmony_ci        return 42
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ci    def readable(self):
1057db96d56Sopenharmony_ci        return True
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ci    def seekable(self):
1087db96d56Sopenharmony_ci        return True
1097db96d56Sopenharmony_ci
1107db96d56Sopenharmony_ci    def seek(self, pos, whence):
1117db96d56Sopenharmony_ci        return 0   # wrong but we gotta return something
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_ci    def tell(self):
1147db96d56Sopenharmony_ci        return 0   # same comment as above
1157db96d56Sopenharmony_ci
1167db96d56Sopenharmony_ci    def readinto(self, buf):
1177db96d56Sopenharmony_ci        self._reads += 1
1187db96d56Sopenharmony_ci        max_len = len(buf)
1197db96d56Sopenharmony_ci        try:
1207db96d56Sopenharmony_ci            data = self._read_stack[0]
1217db96d56Sopenharmony_ci        except IndexError:
1227db96d56Sopenharmony_ci            self._extraneous_reads += 1
1237db96d56Sopenharmony_ci            return 0
1247db96d56Sopenharmony_ci        if data is None:
1257db96d56Sopenharmony_ci            del self._read_stack[0]
1267db96d56Sopenharmony_ci            return None
1277db96d56Sopenharmony_ci        n = len(data)
1287db96d56Sopenharmony_ci        if len(data) <= max_len:
1297db96d56Sopenharmony_ci            del self._read_stack[0]
1307db96d56Sopenharmony_ci            buf[:n] = data
1317db96d56Sopenharmony_ci            return n
1327db96d56Sopenharmony_ci        else:
1337db96d56Sopenharmony_ci            buf[:] = data[:max_len]
1347db96d56Sopenharmony_ci            self._read_stack[0] = data[max_len:]
1357db96d56Sopenharmony_ci            return max_len
1367db96d56Sopenharmony_ci
1377db96d56Sopenharmony_ci    def truncate(self, pos=None):
1387db96d56Sopenharmony_ci        return pos
1397db96d56Sopenharmony_ci
1407db96d56Sopenharmony_ciclass CMockRawIOWithoutRead(MockRawIOWithoutRead, io.RawIOBase):
1417db96d56Sopenharmony_ci    pass
1427db96d56Sopenharmony_ci
1437db96d56Sopenharmony_ciclass PyMockRawIOWithoutRead(MockRawIOWithoutRead, pyio.RawIOBase):
1447db96d56Sopenharmony_ci    pass
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ciclass MockRawIO(MockRawIOWithoutRead):
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_ci    def read(self, n=None):
1507db96d56Sopenharmony_ci        self._reads += 1
1517db96d56Sopenharmony_ci        try:
1527db96d56Sopenharmony_ci            return self._read_stack.pop(0)
1537db96d56Sopenharmony_ci        except:
1547db96d56Sopenharmony_ci            self._extraneous_reads += 1
1557db96d56Sopenharmony_ci            return b""
1567db96d56Sopenharmony_ci
1577db96d56Sopenharmony_ciclass CMockRawIO(MockRawIO, io.RawIOBase):
1587db96d56Sopenharmony_ci    pass
1597db96d56Sopenharmony_ci
1607db96d56Sopenharmony_ciclass PyMockRawIO(MockRawIO, pyio.RawIOBase):
1617db96d56Sopenharmony_ci    pass
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci
1647db96d56Sopenharmony_ciclass MisbehavedRawIO(MockRawIO):
1657db96d56Sopenharmony_ci    def write(self, b):
1667db96d56Sopenharmony_ci        return super().write(b) * 2
1677db96d56Sopenharmony_ci
1687db96d56Sopenharmony_ci    def read(self, n=None):
1697db96d56Sopenharmony_ci        return super().read(n) * 2
1707db96d56Sopenharmony_ci
1717db96d56Sopenharmony_ci    def seek(self, pos, whence):
1727db96d56Sopenharmony_ci        return -123
1737db96d56Sopenharmony_ci
1747db96d56Sopenharmony_ci    def tell(self):
1757db96d56Sopenharmony_ci        return -456
1767db96d56Sopenharmony_ci
1777db96d56Sopenharmony_ci    def readinto(self, buf):
1787db96d56Sopenharmony_ci        super().readinto(buf)
1797db96d56Sopenharmony_ci        return len(buf) * 5
1807db96d56Sopenharmony_ci
1817db96d56Sopenharmony_ciclass CMisbehavedRawIO(MisbehavedRawIO, io.RawIOBase):
1827db96d56Sopenharmony_ci    pass
1837db96d56Sopenharmony_ci
1847db96d56Sopenharmony_ciclass PyMisbehavedRawIO(MisbehavedRawIO, pyio.RawIOBase):
1857db96d56Sopenharmony_ci    pass
1867db96d56Sopenharmony_ci
1877db96d56Sopenharmony_ci
1887db96d56Sopenharmony_ciclass SlowFlushRawIO(MockRawIO):
1897db96d56Sopenharmony_ci    def __init__(self):
1907db96d56Sopenharmony_ci        super().__init__()
1917db96d56Sopenharmony_ci        self.in_flush = threading.Event()
1927db96d56Sopenharmony_ci
1937db96d56Sopenharmony_ci    def flush(self):
1947db96d56Sopenharmony_ci        self.in_flush.set()
1957db96d56Sopenharmony_ci        time.sleep(0.25)
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_ciclass CSlowFlushRawIO(SlowFlushRawIO, io.RawIOBase):
1987db96d56Sopenharmony_ci    pass
1997db96d56Sopenharmony_ci
2007db96d56Sopenharmony_ciclass PySlowFlushRawIO(SlowFlushRawIO, pyio.RawIOBase):
2017db96d56Sopenharmony_ci    pass
2027db96d56Sopenharmony_ci
2037db96d56Sopenharmony_ci
2047db96d56Sopenharmony_ciclass CloseFailureIO(MockRawIO):
2057db96d56Sopenharmony_ci    closed = 0
2067db96d56Sopenharmony_ci
2077db96d56Sopenharmony_ci    def close(self):
2087db96d56Sopenharmony_ci        if not self.closed:
2097db96d56Sopenharmony_ci            self.closed = 1
2107db96d56Sopenharmony_ci            raise OSError
2117db96d56Sopenharmony_ci
2127db96d56Sopenharmony_ciclass CCloseFailureIO(CloseFailureIO, io.RawIOBase):
2137db96d56Sopenharmony_ci    pass
2147db96d56Sopenharmony_ci
2157db96d56Sopenharmony_ciclass PyCloseFailureIO(CloseFailureIO, pyio.RawIOBase):
2167db96d56Sopenharmony_ci    pass
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ci
2197db96d56Sopenharmony_ciclass MockFileIO:
2207db96d56Sopenharmony_ci
2217db96d56Sopenharmony_ci    def __init__(self, data):
2227db96d56Sopenharmony_ci        self.read_history = []
2237db96d56Sopenharmony_ci        super().__init__(data)
2247db96d56Sopenharmony_ci
2257db96d56Sopenharmony_ci    def read(self, n=None):
2267db96d56Sopenharmony_ci        res = super().read(n)
2277db96d56Sopenharmony_ci        self.read_history.append(None if res is None else len(res))
2287db96d56Sopenharmony_ci        return res
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci    def readinto(self, b):
2317db96d56Sopenharmony_ci        res = super().readinto(b)
2327db96d56Sopenharmony_ci        self.read_history.append(res)
2337db96d56Sopenharmony_ci        return res
2347db96d56Sopenharmony_ci
2357db96d56Sopenharmony_ciclass CMockFileIO(MockFileIO, io.BytesIO):
2367db96d56Sopenharmony_ci    pass
2377db96d56Sopenharmony_ci
2387db96d56Sopenharmony_ciclass PyMockFileIO(MockFileIO, pyio.BytesIO):
2397db96d56Sopenharmony_ci    pass
2407db96d56Sopenharmony_ci
2417db96d56Sopenharmony_ci
2427db96d56Sopenharmony_ciclass MockUnseekableIO:
2437db96d56Sopenharmony_ci    def seekable(self):
2447db96d56Sopenharmony_ci        return False
2457db96d56Sopenharmony_ci
2467db96d56Sopenharmony_ci    def seek(self, *args):
2477db96d56Sopenharmony_ci        raise self.UnsupportedOperation("not seekable")
2487db96d56Sopenharmony_ci
2497db96d56Sopenharmony_ci    def tell(self, *args):
2507db96d56Sopenharmony_ci        raise self.UnsupportedOperation("not seekable")
2517db96d56Sopenharmony_ci
2527db96d56Sopenharmony_ci    def truncate(self, *args):
2537db96d56Sopenharmony_ci        raise self.UnsupportedOperation("not seekable")
2547db96d56Sopenharmony_ci
2557db96d56Sopenharmony_ciclass CMockUnseekableIO(MockUnseekableIO, io.BytesIO):
2567db96d56Sopenharmony_ci    UnsupportedOperation = io.UnsupportedOperation
2577db96d56Sopenharmony_ci
2587db96d56Sopenharmony_ciclass PyMockUnseekableIO(MockUnseekableIO, pyio.BytesIO):
2597db96d56Sopenharmony_ci    UnsupportedOperation = pyio.UnsupportedOperation
2607db96d56Sopenharmony_ci
2617db96d56Sopenharmony_ci
2627db96d56Sopenharmony_ciclass MockNonBlockWriterIO:
2637db96d56Sopenharmony_ci
2647db96d56Sopenharmony_ci    def __init__(self):
2657db96d56Sopenharmony_ci        self._write_stack = []
2667db96d56Sopenharmony_ci        self._blocker_char = None
2677db96d56Sopenharmony_ci
2687db96d56Sopenharmony_ci    def pop_written(self):
2697db96d56Sopenharmony_ci        s = b"".join(self._write_stack)
2707db96d56Sopenharmony_ci        self._write_stack[:] = []
2717db96d56Sopenharmony_ci        return s
2727db96d56Sopenharmony_ci
2737db96d56Sopenharmony_ci    def block_on(self, char):
2747db96d56Sopenharmony_ci        """Block when a given char is encountered."""
2757db96d56Sopenharmony_ci        self._blocker_char = char
2767db96d56Sopenharmony_ci
2777db96d56Sopenharmony_ci    def readable(self):
2787db96d56Sopenharmony_ci        return True
2797db96d56Sopenharmony_ci
2807db96d56Sopenharmony_ci    def seekable(self):
2817db96d56Sopenharmony_ci        return True
2827db96d56Sopenharmony_ci
2837db96d56Sopenharmony_ci    def seek(self, pos, whence=0):
2847db96d56Sopenharmony_ci        # naive implementation, enough for tests
2857db96d56Sopenharmony_ci        return 0
2867db96d56Sopenharmony_ci
2877db96d56Sopenharmony_ci    def writable(self):
2887db96d56Sopenharmony_ci        return True
2897db96d56Sopenharmony_ci
2907db96d56Sopenharmony_ci    def write(self, b):
2917db96d56Sopenharmony_ci        b = bytes(b)
2927db96d56Sopenharmony_ci        n = -1
2937db96d56Sopenharmony_ci        if self._blocker_char:
2947db96d56Sopenharmony_ci            try:
2957db96d56Sopenharmony_ci                n = b.index(self._blocker_char)
2967db96d56Sopenharmony_ci            except ValueError:
2977db96d56Sopenharmony_ci                pass
2987db96d56Sopenharmony_ci            else:
2997db96d56Sopenharmony_ci                if n > 0:
3007db96d56Sopenharmony_ci                    # write data up to the first blocker
3017db96d56Sopenharmony_ci                    self._write_stack.append(b[:n])
3027db96d56Sopenharmony_ci                    return n
3037db96d56Sopenharmony_ci                else:
3047db96d56Sopenharmony_ci                    # cancel blocker and indicate would block
3057db96d56Sopenharmony_ci                    self._blocker_char = None
3067db96d56Sopenharmony_ci                    return None
3077db96d56Sopenharmony_ci        self._write_stack.append(b)
3087db96d56Sopenharmony_ci        return len(b)
3097db96d56Sopenharmony_ci
3107db96d56Sopenharmony_ciclass CMockNonBlockWriterIO(MockNonBlockWriterIO, io.RawIOBase):
3117db96d56Sopenharmony_ci    BlockingIOError = io.BlockingIOError
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_ciclass PyMockNonBlockWriterIO(MockNonBlockWriterIO, pyio.RawIOBase):
3147db96d56Sopenharmony_ci    BlockingIOError = pyio.BlockingIOError
3157db96d56Sopenharmony_ci
3167db96d56Sopenharmony_ci
3177db96d56Sopenharmony_ciclass IOTest(unittest.TestCase):
3187db96d56Sopenharmony_ci
3197db96d56Sopenharmony_ci    def setUp(self):
3207db96d56Sopenharmony_ci        os_helper.unlink(os_helper.TESTFN)
3217db96d56Sopenharmony_ci
3227db96d56Sopenharmony_ci    def tearDown(self):
3237db96d56Sopenharmony_ci        os_helper.unlink(os_helper.TESTFN)
3247db96d56Sopenharmony_ci
3257db96d56Sopenharmony_ci    def write_ops(self, f):
3267db96d56Sopenharmony_ci        self.assertEqual(f.write(b"blah."), 5)
3277db96d56Sopenharmony_ci        f.truncate(0)
3287db96d56Sopenharmony_ci        self.assertEqual(f.tell(), 5)
3297db96d56Sopenharmony_ci        f.seek(0)
3307db96d56Sopenharmony_ci
3317db96d56Sopenharmony_ci        self.assertEqual(f.write(b"blah."), 5)
3327db96d56Sopenharmony_ci        self.assertEqual(f.seek(0), 0)
3337db96d56Sopenharmony_ci        self.assertEqual(f.write(b"Hello."), 6)
3347db96d56Sopenharmony_ci        self.assertEqual(f.tell(), 6)
3357db96d56Sopenharmony_ci        self.assertEqual(f.seek(-1, 1), 5)
3367db96d56Sopenharmony_ci        self.assertEqual(f.tell(), 5)
3377db96d56Sopenharmony_ci        buffer = bytearray(b" world\n\n\n")
3387db96d56Sopenharmony_ci        self.assertEqual(f.write(buffer), 9)
3397db96d56Sopenharmony_ci        buffer[:] = b"*" * 9  # Overwrite our copy of the data
3407db96d56Sopenharmony_ci        self.assertEqual(f.seek(0), 0)
3417db96d56Sopenharmony_ci        self.assertEqual(f.write(b"h"), 1)
3427db96d56Sopenharmony_ci        self.assertEqual(f.seek(-1, 2), 13)
3437db96d56Sopenharmony_ci        self.assertEqual(f.tell(), 13)
3447db96d56Sopenharmony_ci
3457db96d56Sopenharmony_ci        self.assertEqual(f.truncate(12), 12)
3467db96d56Sopenharmony_ci        self.assertEqual(f.tell(), 13)
3477db96d56Sopenharmony_ci        self.assertRaises(TypeError, f.seek, 0.0)
3487db96d56Sopenharmony_ci
3497db96d56Sopenharmony_ci    def read_ops(self, f, buffered=False):
3507db96d56Sopenharmony_ci        data = f.read(5)
3517db96d56Sopenharmony_ci        self.assertEqual(data, b"hello")
3527db96d56Sopenharmony_ci        data = byteslike(data)
3537db96d56Sopenharmony_ci        self.assertEqual(f.readinto(data), 5)
3547db96d56Sopenharmony_ci        self.assertEqual(bytes(data), b" worl")
3557db96d56Sopenharmony_ci        data = bytearray(5)
3567db96d56Sopenharmony_ci        self.assertEqual(f.readinto(data), 2)
3577db96d56Sopenharmony_ci        self.assertEqual(len(data), 5)
3587db96d56Sopenharmony_ci        self.assertEqual(data[:2], b"d\n")
3597db96d56Sopenharmony_ci        self.assertEqual(f.seek(0), 0)
3607db96d56Sopenharmony_ci        self.assertEqual(f.read(20), b"hello world\n")
3617db96d56Sopenharmony_ci        self.assertEqual(f.read(1), b"")
3627db96d56Sopenharmony_ci        self.assertEqual(f.readinto(byteslike(b"x")), 0)
3637db96d56Sopenharmony_ci        self.assertEqual(f.seek(-6, 2), 6)
3647db96d56Sopenharmony_ci        self.assertEqual(f.read(5), b"world")
3657db96d56Sopenharmony_ci        self.assertEqual(f.read(0), b"")
3667db96d56Sopenharmony_ci        self.assertEqual(f.readinto(byteslike()), 0)
3677db96d56Sopenharmony_ci        self.assertEqual(f.seek(-6, 1), 5)
3687db96d56Sopenharmony_ci        self.assertEqual(f.read(5), b" worl")
3697db96d56Sopenharmony_ci        self.assertEqual(f.tell(), 10)
3707db96d56Sopenharmony_ci        self.assertRaises(TypeError, f.seek, 0.0)
3717db96d56Sopenharmony_ci        if buffered:
3727db96d56Sopenharmony_ci            f.seek(0)
3737db96d56Sopenharmony_ci            self.assertEqual(f.read(), b"hello world\n")
3747db96d56Sopenharmony_ci            f.seek(6)
3757db96d56Sopenharmony_ci            self.assertEqual(f.read(), b"world\n")
3767db96d56Sopenharmony_ci            self.assertEqual(f.read(), b"")
3777db96d56Sopenharmony_ci            f.seek(0)
3787db96d56Sopenharmony_ci            data = byteslike(5)
3797db96d56Sopenharmony_ci            self.assertEqual(f.readinto1(data), 5)
3807db96d56Sopenharmony_ci            self.assertEqual(bytes(data), b"hello")
3817db96d56Sopenharmony_ci
3827db96d56Sopenharmony_ci    LARGE = 2**31
3837db96d56Sopenharmony_ci
3847db96d56Sopenharmony_ci    def large_file_ops(self, f):
3857db96d56Sopenharmony_ci        assert f.readable()
3867db96d56Sopenharmony_ci        assert f.writable()
3877db96d56Sopenharmony_ci        try:
3887db96d56Sopenharmony_ci            self.assertEqual(f.seek(self.LARGE), self.LARGE)
3897db96d56Sopenharmony_ci        except (OverflowError, ValueError):
3907db96d56Sopenharmony_ci            self.skipTest("no largefile support")
3917db96d56Sopenharmony_ci        self.assertEqual(f.tell(), self.LARGE)
3927db96d56Sopenharmony_ci        self.assertEqual(f.write(b"xxx"), 3)
3937db96d56Sopenharmony_ci        self.assertEqual(f.tell(), self.LARGE + 3)
3947db96d56Sopenharmony_ci        self.assertEqual(f.seek(-1, 1), self.LARGE + 2)
3957db96d56Sopenharmony_ci        self.assertEqual(f.truncate(), self.LARGE + 2)
3967db96d56Sopenharmony_ci        self.assertEqual(f.tell(), self.LARGE + 2)
3977db96d56Sopenharmony_ci        self.assertEqual(f.seek(0, 2), self.LARGE + 2)
3987db96d56Sopenharmony_ci        self.assertEqual(f.truncate(self.LARGE + 1), self.LARGE + 1)
3997db96d56Sopenharmony_ci        self.assertEqual(f.tell(), self.LARGE + 2)
4007db96d56Sopenharmony_ci        self.assertEqual(f.seek(0, 2), self.LARGE + 1)
4017db96d56Sopenharmony_ci        self.assertEqual(f.seek(-1, 2), self.LARGE)
4027db96d56Sopenharmony_ci        self.assertEqual(f.read(2), b"x")
4037db96d56Sopenharmony_ci
4047db96d56Sopenharmony_ci    def test_invalid_operations(self):
4057db96d56Sopenharmony_ci        # Try writing on a file opened in read mode and vice-versa.
4067db96d56Sopenharmony_ci        exc = self.UnsupportedOperation
4077db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "w", encoding="utf-8") as fp:
4087db96d56Sopenharmony_ci            self.assertRaises(exc, fp.read)
4097db96d56Sopenharmony_ci            self.assertRaises(exc, fp.readline)
4107db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb") as fp:
4117db96d56Sopenharmony_ci            self.assertRaises(exc, fp.read)
4127db96d56Sopenharmony_ci            self.assertRaises(exc, fp.readline)
4137db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb", buffering=0) as fp:
4147db96d56Sopenharmony_ci            self.assertRaises(exc, fp.read)
4157db96d56Sopenharmony_ci            self.assertRaises(exc, fp.readline)
4167db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "rb", buffering=0) as fp:
4177db96d56Sopenharmony_ci            self.assertRaises(exc, fp.write, b"blah")
4187db96d56Sopenharmony_ci            self.assertRaises(exc, fp.writelines, [b"blah\n"])
4197db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "rb") as fp:
4207db96d56Sopenharmony_ci            self.assertRaises(exc, fp.write, b"blah")
4217db96d56Sopenharmony_ci            self.assertRaises(exc, fp.writelines, [b"blah\n"])
4227db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "r", encoding="utf-8") as fp:
4237db96d56Sopenharmony_ci            self.assertRaises(exc, fp.write, "blah")
4247db96d56Sopenharmony_ci            self.assertRaises(exc, fp.writelines, ["blah\n"])
4257db96d56Sopenharmony_ci            # Non-zero seeking from current or end pos
4267db96d56Sopenharmony_ci            self.assertRaises(exc, fp.seek, 1, self.SEEK_CUR)
4277db96d56Sopenharmony_ci            self.assertRaises(exc, fp.seek, -1, self.SEEK_END)
4287db96d56Sopenharmony_ci
4297db96d56Sopenharmony_ci    @unittest.skipIf(
4307db96d56Sopenharmony_ci        support.is_emscripten, "fstat() of a pipe fd is not supported"
4317db96d56Sopenharmony_ci    )
4327db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
4337db96d56Sopenharmony_ci    def test_optional_abilities(self):
4347db96d56Sopenharmony_ci        # Test for OSError when optional APIs are not supported
4357db96d56Sopenharmony_ci        # The purpose of this test is to try fileno(), reading, writing and
4367db96d56Sopenharmony_ci        # seeking operations with various objects that indicate they do not
4377db96d56Sopenharmony_ci        # support these operations.
4387db96d56Sopenharmony_ci
4397db96d56Sopenharmony_ci        def pipe_reader():
4407db96d56Sopenharmony_ci            [r, w] = os.pipe()
4417db96d56Sopenharmony_ci            os.close(w)  # So that read() is harmless
4427db96d56Sopenharmony_ci            return self.FileIO(r, "r")
4437db96d56Sopenharmony_ci
4447db96d56Sopenharmony_ci        def pipe_writer():
4457db96d56Sopenharmony_ci            [r, w] = os.pipe()
4467db96d56Sopenharmony_ci            self.addCleanup(os.close, r)
4477db96d56Sopenharmony_ci            # Guarantee that we can write into the pipe without blocking
4487db96d56Sopenharmony_ci            thread = threading.Thread(target=os.read, args=(r, 100))
4497db96d56Sopenharmony_ci            thread.start()
4507db96d56Sopenharmony_ci            self.addCleanup(thread.join)
4517db96d56Sopenharmony_ci            return self.FileIO(w, "w")
4527db96d56Sopenharmony_ci
4537db96d56Sopenharmony_ci        def buffered_reader():
4547db96d56Sopenharmony_ci            return self.BufferedReader(self.MockUnseekableIO())
4557db96d56Sopenharmony_ci
4567db96d56Sopenharmony_ci        def buffered_writer():
4577db96d56Sopenharmony_ci            return self.BufferedWriter(self.MockUnseekableIO())
4587db96d56Sopenharmony_ci
4597db96d56Sopenharmony_ci        def buffered_random():
4607db96d56Sopenharmony_ci            return self.BufferedRandom(self.BytesIO())
4617db96d56Sopenharmony_ci
4627db96d56Sopenharmony_ci        def buffered_rw_pair():
4637db96d56Sopenharmony_ci            return self.BufferedRWPair(self.MockUnseekableIO(),
4647db96d56Sopenharmony_ci                self.MockUnseekableIO())
4657db96d56Sopenharmony_ci
4667db96d56Sopenharmony_ci        def text_reader():
4677db96d56Sopenharmony_ci            class UnseekableReader(self.MockUnseekableIO):
4687db96d56Sopenharmony_ci                writable = self.BufferedIOBase.writable
4697db96d56Sopenharmony_ci                write = self.BufferedIOBase.write
4707db96d56Sopenharmony_ci            return self.TextIOWrapper(UnseekableReader(), "ascii")
4717db96d56Sopenharmony_ci
4727db96d56Sopenharmony_ci        def text_writer():
4737db96d56Sopenharmony_ci            class UnseekableWriter(self.MockUnseekableIO):
4747db96d56Sopenharmony_ci                readable = self.BufferedIOBase.readable
4757db96d56Sopenharmony_ci                read = self.BufferedIOBase.read
4767db96d56Sopenharmony_ci            return self.TextIOWrapper(UnseekableWriter(), "ascii")
4777db96d56Sopenharmony_ci
4787db96d56Sopenharmony_ci        tests = (
4797db96d56Sopenharmony_ci            (pipe_reader, "fr"), (pipe_writer, "fw"),
4807db96d56Sopenharmony_ci            (buffered_reader, "r"), (buffered_writer, "w"),
4817db96d56Sopenharmony_ci            (buffered_random, "rws"), (buffered_rw_pair, "rw"),
4827db96d56Sopenharmony_ci            (text_reader, "r"), (text_writer, "w"),
4837db96d56Sopenharmony_ci            (self.BytesIO, "rws"), (self.StringIO, "rws"),
4847db96d56Sopenharmony_ci        )
4857db96d56Sopenharmony_ci        for [test, abilities] in tests:
4867db96d56Sopenharmony_ci            with self.subTest(test), test() as obj:
4877db96d56Sopenharmony_ci                readable = "r" in abilities
4887db96d56Sopenharmony_ci                self.assertEqual(obj.readable(), readable)
4897db96d56Sopenharmony_ci                writable = "w" in abilities
4907db96d56Sopenharmony_ci                self.assertEqual(obj.writable(), writable)
4917db96d56Sopenharmony_ci
4927db96d56Sopenharmony_ci                if isinstance(obj, self.TextIOBase):
4937db96d56Sopenharmony_ci                    data = "3"
4947db96d56Sopenharmony_ci                elif isinstance(obj, (self.BufferedIOBase, self.RawIOBase)):
4957db96d56Sopenharmony_ci                    data = b"3"
4967db96d56Sopenharmony_ci                else:
4977db96d56Sopenharmony_ci                    self.fail("Unknown base class")
4987db96d56Sopenharmony_ci
4997db96d56Sopenharmony_ci                if "f" in abilities:
5007db96d56Sopenharmony_ci                    obj.fileno()
5017db96d56Sopenharmony_ci                else:
5027db96d56Sopenharmony_ci                    self.assertRaises(OSError, obj.fileno)
5037db96d56Sopenharmony_ci
5047db96d56Sopenharmony_ci                if readable:
5057db96d56Sopenharmony_ci                    obj.read(1)
5067db96d56Sopenharmony_ci                    obj.read()
5077db96d56Sopenharmony_ci                else:
5087db96d56Sopenharmony_ci                    self.assertRaises(OSError, obj.read, 1)
5097db96d56Sopenharmony_ci                    self.assertRaises(OSError, obj.read)
5107db96d56Sopenharmony_ci
5117db96d56Sopenharmony_ci                if writable:
5127db96d56Sopenharmony_ci                    obj.write(data)
5137db96d56Sopenharmony_ci                else:
5147db96d56Sopenharmony_ci                    self.assertRaises(OSError, obj.write, data)
5157db96d56Sopenharmony_ci
5167db96d56Sopenharmony_ci                if sys.platform.startswith("win") and test in (
5177db96d56Sopenharmony_ci                        pipe_reader, pipe_writer):
5187db96d56Sopenharmony_ci                    # Pipes seem to appear as seekable on Windows
5197db96d56Sopenharmony_ci                    continue
5207db96d56Sopenharmony_ci                seekable = "s" in abilities
5217db96d56Sopenharmony_ci                self.assertEqual(obj.seekable(), seekable)
5227db96d56Sopenharmony_ci
5237db96d56Sopenharmony_ci                if seekable:
5247db96d56Sopenharmony_ci                    obj.tell()
5257db96d56Sopenharmony_ci                    obj.seek(0)
5267db96d56Sopenharmony_ci                else:
5277db96d56Sopenharmony_ci                    self.assertRaises(OSError, obj.tell)
5287db96d56Sopenharmony_ci                    self.assertRaises(OSError, obj.seek, 0)
5297db96d56Sopenharmony_ci
5307db96d56Sopenharmony_ci                if writable and seekable:
5317db96d56Sopenharmony_ci                    obj.truncate()
5327db96d56Sopenharmony_ci                    obj.truncate(0)
5337db96d56Sopenharmony_ci                else:
5347db96d56Sopenharmony_ci                    self.assertRaises(OSError, obj.truncate)
5357db96d56Sopenharmony_ci                    self.assertRaises(OSError, obj.truncate, 0)
5367db96d56Sopenharmony_ci
5377db96d56Sopenharmony_ci    def test_open_handles_NUL_chars(self):
5387db96d56Sopenharmony_ci        fn_with_NUL = 'foo\0bar'
5397db96d56Sopenharmony_ci        self.assertRaises(ValueError, self.open, fn_with_NUL, 'w', encoding="utf-8")
5407db96d56Sopenharmony_ci
5417db96d56Sopenharmony_ci        bytes_fn = bytes(fn_with_NUL, 'ascii')
5427db96d56Sopenharmony_ci        with warnings.catch_warnings():
5437db96d56Sopenharmony_ci            warnings.simplefilter("ignore", DeprecationWarning)
5447db96d56Sopenharmony_ci            self.assertRaises(ValueError, self.open, bytes_fn, 'w', encoding="utf-8")
5457db96d56Sopenharmony_ci
5467db96d56Sopenharmony_ci    def test_raw_file_io(self):
5477db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb", buffering=0) as f:
5487db96d56Sopenharmony_ci            self.assertEqual(f.readable(), False)
5497db96d56Sopenharmony_ci            self.assertEqual(f.writable(), True)
5507db96d56Sopenharmony_ci            self.assertEqual(f.seekable(), True)
5517db96d56Sopenharmony_ci            self.write_ops(f)
5527db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "rb", buffering=0) as f:
5537db96d56Sopenharmony_ci            self.assertEqual(f.readable(), True)
5547db96d56Sopenharmony_ci            self.assertEqual(f.writable(), False)
5557db96d56Sopenharmony_ci            self.assertEqual(f.seekable(), True)
5567db96d56Sopenharmony_ci            self.read_ops(f)
5577db96d56Sopenharmony_ci
5587db96d56Sopenharmony_ci    def test_buffered_file_io(self):
5597db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb") as f:
5607db96d56Sopenharmony_ci            self.assertEqual(f.readable(), False)
5617db96d56Sopenharmony_ci            self.assertEqual(f.writable(), True)
5627db96d56Sopenharmony_ci            self.assertEqual(f.seekable(), True)
5637db96d56Sopenharmony_ci            self.write_ops(f)
5647db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "rb") as f:
5657db96d56Sopenharmony_ci            self.assertEqual(f.readable(), True)
5667db96d56Sopenharmony_ci            self.assertEqual(f.writable(), False)
5677db96d56Sopenharmony_ci            self.assertEqual(f.seekable(), True)
5687db96d56Sopenharmony_ci            self.read_ops(f, True)
5697db96d56Sopenharmony_ci
5707db96d56Sopenharmony_ci    def test_readline(self):
5717db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb") as f:
5727db96d56Sopenharmony_ci            f.write(b"abc\ndef\nxyzzy\nfoo\x00bar\nanother line")
5737db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "rb") as f:
5747db96d56Sopenharmony_ci            self.assertEqual(f.readline(), b"abc\n")
5757db96d56Sopenharmony_ci            self.assertEqual(f.readline(10), b"def\n")
5767db96d56Sopenharmony_ci            self.assertEqual(f.readline(2), b"xy")
5777db96d56Sopenharmony_ci            self.assertEqual(f.readline(4), b"zzy\n")
5787db96d56Sopenharmony_ci            self.assertEqual(f.readline(), b"foo\x00bar\n")
5797db96d56Sopenharmony_ci            self.assertEqual(f.readline(None), b"another line")
5807db96d56Sopenharmony_ci            self.assertRaises(TypeError, f.readline, 5.3)
5817db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "r", encoding="utf-8") as f:
5827db96d56Sopenharmony_ci            self.assertRaises(TypeError, f.readline, 5.3)
5837db96d56Sopenharmony_ci
5847db96d56Sopenharmony_ci    def test_readline_nonsizeable(self):
5857db96d56Sopenharmony_ci        # Issue #30061
5867db96d56Sopenharmony_ci        # Crash when readline() returns an object without __len__
5877db96d56Sopenharmony_ci        class R(self.IOBase):
5887db96d56Sopenharmony_ci            def readline(self):
5897db96d56Sopenharmony_ci                return None
5907db96d56Sopenharmony_ci        self.assertRaises((TypeError, StopIteration), next, R())
5917db96d56Sopenharmony_ci
5927db96d56Sopenharmony_ci    def test_next_nonsizeable(self):
5937db96d56Sopenharmony_ci        # Issue #30061
5947db96d56Sopenharmony_ci        # Crash when __next__() returns an object without __len__
5957db96d56Sopenharmony_ci        class R(self.IOBase):
5967db96d56Sopenharmony_ci            def __next__(self):
5977db96d56Sopenharmony_ci                return None
5987db96d56Sopenharmony_ci        self.assertRaises(TypeError, R().readlines, 1)
5997db96d56Sopenharmony_ci
6007db96d56Sopenharmony_ci    def test_raw_bytes_io(self):
6017db96d56Sopenharmony_ci        f = self.BytesIO()
6027db96d56Sopenharmony_ci        self.write_ops(f)
6037db96d56Sopenharmony_ci        data = f.getvalue()
6047db96d56Sopenharmony_ci        self.assertEqual(data, b"hello world\n")
6057db96d56Sopenharmony_ci        f = self.BytesIO(data)
6067db96d56Sopenharmony_ci        self.read_ops(f, True)
6077db96d56Sopenharmony_ci
6087db96d56Sopenharmony_ci    def test_large_file_ops(self):
6097db96d56Sopenharmony_ci        # On Windows and Mac OSX this test consumes large resources; It takes
6107db96d56Sopenharmony_ci        # a long time to build the >2 GiB file and takes >2 GiB of disk space
6117db96d56Sopenharmony_ci        # therefore the resource must be enabled to run this test.
6127db96d56Sopenharmony_ci        if sys.platform[:3] == 'win' or sys.platform == 'darwin':
6137db96d56Sopenharmony_ci            support.requires(
6147db96d56Sopenharmony_ci                'largefile',
6157db96d56Sopenharmony_ci                'test requires %s bytes and a long time to run' % self.LARGE)
6167db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "w+b", 0) as f:
6177db96d56Sopenharmony_ci            self.large_file_ops(f)
6187db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "w+b") as f:
6197db96d56Sopenharmony_ci            self.large_file_ops(f)
6207db96d56Sopenharmony_ci
6217db96d56Sopenharmony_ci    def test_with_open(self):
6227db96d56Sopenharmony_ci        for bufsize in (0, 100):
6237db96d56Sopenharmony_ci            f = None
6247db96d56Sopenharmony_ci            with self.open(os_helper.TESTFN, "wb", bufsize) as f:
6257db96d56Sopenharmony_ci                f.write(b"xxx")
6267db96d56Sopenharmony_ci            self.assertEqual(f.closed, True)
6277db96d56Sopenharmony_ci            f = None
6287db96d56Sopenharmony_ci            try:
6297db96d56Sopenharmony_ci                with self.open(os_helper.TESTFN, "wb", bufsize) as f:
6307db96d56Sopenharmony_ci                    1/0
6317db96d56Sopenharmony_ci            except ZeroDivisionError:
6327db96d56Sopenharmony_ci                self.assertEqual(f.closed, True)
6337db96d56Sopenharmony_ci            else:
6347db96d56Sopenharmony_ci                self.fail("1/0 didn't raise an exception")
6357db96d56Sopenharmony_ci
6367db96d56Sopenharmony_ci    # issue 5008
6377db96d56Sopenharmony_ci    def test_append_mode_tell(self):
6387db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb") as f:
6397db96d56Sopenharmony_ci            f.write(b"xxx")
6407db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "ab", buffering=0) as f:
6417db96d56Sopenharmony_ci            self.assertEqual(f.tell(), 3)
6427db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "ab") as f:
6437db96d56Sopenharmony_ci            self.assertEqual(f.tell(), 3)
6447db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "a", encoding="utf-8") as f:
6457db96d56Sopenharmony_ci            self.assertGreater(f.tell(), 0)
6467db96d56Sopenharmony_ci
6477db96d56Sopenharmony_ci    def test_destructor(self):
6487db96d56Sopenharmony_ci        record = []
6497db96d56Sopenharmony_ci        class MyFileIO(self.FileIO):
6507db96d56Sopenharmony_ci            def __del__(self):
6517db96d56Sopenharmony_ci                record.append(1)
6527db96d56Sopenharmony_ci                try:
6537db96d56Sopenharmony_ci                    f = super().__del__
6547db96d56Sopenharmony_ci                except AttributeError:
6557db96d56Sopenharmony_ci                    pass
6567db96d56Sopenharmony_ci                else:
6577db96d56Sopenharmony_ci                    f()
6587db96d56Sopenharmony_ci            def close(self):
6597db96d56Sopenharmony_ci                record.append(2)
6607db96d56Sopenharmony_ci                super().close()
6617db96d56Sopenharmony_ci            def flush(self):
6627db96d56Sopenharmony_ci                record.append(3)
6637db96d56Sopenharmony_ci                super().flush()
6647db96d56Sopenharmony_ci        with warnings_helper.check_warnings(('', ResourceWarning)):
6657db96d56Sopenharmony_ci            f = MyFileIO(os_helper.TESTFN, "wb")
6667db96d56Sopenharmony_ci            f.write(b"xxx")
6677db96d56Sopenharmony_ci            del f
6687db96d56Sopenharmony_ci            support.gc_collect()
6697db96d56Sopenharmony_ci            self.assertEqual(record, [1, 2, 3])
6707db96d56Sopenharmony_ci            with self.open(os_helper.TESTFN, "rb") as f:
6717db96d56Sopenharmony_ci                self.assertEqual(f.read(), b"xxx")
6727db96d56Sopenharmony_ci
6737db96d56Sopenharmony_ci    def _check_base_destructor(self, base):
6747db96d56Sopenharmony_ci        record = []
6757db96d56Sopenharmony_ci        class MyIO(base):
6767db96d56Sopenharmony_ci            def __init__(self):
6777db96d56Sopenharmony_ci                # This exercises the availability of attributes on object
6787db96d56Sopenharmony_ci                # destruction.
6797db96d56Sopenharmony_ci                # (in the C version, close() is called by the tp_dealloc
6807db96d56Sopenharmony_ci                # function, not by __del__)
6817db96d56Sopenharmony_ci                self.on_del = 1
6827db96d56Sopenharmony_ci                self.on_close = 2
6837db96d56Sopenharmony_ci                self.on_flush = 3
6847db96d56Sopenharmony_ci            def __del__(self):
6857db96d56Sopenharmony_ci                record.append(self.on_del)
6867db96d56Sopenharmony_ci                try:
6877db96d56Sopenharmony_ci                    f = super().__del__
6887db96d56Sopenharmony_ci                except AttributeError:
6897db96d56Sopenharmony_ci                    pass
6907db96d56Sopenharmony_ci                else:
6917db96d56Sopenharmony_ci                    f()
6927db96d56Sopenharmony_ci            def close(self):
6937db96d56Sopenharmony_ci                record.append(self.on_close)
6947db96d56Sopenharmony_ci                super().close()
6957db96d56Sopenharmony_ci            def flush(self):
6967db96d56Sopenharmony_ci                record.append(self.on_flush)
6977db96d56Sopenharmony_ci                super().flush()
6987db96d56Sopenharmony_ci        f = MyIO()
6997db96d56Sopenharmony_ci        del f
7007db96d56Sopenharmony_ci        support.gc_collect()
7017db96d56Sopenharmony_ci        self.assertEqual(record, [1, 2, 3])
7027db96d56Sopenharmony_ci
7037db96d56Sopenharmony_ci    def test_IOBase_destructor(self):
7047db96d56Sopenharmony_ci        self._check_base_destructor(self.IOBase)
7057db96d56Sopenharmony_ci
7067db96d56Sopenharmony_ci    def test_RawIOBase_destructor(self):
7077db96d56Sopenharmony_ci        self._check_base_destructor(self.RawIOBase)
7087db96d56Sopenharmony_ci
7097db96d56Sopenharmony_ci    def test_BufferedIOBase_destructor(self):
7107db96d56Sopenharmony_ci        self._check_base_destructor(self.BufferedIOBase)
7117db96d56Sopenharmony_ci
7127db96d56Sopenharmony_ci    def test_TextIOBase_destructor(self):
7137db96d56Sopenharmony_ci        self._check_base_destructor(self.TextIOBase)
7147db96d56Sopenharmony_ci
7157db96d56Sopenharmony_ci    def test_close_flushes(self):
7167db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb") as f:
7177db96d56Sopenharmony_ci            f.write(b"xxx")
7187db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "rb") as f:
7197db96d56Sopenharmony_ci            self.assertEqual(f.read(), b"xxx")
7207db96d56Sopenharmony_ci
7217db96d56Sopenharmony_ci    def test_array_writes(self):
7227db96d56Sopenharmony_ci        a = array.array('i', range(10))
7237db96d56Sopenharmony_ci        n = len(a.tobytes())
7247db96d56Sopenharmony_ci        def check(f):
7257db96d56Sopenharmony_ci            with f:
7267db96d56Sopenharmony_ci                self.assertEqual(f.write(a), n)
7277db96d56Sopenharmony_ci                f.writelines((a,))
7287db96d56Sopenharmony_ci        check(self.BytesIO())
7297db96d56Sopenharmony_ci        check(self.FileIO(os_helper.TESTFN, "w"))
7307db96d56Sopenharmony_ci        check(self.BufferedWriter(self.MockRawIO()))
7317db96d56Sopenharmony_ci        check(self.BufferedRandom(self.MockRawIO()))
7327db96d56Sopenharmony_ci        check(self.BufferedRWPair(self.MockRawIO(), self.MockRawIO()))
7337db96d56Sopenharmony_ci
7347db96d56Sopenharmony_ci    def test_closefd(self):
7357db96d56Sopenharmony_ci        self.assertRaises(ValueError, self.open, os_helper.TESTFN, 'w',
7367db96d56Sopenharmony_ci                          encoding="utf-8", closefd=False)
7377db96d56Sopenharmony_ci
7387db96d56Sopenharmony_ci    def test_read_closed(self):
7397db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "w", encoding="utf-8") as f:
7407db96d56Sopenharmony_ci            f.write("egg\n")
7417db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "r", encoding="utf-8") as f:
7427db96d56Sopenharmony_ci            file = self.open(f.fileno(), "r", encoding="utf-8", closefd=False)
7437db96d56Sopenharmony_ci            self.assertEqual(file.read(), "egg\n")
7447db96d56Sopenharmony_ci            file.seek(0)
7457db96d56Sopenharmony_ci            file.close()
7467db96d56Sopenharmony_ci            self.assertRaises(ValueError, file.read)
7477db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "rb") as f:
7487db96d56Sopenharmony_ci            file = self.open(f.fileno(), "rb", closefd=False)
7497db96d56Sopenharmony_ci            self.assertEqual(file.read()[:3], b"egg")
7507db96d56Sopenharmony_ci            file.close()
7517db96d56Sopenharmony_ci            self.assertRaises(ValueError, file.readinto, bytearray(1))
7527db96d56Sopenharmony_ci
7537db96d56Sopenharmony_ci    def test_no_closefd_with_filename(self):
7547db96d56Sopenharmony_ci        # can't use closefd in combination with a file name
7557db96d56Sopenharmony_ci        self.assertRaises(ValueError, self.open, os_helper.TESTFN, "r",
7567db96d56Sopenharmony_ci                          encoding="utf-8", closefd=False)
7577db96d56Sopenharmony_ci
7587db96d56Sopenharmony_ci    def test_closefd_attr(self):
7597db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb") as f:
7607db96d56Sopenharmony_ci            f.write(b"egg\n")
7617db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "r", encoding="utf-8") as f:
7627db96d56Sopenharmony_ci            self.assertEqual(f.buffer.raw.closefd, True)
7637db96d56Sopenharmony_ci            file = self.open(f.fileno(), "r", encoding="utf-8", closefd=False)
7647db96d56Sopenharmony_ci            self.assertEqual(file.buffer.raw.closefd, False)
7657db96d56Sopenharmony_ci
7667db96d56Sopenharmony_ci    def test_garbage_collection(self):
7677db96d56Sopenharmony_ci        # FileIO objects are collected, and collecting them flushes
7687db96d56Sopenharmony_ci        # all data to disk.
7697db96d56Sopenharmony_ci        with warnings_helper.check_warnings(('', ResourceWarning)):
7707db96d56Sopenharmony_ci            f = self.FileIO(os_helper.TESTFN, "wb")
7717db96d56Sopenharmony_ci            f.write(b"abcxxx")
7727db96d56Sopenharmony_ci            f.f = f
7737db96d56Sopenharmony_ci            wr = weakref.ref(f)
7747db96d56Sopenharmony_ci            del f
7757db96d56Sopenharmony_ci            support.gc_collect()
7767db96d56Sopenharmony_ci        self.assertIsNone(wr(), wr)
7777db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "rb") as f:
7787db96d56Sopenharmony_ci            self.assertEqual(f.read(), b"abcxxx")
7797db96d56Sopenharmony_ci
7807db96d56Sopenharmony_ci    def test_unbounded_file(self):
7817db96d56Sopenharmony_ci        # Issue #1174606: reading from an unbounded stream such as /dev/zero.
7827db96d56Sopenharmony_ci        zero = "/dev/zero"
7837db96d56Sopenharmony_ci        if not os.path.exists(zero):
7847db96d56Sopenharmony_ci            self.skipTest("{0} does not exist".format(zero))
7857db96d56Sopenharmony_ci        if sys.maxsize > 0x7FFFFFFF:
7867db96d56Sopenharmony_ci            self.skipTest("test can only run in a 32-bit address space")
7877db96d56Sopenharmony_ci        if support.real_max_memuse < support._2G:
7887db96d56Sopenharmony_ci            self.skipTest("test requires at least 2 GiB of memory")
7897db96d56Sopenharmony_ci        with self.open(zero, "rb", buffering=0) as f:
7907db96d56Sopenharmony_ci            self.assertRaises(OverflowError, f.read)
7917db96d56Sopenharmony_ci        with self.open(zero, "rb") as f:
7927db96d56Sopenharmony_ci            self.assertRaises(OverflowError, f.read)
7937db96d56Sopenharmony_ci        with self.open(zero, "r") as f:
7947db96d56Sopenharmony_ci            self.assertRaises(OverflowError, f.read)
7957db96d56Sopenharmony_ci
7967db96d56Sopenharmony_ci    def check_flush_error_on_close(self, *args, **kwargs):
7977db96d56Sopenharmony_ci        # Test that the file is closed despite failed flush
7987db96d56Sopenharmony_ci        # and that flush() is called before file closed.
7997db96d56Sopenharmony_ci        f = self.open(*args, **kwargs)
8007db96d56Sopenharmony_ci        closed = []
8017db96d56Sopenharmony_ci        def bad_flush():
8027db96d56Sopenharmony_ci            closed[:] = [f.closed]
8037db96d56Sopenharmony_ci            raise OSError()
8047db96d56Sopenharmony_ci        f.flush = bad_flush
8057db96d56Sopenharmony_ci        self.assertRaises(OSError, f.close) # exception not swallowed
8067db96d56Sopenharmony_ci        self.assertTrue(f.closed)
8077db96d56Sopenharmony_ci        self.assertTrue(closed)      # flush() called
8087db96d56Sopenharmony_ci        self.assertFalse(closed[0])  # flush() called before file closed
8097db96d56Sopenharmony_ci        f.flush = lambda: None  # break reference loop
8107db96d56Sopenharmony_ci
8117db96d56Sopenharmony_ci    def test_flush_error_on_close(self):
8127db96d56Sopenharmony_ci        # raw file
8137db96d56Sopenharmony_ci        # Issue #5700: io.FileIO calls flush() after file closed
8147db96d56Sopenharmony_ci        self.check_flush_error_on_close(os_helper.TESTFN, 'wb', buffering=0)
8157db96d56Sopenharmony_ci        fd = os.open(os_helper.TESTFN, os.O_WRONLY|os.O_CREAT)
8167db96d56Sopenharmony_ci        self.check_flush_error_on_close(fd, 'wb', buffering=0)
8177db96d56Sopenharmony_ci        fd = os.open(os_helper.TESTFN, os.O_WRONLY|os.O_CREAT)
8187db96d56Sopenharmony_ci        self.check_flush_error_on_close(fd, 'wb', buffering=0, closefd=False)
8197db96d56Sopenharmony_ci        os.close(fd)
8207db96d56Sopenharmony_ci        # buffered io
8217db96d56Sopenharmony_ci        self.check_flush_error_on_close(os_helper.TESTFN, 'wb')
8227db96d56Sopenharmony_ci        fd = os.open(os_helper.TESTFN, os.O_WRONLY|os.O_CREAT)
8237db96d56Sopenharmony_ci        self.check_flush_error_on_close(fd, 'wb')
8247db96d56Sopenharmony_ci        fd = os.open(os_helper.TESTFN, os.O_WRONLY|os.O_CREAT)
8257db96d56Sopenharmony_ci        self.check_flush_error_on_close(fd, 'wb', closefd=False)
8267db96d56Sopenharmony_ci        os.close(fd)
8277db96d56Sopenharmony_ci        # text io
8287db96d56Sopenharmony_ci        self.check_flush_error_on_close(os_helper.TESTFN, 'w', encoding="utf-8")
8297db96d56Sopenharmony_ci        fd = os.open(os_helper.TESTFN, os.O_WRONLY|os.O_CREAT)
8307db96d56Sopenharmony_ci        self.check_flush_error_on_close(fd, 'w', encoding="utf-8")
8317db96d56Sopenharmony_ci        fd = os.open(os_helper.TESTFN, os.O_WRONLY|os.O_CREAT)
8327db96d56Sopenharmony_ci        self.check_flush_error_on_close(fd, 'w', encoding="utf-8", closefd=False)
8337db96d56Sopenharmony_ci        os.close(fd)
8347db96d56Sopenharmony_ci
8357db96d56Sopenharmony_ci    def test_multi_close(self):
8367db96d56Sopenharmony_ci        f = self.open(os_helper.TESTFN, "wb", buffering=0)
8377db96d56Sopenharmony_ci        f.close()
8387db96d56Sopenharmony_ci        f.close()
8397db96d56Sopenharmony_ci        f.close()
8407db96d56Sopenharmony_ci        self.assertRaises(ValueError, f.flush)
8417db96d56Sopenharmony_ci
8427db96d56Sopenharmony_ci    def test_RawIOBase_read(self):
8437db96d56Sopenharmony_ci        # Exercise the default limited RawIOBase.read(n) implementation (which
8447db96d56Sopenharmony_ci        # calls readinto() internally).
8457db96d56Sopenharmony_ci        rawio = self.MockRawIOWithoutRead((b"abc", b"d", None, b"efg", None))
8467db96d56Sopenharmony_ci        self.assertEqual(rawio.read(2), b"ab")
8477db96d56Sopenharmony_ci        self.assertEqual(rawio.read(2), b"c")
8487db96d56Sopenharmony_ci        self.assertEqual(rawio.read(2), b"d")
8497db96d56Sopenharmony_ci        self.assertEqual(rawio.read(2), None)
8507db96d56Sopenharmony_ci        self.assertEqual(rawio.read(2), b"ef")
8517db96d56Sopenharmony_ci        self.assertEqual(rawio.read(2), b"g")
8527db96d56Sopenharmony_ci        self.assertEqual(rawio.read(2), None)
8537db96d56Sopenharmony_ci        self.assertEqual(rawio.read(2), b"")
8547db96d56Sopenharmony_ci
8557db96d56Sopenharmony_ci    def test_types_have_dict(self):
8567db96d56Sopenharmony_ci        test = (
8577db96d56Sopenharmony_ci            self.IOBase(),
8587db96d56Sopenharmony_ci            self.RawIOBase(),
8597db96d56Sopenharmony_ci            self.TextIOBase(),
8607db96d56Sopenharmony_ci            self.StringIO(),
8617db96d56Sopenharmony_ci            self.BytesIO()
8627db96d56Sopenharmony_ci        )
8637db96d56Sopenharmony_ci        for obj in test:
8647db96d56Sopenharmony_ci            self.assertTrue(hasattr(obj, "__dict__"))
8657db96d56Sopenharmony_ci
8667db96d56Sopenharmony_ci    def test_opener(self):
8677db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "w", encoding="utf-8") as f:
8687db96d56Sopenharmony_ci            f.write("egg\n")
8697db96d56Sopenharmony_ci        fd = os.open(os_helper.TESTFN, os.O_RDONLY)
8707db96d56Sopenharmony_ci        def opener(path, flags):
8717db96d56Sopenharmony_ci            return fd
8727db96d56Sopenharmony_ci        with self.open("non-existent", "r", encoding="utf-8", opener=opener) as f:
8737db96d56Sopenharmony_ci            self.assertEqual(f.read(), "egg\n")
8747db96d56Sopenharmony_ci
8757db96d56Sopenharmony_ci    def test_bad_opener_negative_1(self):
8767db96d56Sopenharmony_ci        # Issue #27066.
8777db96d56Sopenharmony_ci        def badopener(fname, flags):
8787db96d56Sopenharmony_ci            return -1
8797db96d56Sopenharmony_ci        with self.assertRaises(ValueError) as cm:
8807db96d56Sopenharmony_ci            open('non-existent', 'r', opener=badopener)
8817db96d56Sopenharmony_ci        self.assertEqual(str(cm.exception), 'opener returned -1')
8827db96d56Sopenharmony_ci
8837db96d56Sopenharmony_ci    def test_bad_opener_other_negative(self):
8847db96d56Sopenharmony_ci        # Issue #27066.
8857db96d56Sopenharmony_ci        def badopener(fname, flags):
8867db96d56Sopenharmony_ci            return -2
8877db96d56Sopenharmony_ci        with self.assertRaises(ValueError) as cm:
8887db96d56Sopenharmony_ci            open('non-existent', 'r', opener=badopener)
8897db96d56Sopenharmony_ci        self.assertEqual(str(cm.exception), 'opener returned -2')
8907db96d56Sopenharmony_ci
8917db96d56Sopenharmony_ci    def test_opener_invalid_fd(self):
8927db96d56Sopenharmony_ci        # Check that OSError is raised with error code EBADF if the
8937db96d56Sopenharmony_ci        # opener returns an invalid file descriptor (see gh-82212).
8947db96d56Sopenharmony_ci        fd = os_helper.make_bad_fd()
8957db96d56Sopenharmony_ci        with self.assertRaises(OSError) as cm:
8967db96d56Sopenharmony_ci            self.open('foo', opener=lambda name, flags: fd)
8977db96d56Sopenharmony_ci        self.assertEqual(cm.exception.errno, errno.EBADF)
8987db96d56Sopenharmony_ci
8997db96d56Sopenharmony_ci    def test_fileio_closefd(self):
9007db96d56Sopenharmony_ci        # Issue #4841
9017db96d56Sopenharmony_ci        with self.open(__file__, 'rb') as f1, \
9027db96d56Sopenharmony_ci             self.open(__file__, 'rb') as f2:
9037db96d56Sopenharmony_ci            fileio = self.FileIO(f1.fileno(), closefd=False)
9047db96d56Sopenharmony_ci            # .__init__() must not close f1
9057db96d56Sopenharmony_ci            fileio.__init__(f2.fileno(), closefd=False)
9067db96d56Sopenharmony_ci            f1.readline()
9077db96d56Sopenharmony_ci            # .close() must not close f2
9087db96d56Sopenharmony_ci            fileio.close()
9097db96d56Sopenharmony_ci            f2.readline()
9107db96d56Sopenharmony_ci
9117db96d56Sopenharmony_ci    def test_nonbuffered_textio(self):
9127db96d56Sopenharmony_ci        with warnings_helper.check_no_resource_warning(self):
9137db96d56Sopenharmony_ci            with self.assertRaises(ValueError):
9147db96d56Sopenharmony_ci                self.open(os_helper.TESTFN, 'w', encoding="utf-8", buffering=0)
9157db96d56Sopenharmony_ci
9167db96d56Sopenharmony_ci    def test_invalid_newline(self):
9177db96d56Sopenharmony_ci        with warnings_helper.check_no_resource_warning(self):
9187db96d56Sopenharmony_ci            with self.assertRaises(ValueError):
9197db96d56Sopenharmony_ci                self.open(os_helper.TESTFN, 'w', encoding="utf-8", newline='invalid')
9207db96d56Sopenharmony_ci
9217db96d56Sopenharmony_ci    def test_buffered_readinto_mixin(self):
9227db96d56Sopenharmony_ci        # Test the implementation provided by BufferedIOBase
9237db96d56Sopenharmony_ci        class Stream(self.BufferedIOBase):
9247db96d56Sopenharmony_ci            def read(self, size):
9257db96d56Sopenharmony_ci                return b"12345"
9267db96d56Sopenharmony_ci            read1 = read
9277db96d56Sopenharmony_ci        stream = Stream()
9287db96d56Sopenharmony_ci        for method in ("readinto", "readinto1"):
9297db96d56Sopenharmony_ci            with self.subTest(method):
9307db96d56Sopenharmony_ci                buffer = byteslike(5)
9317db96d56Sopenharmony_ci                self.assertEqual(getattr(stream, method)(buffer), 5)
9327db96d56Sopenharmony_ci                self.assertEqual(bytes(buffer), b"12345")
9337db96d56Sopenharmony_ci
9347db96d56Sopenharmony_ci    def test_fspath_support(self):
9357db96d56Sopenharmony_ci        def check_path_succeeds(path):
9367db96d56Sopenharmony_ci            with self.open(path, "w", encoding="utf-8") as f:
9377db96d56Sopenharmony_ci                f.write("egg\n")
9387db96d56Sopenharmony_ci
9397db96d56Sopenharmony_ci            with self.open(path, "r", encoding="utf-8") as f:
9407db96d56Sopenharmony_ci                self.assertEqual(f.read(), "egg\n")
9417db96d56Sopenharmony_ci
9427db96d56Sopenharmony_ci        check_path_succeeds(FakePath(os_helper.TESTFN))
9437db96d56Sopenharmony_ci        check_path_succeeds(FakePath(os.fsencode(os_helper.TESTFN)))
9447db96d56Sopenharmony_ci
9457db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "w", encoding="utf-8") as f:
9467db96d56Sopenharmony_ci            bad_path = FakePath(f.fileno())
9477db96d56Sopenharmony_ci            with self.assertRaises(TypeError):
9487db96d56Sopenharmony_ci                self.open(bad_path, 'w', encoding="utf-8")
9497db96d56Sopenharmony_ci
9507db96d56Sopenharmony_ci        bad_path = FakePath(None)
9517db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
9527db96d56Sopenharmony_ci            self.open(bad_path, 'w', encoding="utf-8")
9537db96d56Sopenharmony_ci
9547db96d56Sopenharmony_ci        bad_path = FakePath(FloatingPointError)
9557db96d56Sopenharmony_ci        with self.assertRaises(FloatingPointError):
9567db96d56Sopenharmony_ci            self.open(bad_path, 'w', encoding="utf-8")
9577db96d56Sopenharmony_ci
9587db96d56Sopenharmony_ci        # ensure that refcounting is correct with some error conditions
9597db96d56Sopenharmony_ci        with self.assertRaisesRegex(ValueError, 'read/write/append mode'):
9607db96d56Sopenharmony_ci            self.open(FakePath(os_helper.TESTFN), 'rwxa', encoding="utf-8")
9617db96d56Sopenharmony_ci
9627db96d56Sopenharmony_ci    def test_RawIOBase_readall(self):
9637db96d56Sopenharmony_ci        # Exercise the default unlimited RawIOBase.read() and readall()
9647db96d56Sopenharmony_ci        # implementations.
9657db96d56Sopenharmony_ci        rawio = self.MockRawIOWithoutRead((b"abc", b"d", b"efg"))
9667db96d56Sopenharmony_ci        self.assertEqual(rawio.read(), b"abcdefg")
9677db96d56Sopenharmony_ci        rawio = self.MockRawIOWithoutRead((b"abc", b"d", b"efg"))
9687db96d56Sopenharmony_ci        self.assertEqual(rawio.readall(), b"abcdefg")
9697db96d56Sopenharmony_ci
9707db96d56Sopenharmony_ci    def test_BufferedIOBase_readinto(self):
9717db96d56Sopenharmony_ci        # Exercise the default BufferedIOBase.readinto() and readinto1()
9727db96d56Sopenharmony_ci        # implementations (which call read() or read1() internally).
9737db96d56Sopenharmony_ci        class Reader(self.BufferedIOBase):
9747db96d56Sopenharmony_ci            def __init__(self, avail):
9757db96d56Sopenharmony_ci                self.avail = avail
9767db96d56Sopenharmony_ci            def read(self, size):
9777db96d56Sopenharmony_ci                result = self.avail[:size]
9787db96d56Sopenharmony_ci                self.avail = self.avail[size:]
9797db96d56Sopenharmony_ci                return result
9807db96d56Sopenharmony_ci            def read1(self, size):
9817db96d56Sopenharmony_ci                """Returns no more than 5 bytes at once"""
9827db96d56Sopenharmony_ci                return self.read(min(size, 5))
9837db96d56Sopenharmony_ci        tests = (
9847db96d56Sopenharmony_ci            # (test method, total data available, read buffer size, expected
9857db96d56Sopenharmony_ci            #     read size)
9867db96d56Sopenharmony_ci            ("readinto", 10, 5, 5),
9877db96d56Sopenharmony_ci            ("readinto", 10, 6, 6),  # More than read1() can return
9887db96d56Sopenharmony_ci            ("readinto", 5, 6, 5),  # Buffer larger than total available
9897db96d56Sopenharmony_ci            ("readinto", 6, 7, 6),
9907db96d56Sopenharmony_ci            ("readinto", 10, 0, 0),  # Empty buffer
9917db96d56Sopenharmony_ci            ("readinto1", 10, 5, 5),  # Result limited to single read1() call
9927db96d56Sopenharmony_ci            ("readinto1", 10, 6, 5),  # Buffer larger than read1() can return
9937db96d56Sopenharmony_ci            ("readinto1", 5, 6, 5),  # Buffer larger than total available
9947db96d56Sopenharmony_ci            ("readinto1", 6, 7, 5),
9957db96d56Sopenharmony_ci            ("readinto1", 10, 0, 0),  # Empty buffer
9967db96d56Sopenharmony_ci        )
9977db96d56Sopenharmony_ci        UNUSED_BYTE = 0x81
9987db96d56Sopenharmony_ci        for test in tests:
9997db96d56Sopenharmony_ci            with self.subTest(test):
10007db96d56Sopenharmony_ci                method, avail, request, result = test
10017db96d56Sopenharmony_ci                reader = Reader(bytes(range(avail)))
10027db96d56Sopenharmony_ci                buffer = bytearray((UNUSED_BYTE,) * request)
10037db96d56Sopenharmony_ci                method = getattr(reader, method)
10047db96d56Sopenharmony_ci                self.assertEqual(method(buffer), result)
10057db96d56Sopenharmony_ci                self.assertEqual(len(buffer), request)
10067db96d56Sopenharmony_ci                self.assertSequenceEqual(buffer[:result], range(result))
10077db96d56Sopenharmony_ci                unused = (UNUSED_BYTE,) * (request - result)
10087db96d56Sopenharmony_ci                self.assertSequenceEqual(buffer[result:], unused)
10097db96d56Sopenharmony_ci                self.assertEqual(len(reader.avail), avail - result)
10107db96d56Sopenharmony_ci
10117db96d56Sopenharmony_ci    def test_close_assert(self):
10127db96d56Sopenharmony_ci        class R(self.IOBase):
10137db96d56Sopenharmony_ci            def __setattr__(self, name, value):
10147db96d56Sopenharmony_ci                pass
10157db96d56Sopenharmony_ci            def flush(self):
10167db96d56Sopenharmony_ci                raise OSError()
10177db96d56Sopenharmony_ci        f = R()
10187db96d56Sopenharmony_ci        # This would cause an assertion failure.
10197db96d56Sopenharmony_ci        self.assertRaises(OSError, f.close)
10207db96d56Sopenharmony_ci
10217db96d56Sopenharmony_ci        # Silence destructor error
10227db96d56Sopenharmony_ci        R.flush = lambda self: None
10237db96d56Sopenharmony_ci
10247db96d56Sopenharmony_ci
10257db96d56Sopenharmony_ciclass CIOTest(IOTest):
10267db96d56Sopenharmony_ci
10277db96d56Sopenharmony_ci    def test_IOBase_finalize(self):
10287db96d56Sopenharmony_ci        # Issue #12149: segmentation fault on _PyIOBase_finalize when both a
10297db96d56Sopenharmony_ci        # class which inherits IOBase and an object of this class are caught
10307db96d56Sopenharmony_ci        # in a reference cycle and close() is already in the method cache.
10317db96d56Sopenharmony_ci        class MyIO(self.IOBase):
10327db96d56Sopenharmony_ci            def close(self):
10337db96d56Sopenharmony_ci                pass
10347db96d56Sopenharmony_ci
10357db96d56Sopenharmony_ci        # create an instance to populate the method cache
10367db96d56Sopenharmony_ci        MyIO()
10377db96d56Sopenharmony_ci        obj = MyIO()
10387db96d56Sopenharmony_ci        obj.obj = obj
10397db96d56Sopenharmony_ci        wr = weakref.ref(obj)
10407db96d56Sopenharmony_ci        del MyIO
10417db96d56Sopenharmony_ci        del obj
10427db96d56Sopenharmony_ci        support.gc_collect()
10437db96d56Sopenharmony_ci        self.assertIsNone(wr(), wr)
10447db96d56Sopenharmony_ci
10457db96d56Sopenharmony_ciclass PyIOTest(IOTest):
10467db96d56Sopenharmony_ci    pass
10477db96d56Sopenharmony_ci
10487db96d56Sopenharmony_ci
10497db96d56Sopenharmony_ci@support.cpython_only
10507db96d56Sopenharmony_ciclass APIMismatchTest(unittest.TestCase):
10517db96d56Sopenharmony_ci
10527db96d56Sopenharmony_ci    def test_RawIOBase_io_in_pyio_match(self):
10537db96d56Sopenharmony_ci        """Test that pyio RawIOBase class has all c RawIOBase methods"""
10547db96d56Sopenharmony_ci        mismatch = support.detect_api_mismatch(pyio.RawIOBase, io.RawIOBase,
10557db96d56Sopenharmony_ci                                               ignore=('__weakref__',))
10567db96d56Sopenharmony_ci        self.assertEqual(mismatch, set(), msg='Python RawIOBase does not have all C RawIOBase methods')
10577db96d56Sopenharmony_ci
10587db96d56Sopenharmony_ci    def test_RawIOBase_pyio_in_io_match(self):
10597db96d56Sopenharmony_ci        """Test that c RawIOBase class has all pyio RawIOBase methods"""
10607db96d56Sopenharmony_ci        mismatch = support.detect_api_mismatch(io.RawIOBase, pyio.RawIOBase)
10617db96d56Sopenharmony_ci        self.assertEqual(mismatch, set(), msg='C RawIOBase does not have all Python RawIOBase methods')
10627db96d56Sopenharmony_ci
10637db96d56Sopenharmony_ci
10647db96d56Sopenharmony_ciclass CommonBufferedTests:
10657db96d56Sopenharmony_ci    # Tests common to BufferedReader, BufferedWriter and BufferedRandom
10667db96d56Sopenharmony_ci
10677db96d56Sopenharmony_ci    def test_detach(self):
10687db96d56Sopenharmony_ci        raw = self.MockRawIO()
10697db96d56Sopenharmony_ci        buf = self.tp(raw)
10707db96d56Sopenharmony_ci        self.assertIs(buf.detach(), raw)
10717db96d56Sopenharmony_ci        self.assertRaises(ValueError, buf.detach)
10727db96d56Sopenharmony_ci
10737db96d56Sopenharmony_ci        repr(buf)  # Should still work
10747db96d56Sopenharmony_ci
10757db96d56Sopenharmony_ci    def test_fileno(self):
10767db96d56Sopenharmony_ci        rawio = self.MockRawIO()
10777db96d56Sopenharmony_ci        bufio = self.tp(rawio)
10787db96d56Sopenharmony_ci
10797db96d56Sopenharmony_ci        self.assertEqual(42, bufio.fileno())
10807db96d56Sopenharmony_ci
10817db96d56Sopenharmony_ci    def test_invalid_args(self):
10827db96d56Sopenharmony_ci        rawio = self.MockRawIO()
10837db96d56Sopenharmony_ci        bufio = self.tp(rawio)
10847db96d56Sopenharmony_ci        # Invalid whence
10857db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.seek, 0, -1)
10867db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.seek, 0, 9)
10877db96d56Sopenharmony_ci
10887db96d56Sopenharmony_ci    def test_override_destructor(self):
10897db96d56Sopenharmony_ci        tp = self.tp
10907db96d56Sopenharmony_ci        record = []
10917db96d56Sopenharmony_ci        class MyBufferedIO(tp):
10927db96d56Sopenharmony_ci            def __del__(self):
10937db96d56Sopenharmony_ci                record.append(1)
10947db96d56Sopenharmony_ci                try:
10957db96d56Sopenharmony_ci                    f = super().__del__
10967db96d56Sopenharmony_ci                except AttributeError:
10977db96d56Sopenharmony_ci                    pass
10987db96d56Sopenharmony_ci                else:
10997db96d56Sopenharmony_ci                    f()
11007db96d56Sopenharmony_ci            def close(self):
11017db96d56Sopenharmony_ci                record.append(2)
11027db96d56Sopenharmony_ci                super().close()
11037db96d56Sopenharmony_ci            def flush(self):
11047db96d56Sopenharmony_ci                record.append(3)
11057db96d56Sopenharmony_ci                super().flush()
11067db96d56Sopenharmony_ci        rawio = self.MockRawIO()
11077db96d56Sopenharmony_ci        bufio = MyBufferedIO(rawio)
11087db96d56Sopenharmony_ci        del bufio
11097db96d56Sopenharmony_ci        support.gc_collect()
11107db96d56Sopenharmony_ci        self.assertEqual(record, [1, 2, 3])
11117db96d56Sopenharmony_ci
11127db96d56Sopenharmony_ci    def test_context_manager(self):
11137db96d56Sopenharmony_ci        # Test usability as a context manager
11147db96d56Sopenharmony_ci        rawio = self.MockRawIO()
11157db96d56Sopenharmony_ci        bufio = self.tp(rawio)
11167db96d56Sopenharmony_ci        def _with():
11177db96d56Sopenharmony_ci            with bufio:
11187db96d56Sopenharmony_ci                pass
11197db96d56Sopenharmony_ci        _with()
11207db96d56Sopenharmony_ci        # bufio should now be closed, and using it a second time should raise
11217db96d56Sopenharmony_ci        # a ValueError.
11227db96d56Sopenharmony_ci        self.assertRaises(ValueError, _with)
11237db96d56Sopenharmony_ci
11247db96d56Sopenharmony_ci    def test_error_through_destructor(self):
11257db96d56Sopenharmony_ci        # Test that the exception state is not modified by a destructor,
11267db96d56Sopenharmony_ci        # even if close() fails.
11277db96d56Sopenharmony_ci        rawio = self.CloseFailureIO()
11287db96d56Sopenharmony_ci        with support.catch_unraisable_exception() as cm:
11297db96d56Sopenharmony_ci            with self.assertRaises(AttributeError):
11307db96d56Sopenharmony_ci                self.tp(rawio).xyzzy
11317db96d56Sopenharmony_ci
11327db96d56Sopenharmony_ci            if not IOBASE_EMITS_UNRAISABLE:
11337db96d56Sopenharmony_ci                self.assertIsNone(cm.unraisable)
11347db96d56Sopenharmony_ci            elif cm.unraisable is not None:
11357db96d56Sopenharmony_ci                self.assertEqual(cm.unraisable.exc_type, OSError)
11367db96d56Sopenharmony_ci
11377db96d56Sopenharmony_ci    def test_repr(self):
11387db96d56Sopenharmony_ci        raw = self.MockRawIO()
11397db96d56Sopenharmony_ci        b = self.tp(raw)
11407db96d56Sopenharmony_ci        clsname = r"(%s\.)?%s" % (self.tp.__module__, self.tp.__qualname__)
11417db96d56Sopenharmony_ci        self.assertRegex(repr(b), "<%s>" % clsname)
11427db96d56Sopenharmony_ci        raw.name = "dummy"
11437db96d56Sopenharmony_ci        self.assertRegex(repr(b), "<%s name='dummy'>" % clsname)
11447db96d56Sopenharmony_ci        raw.name = b"dummy"
11457db96d56Sopenharmony_ci        self.assertRegex(repr(b), "<%s name=b'dummy'>" % clsname)
11467db96d56Sopenharmony_ci
11477db96d56Sopenharmony_ci    def test_recursive_repr(self):
11487db96d56Sopenharmony_ci        # Issue #25455
11497db96d56Sopenharmony_ci        raw = self.MockRawIO()
11507db96d56Sopenharmony_ci        b = self.tp(raw)
11517db96d56Sopenharmony_ci        with support.swap_attr(raw, 'name', b):
11527db96d56Sopenharmony_ci            try:
11537db96d56Sopenharmony_ci                repr(b)  # Should not crash
11547db96d56Sopenharmony_ci            except RuntimeError:
11557db96d56Sopenharmony_ci                pass
11567db96d56Sopenharmony_ci
11577db96d56Sopenharmony_ci    def test_flush_error_on_close(self):
11587db96d56Sopenharmony_ci        # Test that buffered file is closed despite failed flush
11597db96d56Sopenharmony_ci        # and that flush() is called before file closed.
11607db96d56Sopenharmony_ci        raw = self.MockRawIO()
11617db96d56Sopenharmony_ci        closed = []
11627db96d56Sopenharmony_ci        def bad_flush():
11637db96d56Sopenharmony_ci            closed[:] = [b.closed, raw.closed]
11647db96d56Sopenharmony_ci            raise OSError()
11657db96d56Sopenharmony_ci        raw.flush = bad_flush
11667db96d56Sopenharmony_ci        b = self.tp(raw)
11677db96d56Sopenharmony_ci        self.assertRaises(OSError, b.close) # exception not swallowed
11687db96d56Sopenharmony_ci        self.assertTrue(b.closed)
11697db96d56Sopenharmony_ci        self.assertTrue(raw.closed)
11707db96d56Sopenharmony_ci        self.assertTrue(closed)      # flush() called
11717db96d56Sopenharmony_ci        self.assertFalse(closed[0])  # flush() called before file closed
11727db96d56Sopenharmony_ci        self.assertFalse(closed[1])
11737db96d56Sopenharmony_ci        raw.flush = lambda: None  # break reference loop
11747db96d56Sopenharmony_ci
11757db96d56Sopenharmony_ci    def test_close_error_on_close(self):
11767db96d56Sopenharmony_ci        raw = self.MockRawIO()
11777db96d56Sopenharmony_ci        def bad_flush():
11787db96d56Sopenharmony_ci            raise OSError('flush')
11797db96d56Sopenharmony_ci        def bad_close():
11807db96d56Sopenharmony_ci            raise OSError('close')
11817db96d56Sopenharmony_ci        raw.close = bad_close
11827db96d56Sopenharmony_ci        b = self.tp(raw)
11837db96d56Sopenharmony_ci        b.flush = bad_flush
11847db96d56Sopenharmony_ci        with self.assertRaises(OSError) as err: # exception not swallowed
11857db96d56Sopenharmony_ci            b.close()
11867db96d56Sopenharmony_ci        self.assertEqual(err.exception.args, ('close',))
11877db96d56Sopenharmony_ci        self.assertIsInstance(err.exception.__context__, OSError)
11887db96d56Sopenharmony_ci        self.assertEqual(err.exception.__context__.args, ('flush',))
11897db96d56Sopenharmony_ci        self.assertFalse(b.closed)
11907db96d56Sopenharmony_ci
11917db96d56Sopenharmony_ci        # Silence destructor error
11927db96d56Sopenharmony_ci        raw.close = lambda: None
11937db96d56Sopenharmony_ci        b.flush = lambda: None
11947db96d56Sopenharmony_ci
11957db96d56Sopenharmony_ci    def test_nonnormalized_close_error_on_close(self):
11967db96d56Sopenharmony_ci        # Issue #21677
11977db96d56Sopenharmony_ci        raw = self.MockRawIO()
11987db96d56Sopenharmony_ci        def bad_flush():
11997db96d56Sopenharmony_ci            raise non_existing_flush
12007db96d56Sopenharmony_ci        def bad_close():
12017db96d56Sopenharmony_ci            raise non_existing_close
12027db96d56Sopenharmony_ci        raw.close = bad_close
12037db96d56Sopenharmony_ci        b = self.tp(raw)
12047db96d56Sopenharmony_ci        b.flush = bad_flush
12057db96d56Sopenharmony_ci        with self.assertRaises(NameError) as err: # exception not swallowed
12067db96d56Sopenharmony_ci            b.close()
12077db96d56Sopenharmony_ci        self.assertIn('non_existing_close', str(err.exception))
12087db96d56Sopenharmony_ci        self.assertIsInstance(err.exception.__context__, NameError)
12097db96d56Sopenharmony_ci        self.assertIn('non_existing_flush', str(err.exception.__context__))
12107db96d56Sopenharmony_ci        self.assertFalse(b.closed)
12117db96d56Sopenharmony_ci
12127db96d56Sopenharmony_ci        # Silence destructor error
12137db96d56Sopenharmony_ci        b.flush = lambda: None
12147db96d56Sopenharmony_ci        raw.close = lambda: None
12157db96d56Sopenharmony_ci
12167db96d56Sopenharmony_ci    def test_multi_close(self):
12177db96d56Sopenharmony_ci        raw = self.MockRawIO()
12187db96d56Sopenharmony_ci        b = self.tp(raw)
12197db96d56Sopenharmony_ci        b.close()
12207db96d56Sopenharmony_ci        b.close()
12217db96d56Sopenharmony_ci        b.close()
12227db96d56Sopenharmony_ci        self.assertRaises(ValueError, b.flush)
12237db96d56Sopenharmony_ci
12247db96d56Sopenharmony_ci    def test_unseekable(self):
12257db96d56Sopenharmony_ci        bufio = self.tp(self.MockUnseekableIO(b"A" * 10))
12267db96d56Sopenharmony_ci        self.assertRaises(self.UnsupportedOperation, bufio.tell)
12277db96d56Sopenharmony_ci        self.assertRaises(self.UnsupportedOperation, bufio.seek, 0)
12287db96d56Sopenharmony_ci
12297db96d56Sopenharmony_ci    def test_readonly_attributes(self):
12307db96d56Sopenharmony_ci        raw = self.MockRawIO()
12317db96d56Sopenharmony_ci        buf = self.tp(raw)
12327db96d56Sopenharmony_ci        x = self.MockRawIO()
12337db96d56Sopenharmony_ci        with self.assertRaises(AttributeError):
12347db96d56Sopenharmony_ci            buf.raw = x
12357db96d56Sopenharmony_ci
12367db96d56Sopenharmony_ci
12377db96d56Sopenharmony_ciclass SizeofTest:
12387db96d56Sopenharmony_ci
12397db96d56Sopenharmony_ci    @support.cpython_only
12407db96d56Sopenharmony_ci    def test_sizeof(self):
12417db96d56Sopenharmony_ci        bufsize1 = 4096
12427db96d56Sopenharmony_ci        bufsize2 = 8192
12437db96d56Sopenharmony_ci        rawio = self.MockRawIO()
12447db96d56Sopenharmony_ci        bufio = self.tp(rawio, buffer_size=bufsize1)
12457db96d56Sopenharmony_ci        size = sys.getsizeof(bufio) - bufsize1
12467db96d56Sopenharmony_ci        rawio = self.MockRawIO()
12477db96d56Sopenharmony_ci        bufio = self.tp(rawio, buffer_size=bufsize2)
12487db96d56Sopenharmony_ci        self.assertEqual(sys.getsizeof(bufio), size + bufsize2)
12497db96d56Sopenharmony_ci
12507db96d56Sopenharmony_ci    @support.cpython_only
12517db96d56Sopenharmony_ci    def test_buffer_freeing(self) :
12527db96d56Sopenharmony_ci        bufsize = 4096
12537db96d56Sopenharmony_ci        rawio = self.MockRawIO()
12547db96d56Sopenharmony_ci        bufio = self.tp(rawio, buffer_size=bufsize)
12557db96d56Sopenharmony_ci        size = sys.getsizeof(bufio) - bufsize
12567db96d56Sopenharmony_ci        bufio.close()
12577db96d56Sopenharmony_ci        self.assertEqual(sys.getsizeof(bufio), size)
12587db96d56Sopenharmony_ci
12597db96d56Sopenharmony_ciclass BufferedReaderTest(unittest.TestCase, CommonBufferedTests):
12607db96d56Sopenharmony_ci    read_mode = "rb"
12617db96d56Sopenharmony_ci
12627db96d56Sopenharmony_ci    def test_constructor(self):
12637db96d56Sopenharmony_ci        rawio = self.MockRawIO([b"abc"])
12647db96d56Sopenharmony_ci        bufio = self.tp(rawio)
12657db96d56Sopenharmony_ci        bufio.__init__(rawio)
12667db96d56Sopenharmony_ci        bufio.__init__(rawio, buffer_size=1024)
12677db96d56Sopenharmony_ci        bufio.__init__(rawio, buffer_size=16)
12687db96d56Sopenharmony_ci        self.assertEqual(b"abc", bufio.read())
12697db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=0)
12707db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-16)
12717db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-1)
12727db96d56Sopenharmony_ci        rawio = self.MockRawIO([b"abc"])
12737db96d56Sopenharmony_ci        bufio.__init__(rawio)
12747db96d56Sopenharmony_ci        self.assertEqual(b"abc", bufio.read())
12757db96d56Sopenharmony_ci
12767db96d56Sopenharmony_ci    def test_uninitialized(self):
12777db96d56Sopenharmony_ci        bufio = self.tp.__new__(self.tp)
12787db96d56Sopenharmony_ci        del bufio
12797db96d56Sopenharmony_ci        bufio = self.tp.__new__(self.tp)
12807db96d56Sopenharmony_ci        self.assertRaisesRegex((ValueError, AttributeError),
12817db96d56Sopenharmony_ci                               'uninitialized|has no attribute',
12827db96d56Sopenharmony_ci                               bufio.read, 0)
12837db96d56Sopenharmony_ci        bufio.__init__(self.MockRawIO())
12847db96d56Sopenharmony_ci        self.assertEqual(bufio.read(0), b'')
12857db96d56Sopenharmony_ci
12867db96d56Sopenharmony_ci    def test_read(self):
12877db96d56Sopenharmony_ci        for arg in (None, 7):
12887db96d56Sopenharmony_ci            rawio = self.MockRawIO((b"abc", b"d", b"efg"))
12897db96d56Sopenharmony_ci            bufio = self.tp(rawio)
12907db96d56Sopenharmony_ci            self.assertEqual(b"abcdefg", bufio.read(arg))
12917db96d56Sopenharmony_ci        # Invalid args
12927db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.read, -2)
12937db96d56Sopenharmony_ci
12947db96d56Sopenharmony_ci    def test_read1(self):
12957db96d56Sopenharmony_ci        rawio = self.MockRawIO((b"abc", b"d", b"efg"))
12967db96d56Sopenharmony_ci        bufio = self.tp(rawio)
12977db96d56Sopenharmony_ci        self.assertEqual(b"a", bufio.read(1))
12987db96d56Sopenharmony_ci        self.assertEqual(b"b", bufio.read1(1))
12997db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 1)
13007db96d56Sopenharmony_ci        self.assertEqual(b"", bufio.read1(0))
13017db96d56Sopenharmony_ci        self.assertEqual(b"c", bufio.read1(100))
13027db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 1)
13037db96d56Sopenharmony_ci        self.assertEqual(b"d", bufio.read1(100))
13047db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 2)
13057db96d56Sopenharmony_ci        self.assertEqual(b"efg", bufio.read1(100))
13067db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 3)
13077db96d56Sopenharmony_ci        self.assertEqual(b"", bufio.read1(100))
13087db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 4)
13097db96d56Sopenharmony_ci
13107db96d56Sopenharmony_ci    def test_read1_arbitrary(self):
13117db96d56Sopenharmony_ci        rawio = self.MockRawIO((b"abc", b"d", b"efg"))
13127db96d56Sopenharmony_ci        bufio = self.tp(rawio)
13137db96d56Sopenharmony_ci        self.assertEqual(b"a", bufio.read(1))
13147db96d56Sopenharmony_ci        self.assertEqual(b"bc", bufio.read1())
13157db96d56Sopenharmony_ci        self.assertEqual(b"d", bufio.read1())
13167db96d56Sopenharmony_ci        self.assertEqual(b"efg", bufio.read1(-1))
13177db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 3)
13187db96d56Sopenharmony_ci        self.assertEqual(b"", bufio.read1())
13197db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 4)
13207db96d56Sopenharmony_ci
13217db96d56Sopenharmony_ci    def test_readinto(self):
13227db96d56Sopenharmony_ci        rawio = self.MockRawIO((b"abc", b"d", b"efg"))
13237db96d56Sopenharmony_ci        bufio = self.tp(rawio)
13247db96d56Sopenharmony_ci        b = bytearray(2)
13257db96d56Sopenharmony_ci        self.assertEqual(bufio.readinto(b), 2)
13267db96d56Sopenharmony_ci        self.assertEqual(b, b"ab")
13277db96d56Sopenharmony_ci        self.assertEqual(bufio.readinto(b), 2)
13287db96d56Sopenharmony_ci        self.assertEqual(b, b"cd")
13297db96d56Sopenharmony_ci        self.assertEqual(bufio.readinto(b), 2)
13307db96d56Sopenharmony_ci        self.assertEqual(b, b"ef")
13317db96d56Sopenharmony_ci        self.assertEqual(bufio.readinto(b), 1)
13327db96d56Sopenharmony_ci        self.assertEqual(b, b"gf")
13337db96d56Sopenharmony_ci        self.assertEqual(bufio.readinto(b), 0)
13347db96d56Sopenharmony_ci        self.assertEqual(b, b"gf")
13357db96d56Sopenharmony_ci        rawio = self.MockRawIO((b"abc", None))
13367db96d56Sopenharmony_ci        bufio = self.tp(rawio)
13377db96d56Sopenharmony_ci        self.assertEqual(bufio.readinto(b), 2)
13387db96d56Sopenharmony_ci        self.assertEqual(b, b"ab")
13397db96d56Sopenharmony_ci        self.assertEqual(bufio.readinto(b), 1)
13407db96d56Sopenharmony_ci        self.assertEqual(b, b"cb")
13417db96d56Sopenharmony_ci
13427db96d56Sopenharmony_ci    def test_readinto1(self):
13437db96d56Sopenharmony_ci        buffer_size = 10
13447db96d56Sopenharmony_ci        rawio = self.MockRawIO((b"abc", b"de", b"fgh", b"jkl"))
13457db96d56Sopenharmony_ci        bufio = self.tp(rawio, buffer_size=buffer_size)
13467db96d56Sopenharmony_ci        b = bytearray(2)
13477db96d56Sopenharmony_ci        self.assertEqual(bufio.peek(3), b'abc')
13487db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 1)
13497db96d56Sopenharmony_ci        self.assertEqual(bufio.readinto1(b), 2)
13507db96d56Sopenharmony_ci        self.assertEqual(b, b"ab")
13517db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 1)
13527db96d56Sopenharmony_ci        self.assertEqual(bufio.readinto1(b), 1)
13537db96d56Sopenharmony_ci        self.assertEqual(b[:1], b"c")
13547db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 1)
13557db96d56Sopenharmony_ci        self.assertEqual(bufio.readinto1(b), 2)
13567db96d56Sopenharmony_ci        self.assertEqual(b, b"de")
13577db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 2)
13587db96d56Sopenharmony_ci        b = bytearray(2*buffer_size)
13597db96d56Sopenharmony_ci        self.assertEqual(bufio.peek(3), b'fgh')
13607db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 3)
13617db96d56Sopenharmony_ci        self.assertEqual(bufio.readinto1(b), 6)
13627db96d56Sopenharmony_ci        self.assertEqual(b[:6], b"fghjkl")
13637db96d56Sopenharmony_ci        self.assertEqual(rawio._reads, 4)
13647db96d56Sopenharmony_ci
13657db96d56Sopenharmony_ci    def test_readinto_array(self):
13667db96d56Sopenharmony_ci        buffer_size = 60
13677db96d56Sopenharmony_ci        data = b"a" * 26
13687db96d56Sopenharmony_ci        rawio = self.MockRawIO((data,))
13697db96d56Sopenharmony_ci        bufio = self.tp(rawio, buffer_size=buffer_size)
13707db96d56Sopenharmony_ci
13717db96d56Sopenharmony_ci        # Create an array with element size > 1 byte
13727db96d56Sopenharmony_ci        b = array.array('i', b'x' * 32)
13737db96d56Sopenharmony_ci        assert len(b) != 16
13747db96d56Sopenharmony_ci
13757db96d56Sopenharmony_ci        # Read into it. We should get as many *bytes* as we can fit into b
13767db96d56Sopenharmony_ci        # (which is more than the number of elements)
13777db96d56Sopenharmony_ci        n = bufio.readinto(b)
13787db96d56Sopenharmony_ci        self.assertGreater(n, len(b))
13797db96d56Sopenharmony_ci
13807db96d56Sopenharmony_ci        # Check that old contents of b are preserved
13817db96d56Sopenharmony_ci        bm = memoryview(b).cast('B')
13827db96d56Sopenharmony_ci        self.assertLess(n, len(bm))
13837db96d56Sopenharmony_ci        self.assertEqual(bm[:n], data[:n])
13847db96d56Sopenharmony_ci        self.assertEqual(bm[n:], b'x' * (len(bm[n:])))
13857db96d56Sopenharmony_ci
13867db96d56Sopenharmony_ci    def test_readinto1_array(self):
13877db96d56Sopenharmony_ci        buffer_size = 60
13887db96d56Sopenharmony_ci        data = b"a" * 26
13897db96d56Sopenharmony_ci        rawio = self.MockRawIO((data,))
13907db96d56Sopenharmony_ci        bufio = self.tp(rawio, buffer_size=buffer_size)
13917db96d56Sopenharmony_ci
13927db96d56Sopenharmony_ci        # Create an array with element size > 1 byte
13937db96d56Sopenharmony_ci        b = array.array('i', b'x' * 32)
13947db96d56Sopenharmony_ci        assert len(b) != 16
13957db96d56Sopenharmony_ci
13967db96d56Sopenharmony_ci        # Read into it. We should get as many *bytes* as we can fit into b
13977db96d56Sopenharmony_ci        # (which is more than the number of elements)
13987db96d56Sopenharmony_ci        n = bufio.readinto1(b)
13997db96d56Sopenharmony_ci        self.assertGreater(n, len(b))
14007db96d56Sopenharmony_ci
14017db96d56Sopenharmony_ci        # Check that old contents of b are preserved
14027db96d56Sopenharmony_ci        bm = memoryview(b).cast('B')
14037db96d56Sopenharmony_ci        self.assertLess(n, len(bm))
14047db96d56Sopenharmony_ci        self.assertEqual(bm[:n], data[:n])
14057db96d56Sopenharmony_ci        self.assertEqual(bm[n:], b'x' * (len(bm[n:])))
14067db96d56Sopenharmony_ci
14077db96d56Sopenharmony_ci    def test_readlines(self):
14087db96d56Sopenharmony_ci        def bufio():
14097db96d56Sopenharmony_ci            rawio = self.MockRawIO((b"abc\n", b"d\n", b"ef"))
14107db96d56Sopenharmony_ci            return self.tp(rawio)
14117db96d56Sopenharmony_ci        self.assertEqual(bufio().readlines(), [b"abc\n", b"d\n", b"ef"])
14127db96d56Sopenharmony_ci        self.assertEqual(bufio().readlines(5), [b"abc\n", b"d\n"])
14137db96d56Sopenharmony_ci        self.assertEqual(bufio().readlines(None), [b"abc\n", b"d\n", b"ef"])
14147db96d56Sopenharmony_ci
14157db96d56Sopenharmony_ci    def test_buffering(self):
14167db96d56Sopenharmony_ci        data = b"abcdefghi"
14177db96d56Sopenharmony_ci        dlen = len(data)
14187db96d56Sopenharmony_ci
14197db96d56Sopenharmony_ci        tests = [
14207db96d56Sopenharmony_ci            [ 100, [ 3, 1, 4, 8 ], [ dlen, 0 ] ],
14217db96d56Sopenharmony_ci            [ 100, [ 3, 3, 3],     [ dlen ]    ],
14227db96d56Sopenharmony_ci            [   4, [ 1, 2, 4, 2 ], [ 4, 4, 1 ] ],
14237db96d56Sopenharmony_ci        ]
14247db96d56Sopenharmony_ci
14257db96d56Sopenharmony_ci        for bufsize, buf_read_sizes, raw_read_sizes in tests:
14267db96d56Sopenharmony_ci            rawio = self.MockFileIO(data)
14277db96d56Sopenharmony_ci            bufio = self.tp(rawio, buffer_size=bufsize)
14287db96d56Sopenharmony_ci            pos = 0
14297db96d56Sopenharmony_ci            for nbytes in buf_read_sizes:
14307db96d56Sopenharmony_ci                self.assertEqual(bufio.read(nbytes), data[pos:pos+nbytes])
14317db96d56Sopenharmony_ci                pos += nbytes
14327db96d56Sopenharmony_ci            # this is mildly implementation-dependent
14337db96d56Sopenharmony_ci            self.assertEqual(rawio.read_history, raw_read_sizes)
14347db96d56Sopenharmony_ci
14357db96d56Sopenharmony_ci    def test_read_non_blocking(self):
14367db96d56Sopenharmony_ci        # Inject some None's in there to simulate EWOULDBLOCK
14377db96d56Sopenharmony_ci        rawio = self.MockRawIO((b"abc", b"d", None, b"efg", None, None, None))
14387db96d56Sopenharmony_ci        bufio = self.tp(rawio)
14397db96d56Sopenharmony_ci        self.assertEqual(b"abcd", bufio.read(6))
14407db96d56Sopenharmony_ci        self.assertEqual(b"e", bufio.read(1))
14417db96d56Sopenharmony_ci        self.assertEqual(b"fg", bufio.read())
14427db96d56Sopenharmony_ci        self.assertEqual(b"", bufio.peek(1))
14437db96d56Sopenharmony_ci        self.assertIsNone(bufio.read())
14447db96d56Sopenharmony_ci        self.assertEqual(b"", bufio.read())
14457db96d56Sopenharmony_ci
14467db96d56Sopenharmony_ci        rawio = self.MockRawIO((b"a", None, None))
14477db96d56Sopenharmony_ci        self.assertEqual(b"a", rawio.readall())
14487db96d56Sopenharmony_ci        self.assertIsNone(rawio.readall())
14497db96d56Sopenharmony_ci
14507db96d56Sopenharmony_ci    def test_read_past_eof(self):
14517db96d56Sopenharmony_ci        rawio = self.MockRawIO((b"abc", b"d", b"efg"))
14527db96d56Sopenharmony_ci        bufio = self.tp(rawio)
14537db96d56Sopenharmony_ci
14547db96d56Sopenharmony_ci        self.assertEqual(b"abcdefg", bufio.read(9000))
14557db96d56Sopenharmony_ci
14567db96d56Sopenharmony_ci    def test_read_all(self):
14577db96d56Sopenharmony_ci        rawio = self.MockRawIO((b"abc", b"d", b"efg"))
14587db96d56Sopenharmony_ci        bufio = self.tp(rawio)
14597db96d56Sopenharmony_ci
14607db96d56Sopenharmony_ci        self.assertEqual(b"abcdefg", bufio.read())
14617db96d56Sopenharmony_ci
14627db96d56Sopenharmony_ci    @support.requires_resource('cpu')
14637db96d56Sopenharmony_ci    @threading_helper.requires_working_threading()
14647db96d56Sopenharmony_ci    def test_threads(self):
14657db96d56Sopenharmony_ci        try:
14667db96d56Sopenharmony_ci            # Write out many bytes with exactly the same number of 0's,
14677db96d56Sopenharmony_ci            # 1's... 255's. This will help us check that concurrent reading
14687db96d56Sopenharmony_ci            # doesn't duplicate or forget contents.
14697db96d56Sopenharmony_ci            N = 1000
14707db96d56Sopenharmony_ci            l = list(range(256)) * N
14717db96d56Sopenharmony_ci            random.shuffle(l)
14727db96d56Sopenharmony_ci            s = bytes(bytearray(l))
14737db96d56Sopenharmony_ci            with self.open(os_helper.TESTFN, "wb") as f:
14747db96d56Sopenharmony_ci                f.write(s)
14757db96d56Sopenharmony_ci            with self.open(os_helper.TESTFN, self.read_mode, buffering=0) as raw:
14767db96d56Sopenharmony_ci                bufio = self.tp(raw, 8)
14777db96d56Sopenharmony_ci                errors = []
14787db96d56Sopenharmony_ci                results = []
14797db96d56Sopenharmony_ci                def f():
14807db96d56Sopenharmony_ci                    try:
14817db96d56Sopenharmony_ci                        # Intra-buffer read then buffer-flushing read
14827db96d56Sopenharmony_ci                        for n in cycle([1, 19]):
14837db96d56Sopenharmony_ci                            s = bufio.read(n)
14847db96d56Sopenharmony_ci                            if not s:
14857db96d56Sopenharmony_ci                                break
14867db96d56Sopenharmony_ci                            # list.append() is atomic
14877db96d56Sopenharmony_ci                            results.append(s)
14887db96d56Sopenharmony_ci                    except Exception as e:
14897db96d56Sopenharmony_ci                        errors.append(e)
14907db96d56Sopenharmony_ci                        raise
14917db96d56Sopenharmony_ci                threads = [threading.Thread(target=f) for x in range(20)]
14927db96d56Sopenharmony_ci                with threading_helper.start_threads(threads):
14937db96d56Sopenharmony_ci                    time.sleep(0.02) # yield
14947db96d56Sopenharmony_ci                self.assertFalse(errors,
14957db96d56Sopenharmony_ci                    "the following exceptions were caught: %r" % errors)
14967db96d56Sopenharmony_ci                s = b''.join(results)
14977db96d56Sopenharmony_ci                for i in range(256):
14987db96d56Sopenharmony_ci                    c = bytes(bytearray([i]))
14997db96d56Sopenharmony_ci                    self.assertEqual(s.count(c), N)
15007db96d56Sopenharmony_ci        finally:
15017db96d56Sopenharmony_ci            os_helper.unlink(os_helper.TESTFN)
15027db96d56Sopenharmony_ci
15037db96d56Sopenharmony_ci    def test_unseekable(self):
15047db96d56Sopenharmony_ci        bufio = self.tp(self.MockUnseekableIO(b"A" * 10))
15057db96d56Sopenharmony_ci        self.assertRaises(self.UnsupportedOperation, bufio.tell)
15067db96d56Sopenharmony_ci        self.assertRaises(self.UnsupportedOperation, bufio.seek, 0)
15077db96d56Sopenharmony_ci        bufio.read(1)
15087db96d56Sopenharmony_ci        self.assertRaises(self.UnsupportedOperation, bufio.seek, 0)
15097db96d56Sopenharmony_ci        self.assertRaises(self.UnsupportedOperation, bufio.tell)
15107db96d56Sopenharmony_ci
15117db96d56Sopenharmony_ci    def test_misbehaved_io(self):
15127db96d56Sopenharmony_ci        rawio = self.MisbehavedRawIO((b"abc", b"d", b"efg"))
15137db96d56Sopenharmony_ci        bufio = self.tp(rawio)
15147db96d56Sopenharmony_ci        self.assertRaises(OSError, bufio.seek, 0)
15157db96d56Sopenharmony_ci        self.assertRaises(OSError, bufio.tell)
15167db96d56Sopenharmony_ci
15177db96d56Sopenharmony_ci        # Silence destructor error
15187db96d56Sopenharmony_ci        bufio.close = lambda: None
15197db96d56Sopenharmony_ci
15207db96d56Sopenharmony_ci    def test_no_extraneous_read(self):
15217db96d56Sopenharmony_ci        # Issue #9550; when the raw IO object has satisfied the read request,
15227db96d56Sopenharmony_ci        # we should not issue any additional reads, otherwise it may block
15237db96d56Sopenharmony_ci        # (e.g. socket).
15247db96d56Sopenharmony_ci        bufsize = 16
15257db96d56Sopenharmony_ci        for n in (2, bufsize - 1, bufsize, bufsize + 1, bufsize * 2):
15267db96d56Sopenharmony_ci            rawio = self.MockRawIO([b"x" * n])
15277db96d56Sopenharmony_ci            bufio = self.tp(rawio, bufsize)
15287db96d56Sopenharmony_ci            self.assertEqual(bufio.read(n), b"x" * n)
15297db96d56Sopenharmony_ci            # Simple case: one raw read is enough to satisfy the request.
15307db96d56Sopenharmony_ci            self.assertEqual(rawio._extraneous_reads, 0,
15317db96d56Sopenharmony_ci                             "failed for {}: {} != 0".format(n, rawio._extraneous_reads))
15327db96d56Sopenharmony_ci            # A more complex case where two raw reads are needed to satisfy
15337db96d56Sopenharmony_ci            # the request.
15347db96d56Sopenharmony_ci            rawio = self.MockRawIO([b"x" * (n - 1), b"x"])
15357db96d56Sopenharmony_ci            bufio = self.tp(rawio, bufsize)
15367db96d56Sopenharmony_ci            self.assertEqual(bufio.read(n), b"x" * n)
15377db96d56Sopenharmony_ci            self.assertEqual(rawio._extraneous_reads, 0,
15387db96d56Sopenharmony_ci                             "failed for {}: {} != 0".format(n, rawio._extraneous_reads))
15397db96d56Sopenharmony_ci
15407db96d56Sopenharmony_ci    def test_read_on_closed(self):
15417db96d56Sopenharmony_ci        # Issue #23796
15427db96d56Sopenharmony_ci        b = io.BufferedReader(io.BytesIO(b"12"))
15437db96d56Sopenharmony_ci        b.read(1)
15447db96d56Sopenharmony_ci        b.close()
15457db96d56Sopenharmony_ci        self.assertRaises(ValueError, b.peek)
15467db96d56Sopenharmony_ci        self.assertRaises(ValueError, b.read1, 1)
15477db96d56Sopenharmony_ci
15487db96d56Sopenharmony_ci    def test_truncate_on_read_only(self):
15497db96d56Sopenharmony_ci        rawio = self.MockFileIO(b"abc")
15507db96d56Sopenharmony_ci        bufio = self.tp(rawio)
15517db96d56Sopenharmony_ci        self.assertFalse(bufio.writable())
15527db96d56Sopenharmony_ci        self.assertRaises(self.UnsupportedOperation, bufio.truncate)
15537db96d56Sopenharmony_ci        self.assertRaises(self.UnsupportedOperation, bufio.truncate, 0)
15547db96d56Sopenharmony_ci
15557db96d56Sopenharmony_ci
15567db96d56Sopenharmony_ciclass CBufferedReaderTest(BufferedReaderTest, SizeofTest):
15577db96d56Sopenharmony_ci    tp = io.BufferedReader
15587db96d56Sopenharmony_ci
15597db96d56Sopenharmony_ci    @skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing "
15607db96d56Sopenharmony_ci                       "instead of returning NULL for malloc failure.")
15617db96d56Sopenharmony_ci    def test_constructor(self):
15627db96d56Sopenharmony_ci        BufferedReaderTest.test_constructor(self)
15637db96d56Sopenharmony_ci        # The allocation can succeed on 32-bit builds, e.g. with more
15647db96d56Sopenharmony_ci        # than 2 GiB RAM and a 64-bit kernel.
15657db96d56Sopenharmony_ci        if sys.maxsize > 0x7FFFFFFF:
15667db96d56Sopenharmony_ci            rawio = self.MockRawIO()
15677db96d56Sopenharmony_ci            bufio = self.tp(rawio)
15687db96d56Sopenharmony_ci            self.assertRaises((OverflowError, MemoryError, ValueError),
15697db96d56Sopenharmony_ci                bufio.__init__, rawio, sys.maxsize)
15707db96d56Sopenharmony_ci
15717db96d56Sopenharmony_ci    def test_initialization(self):
15727db96d56Sopenharmony_ci        rawio = self.MockRawIO([b"abc"])
15737db96d56Sopenharmony_ci        bufio = self.tp(rawio)
15747db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=0)
15757db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.read)
15767db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-16)
15777db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.read)
15787db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-1)
15797db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.read)
15807db96d56Sopenharmony_ci
15817db96d56Sopenharmony_ci    def test_misbehaved_io_read(self):
15827db96d56Sopenharmony_ci        rawio = self.MisbehavedRawIO((b"abc", b"d", b"efg"))
15837db96d56Sopenharmony_ci        bufio = self.tp(rawio)
15847db96d56Sopenharmony_ci        # _pyio.BufferedReader seems to implement reading different, so that
15857db96d56Sopenharmony_ci        # checking this is not so easy.
15867db96d56Sopenharmony_ci        self.assertRaises(OSError, bufio.read, 10)
15877db96d56Sopenharmony_ci
15887db96d56Sopenharmony_ci    def test_garbage_collection(self):
15897db96d56Sopenharmony_ci        # C BufferedReader objects are collected.
15907db96d56Sopenharmony_ci        # The Python version has __del__, so it ends into gc.garbage instead
15917db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
15927db96d56Sopenharmony_ci        with warnings_helper.check_warnings(('', ResourceWarning)):
15937db96d56Sopenharmony_ci            rawio = self.FileIO(os_helper.TESTFN, "w+b")
15947db96d56Sopenharmony_ci            f = self.tp(rawio)
15957db96d56Sopenharmony_ci            f.f = f
15967db96d56Sopenharmony_ci            wr = weakref.ref(f)
15977db96d56Sopenharmony_ci            del f
15987db96d56Sopenharmony_ci            support.gc_collect()
15997db96d56Sopenharmony_ci        self.assertIsNone(wr(), wr)
16007db96d56Sopenharmony_ci
16017db96d56Sopenharmony_ci    def test_args_error(self):
16027db96d56Sopenharmony_ci        # Issue #17275
16037db96d56Sopenharmony_ci        with self.assertRaisesRegex(TypeError, "BufferedReader"):
16047db96d56Sopenharmony_ci            self.tp(io.BytesIO(), 1024, 1024, 1024)
16057db96d56Sopenharmony_ci
16067db96d56Sopenharmony_ci    def test_bad_readinto_value(self):
16077db96d56Sopenharmony_ci        rawio = io.BufferedReader(io.BytesIO(b"12"))
16087db96d56Sopenharmony_ci        rawio.readinto = lambda buf: -1
16097db96d56Sopenharmony_ci        bufio = self.tp(rawio)
16107db96d56Sopenharmony_ci        with self.assertRaises(OSError) as cm:
16117db96d56Sopenharmony_ci            bufio.readline()
16127db96d56Sopenharmony_ci        self.assertIsNone(cm.exception.__cause__)
16137db96d56Sopenharmony_ci
16147db96d56Sopenharmony_ci    def test_bad_readinto_type(self):
16157db96d56Sopenharmony_ci        rawio = io.BufferedReader(io.BytesIO(b"12"))
16167db96d56Sopenharmony_ci        rawio.readinto = lambda buf: b''
16177db96d56Sopenharmony_ci        bufio = self.tp(rawio)
16187db96d56Sopenharmony_ci        with self.assertRaises(OSError) as cm:
16197db96d56Sopenharmony_ci            bufio.readline()
16207db96d56Sopenharmony_ci        self.assertIsInstance(cm.exception.__cause__, TypeError)
16217db96d56Sopenharmony_ci
16227db96d56Sopenharmony_ci
16237db96d56Sopenharmony_ciclass PyBufferedReaderTest(BufferedReaderTest):
16247db96d56Sopenharmony_ci    tp = pyio.BufferedReader
16257db96d56Sopenharmony_ci
16267db96d56Sopenharmony_ci
16277db96d56Sopenharmony_ciclass BufferedWriterTest(unittest.TestCase, CommonBufferedTests):
16287db96d56Sopenharmony_ci    write_mode = "wb"
16297db96d56Sopenharmony_ci
16307db96d56Sopenharmony_ci    def test_constructor(self):
16317db96d56Sopenharmony_ci        rawio = self.MockRawIO()
16327db96d56Sopenharmony_ci        bufio = self.tp(rawio)
16337db96d56Sopenharmony_ci        bufio.__init__(rawio)
16347db96d56Sopenharmony_ci        bufio.__init__(rawio, buffer_size=1024)
16357db96d56Sopenharmony_ci        bufio.__init__(rawio, buffer_size=16)
16367db96d56Sopenharmony_ci        self.assertEqual(3, bufio.write(b"abc"))
16377db96d56Sopenharmony_ci        bufio.flush()
16387db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=0)
16397db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-16)
16407db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-1)
16417db96d56Sopenharmony_ci        bufio.__init__(rawio)
16427db96d56Sopenharmony_ci        self.assertEqual(3, bufio.write(b"ghi"))
16437db96d56Sopenharmony_ci        bufio.flush()
16447db96d56Sopenharmony_ci        self.assertEqual(b"".join(rawio._write_stack), b"abcghi")
16457db96d56Sopenharmony_ci
16467db96d56Sopenharmony_ci    def test_uninitialized(self):
16477db96d56Sopenharmony_ci        bufio = self.tp.__new__(self.tp)
16487db96d56Sopenharmony_ci        del bufio
16497db96d56Sopenharmony_ci        bufio = self.tp.__new__(self.tp)
16507db96d56Sopenharmony_ci        self.assertRaisesRegex((ValueError, AttributeError),
16517db96d56Sopenharmony_ci                               'uninitialized|has no attribute',
16527db96d56Sopenharmony_ci                               bufio.write, b'')
16537db96d56Sopenharmony_ci        bufio.__init__(self.MockRawIO())
16547db96d56Sopenharmony_ci        self.assertEqual(bufio.write(b''), 0)
16557db96d56Sopenharmony_ci
16567db96d56Sopenharmony_ci    def test_detach_flush(self):
16577db96d56Sopenharmony_ci        raw = self.MockRawIO()
16587db96d56Sopenharmony_ci        buf = self.tp(raw)
16597db96d56Sopenharmony_ci        buf.write(b"howdy!")
16607db96d56Sopenharmony_ci        self.assertFalse(raw._write_stack)
16617db96d56Sopenharmony_ci        buf.detach()
16627db96d56Sopenharmony_ci        self.assertEqual(raw._write_stack, [b"howdy!"])
16637db96d56Sopenharmony_ci
16647db96d56Sopenharmony_ci    def test_write(self):
16657db96d56Sopenharmony_ci        # Write to the buffered IO but don't overflow the buffer.
16667db96d56Sopenharmony_ci        writer = self.MockRawIO()
16677db96d56Sopenharmony_ci        bufio = self.tp(writer, 8)
16687db96d56Sopenharmony_ci        bufio.write(b"abc")
16697db96d56Sopenharmony_ci        self.assertFalse(writer._write_stack)
16707db96d56Sopenharmony_ci        buffer = bytearray(b"def")
16717db96d56Sopenharmony_ci        bufio.write(buffer)
16727db96d56Sopenharmony_ci        buffer[:] = b"***"  # Overwrite our copy of the data
16737db96d56Sopenharmony_ci        bufio.flush()
16747db96d56Sopenharmony_ci        self.assertEqual(b"".join(writer._write_stack), b"abcdef")
16757db96d56Sopenharmony_ci
16767db96d56Sopenharmony_ci    def test_write_overflow(self):
16777db96d56Sopenharmony_ci        writer = self.MockRawIO()
16787db96d56Sopenharmony_ci        bufio = self.tp(writer, 8)
16797db96d56Sopenharmony_ci        contents = b"abcdefghijklmnop"
16807db96d56Sopenharmony_ci        for n in range(0, len(contents), 3):
16817db96d56Sopenharmony_ci            bufio.write(contents[n:n+3])
16827db96d56Sopenharmony_ci        flushed = b"".join(writer._write_stack)
16837db96d56Sopenharmony_ci        # At least (total - 8) bytes were implicitly flushed, perhaps more
16847db96d56Sopenharmony_ci        # depending on the implementation.
16857db96d56Sopenharmony_ci        self.assertTrue(flushed.startswith(contents[:-8]), flushed)
16867db96d56Sopenharmony_ci
16877db96d56Sopenharmony_ci    def check_writes(self, intermediate_func):
16887db96d56Sopenharmony_ci        # Lots of writes, test the flushed output is as expected.
16897db96d56Sopenharmony_ci        contents = bytes(range(256)) * 1000
16907db96d56Sopenharmony_ci        n = 0
16917db96d56Sopenharmony_ci        writer = self.MockRawIO()
16927db96d56Sopenharmony_ci        bufio = self.tp(writer, 13)
16937db96d56Sopenharmony_ci        # Generator of write sizes: repeat each N 15 times then proceed to N+1
16947db96d56Sopenharmony_ci        def gen_sizes():
16957db96d56Sopenharmony_ci            for size in count(1):
16967db96d56Sopenharmony_ci                for i in range(15):
16977db96d56Sopenharmony_ci                    yield size
16987db96d56Sopenharmony_ci        sizes = gen_sizes()
16997db96d56Sopenharmony_ci        while n < len(contents):
17007db96d56Sopenharmony_ci            size = min(next(sizes), len(contents) - n)
17017db96d56Sopenharmony_ci            self.assertEqual(bufio.write(contents[n:n+size]), size)
17027db96d56Sopenharmony_ci            intermediate_func(bufio)
17037db96d56Sopenharmony_ci            n += size
17047db96d56Sopenharmony_ci        bufio.flush()
17057db96d56Sopenharmony_ci        self.assertEqual(contents, b"".join(writer._write_stack))
17067db96d56Sopenharmony_ci
17077db96d56Sopenharmony_ci    def test_writes(self):
17087db96d56Sopenharmony_ci        self.check_writes(lambda bufio: None)
17097db96d56Sopenharmony_ci
17107db96d56Sopenharmony_ci    def test_writes_and_flushes(self):
17117db96d56Sopenharmony_ci        self.check_writes(lambda bufio: bufio.flush())
17127db96d56Sopenharmony_ci
17137db96d56Sopenharmony_ci    def test_writes_and_seeks(self):
17147db96d56Sopenharmony_ci        def _seekabs(bufio):
17157db96d56Sopenharmony_ci            pos = bufio.tell()
17167db96d56Sopenharmony_ci            bufio.seek(pos + 1, 0)
17177db96d56Sopenharmony_ci            bufio.seek(pos - 1, 0)
17187db96d56Sopenharmony_ci            bufio.seek(pos, 0)
17197db96d56Sopenharmony_ci        self.check_writes(_seekabs)
17207db96d56Sopenharmony_ci        def _seekrel(bufio):
17217db96d56Sopenharmony_ci            pos = bufio.seek(0, 1)
17227db96d56Sopenharmony_ci            bufio.seek(+1, 1)
17237db96d56Sopenharmony_ci            bufio.seek(-1, 1)
17247db96d56Sopenharmony_ci            bufio.seek(pos, 0)
17257db96d56Sopenharmony_ci        self.check_writes(_seekrel)
17267db96d56Sopenharmony_ci
17277db96d56Sopenharmony_ci    def test_writes_and_truncates(self):
17287db96d56Sopenharmony_ci        self.check_writes(lambda bufio: bufio.truncate(bufio.tell()))
17297db96d56Sopenharmony_ci
17307db96d56Sopenharmony_ci    def test_write_non_blocking(self):
17317db96d56Sopenharmony_ci        raw = self.MockNonBlockWriterIO()
17327db96d56Sopenharmony_ci        bufio = self.tp(raw, 8)
17337db96d56Sopenharmony_ci
17347db96d56Sopenharmony_ci        self.assertEqual(bufio.write(b"abcd"), 4)
17357db96d56Sopenharmony_ci        self.assertEqual(bufio.write(b"efghi"), 5)
17367db96d56Sopenharmony_ci        # 1 byte will be written, the rest will be buffered
17377db96d56Sopenharmony_ci        raw.block_on(b"k")
17387db96d56Sopenharmony_ci        self.assertEqual(bufio.write(b"jklmn"), 5)
17397db96d56Sopenharmony_ci
17407db96d56Sopenharmony_ci        # 8 bytes will be written, 8 will be buffered and the rest will be lost
17417db96d56Sopenharmony_ci        raw.block_on(b"0")
17427db96d56Sopenharmony_ci        try:
17437db96d56Sopenharmony_ci            bufio.write(b"opqrwxyz0123456789")
17447db96d56Sopenharmony_ci        except self.BlockingIOError as e:
17457db96d56Sopenharmony_ci            written = e.characters_written
17467db96d56Sopenharmony_ci        else:
17477db96d56Sopenharmony_ci            self.fail("BlockingIOError should have been raised")
17487db96d56Sopenharmony_ci        self.assertEqual(written, 16)
17497db96d56Sopenharmony_ci        self.assertEqual(raw.pop_written(),
17507db96d56Sopenharmony_ci            b"abcdefghijklmnopqrwxyz")
17517db96d56Sopenharmony_ci
17527db96d56Sopenharmony_ci        self.assertEqual(bufio.write(b"ABCDEFGHI"), 9)
17537db96d56Sopenharmony_ci        s = raw.pop_written()
17547db96d56Sopenharmony_ci        # Previously buffered bytes were flushed
17557db96d56Sopenharmony_ci        self.assertTrue(s.startswith(b"01234567A"), s)
17567db96d56Sopenharmony_ci
17577db96d56Sopenharmony_ci    def test_write_and_rewind(self):
17587db96d56Sopenharmony_ci        raw = io.BytesIO()
17597db96d56Sopenharmony_ci        bufio = self.tp(raw, 4)
17607db96d56Sopenharmony_ci        self.assertEqual(bufio.write(b"abcdef"), 6)
17617db96d56Sopenharmony_ci        self.assertEqual(bufio.tell(), 6)
17627db96d56Sopenharmony_ci        bufio.seek(0, 0)
17637db96d56Sopenharmony_ci        self.assertEqual(bufio.write(b"XY"), 2)
17647db96d56Sopenharmony_ci        bufio.seek(6, 0)
17657db96d56Sopenharmony_ci        self.assertEqual(raw.getvalue(), b"XYcdef")
17667db96d56Sopenharmony_ci        self.assertEqual(bufio.write(b"123456"), 6)
17677db96d56Sopenharmony_ci        bufio.flush()
17687db96d56Sopenharmony_ci        self.assertEqual(raw.getvalue(), b"XYcdef123456")
17697db96d56Sopenharmony_ci
17707db96d56Sopenharmony_ci    def test_flush(self):
17717db96d56Sopenharmony_ci        writer = self.MockRawIO()
17727db96d56Sopenharmony_ci        bufio = self.tp(writer, 8)
17737db96d56Sopenharmony_ci        bufio.write(b"abc")
17747db96d56Sopenharmony_ci        bufio.flush()
17757db96d56Sopenharmony_ci        self.assertEqual(b"abc", writer._write_stack[0])
17767db96d56Sopenharmony_ci
17777db96d56Sopenharmony_ci    def test_writelines(self):
17787db96d56Sopenharmony_ci        l = [b'ab', b'cd', b'ef']
17797db96d56Sopenharmony_ci        writer = self.MockRawIO()
17807db96d56Sopenharmony_ci        bufio = self.tp(writer, 8)
17817db96d56Sopenharmony_ci        bufio.writelines(l)
17827db96d56Sopenharmony_ci        bufio.flush()
17837db96d56Sopenharmony_ci        self.assertEqual(b''.join(writer._write_stack), b'abcdef')
17847db96d56Sopenharmony_ci
17857db96d56Sopenharmony_ci    def test_writelines_userlist(self):
17867db96d56Sopenharmony_ci        l = UserList([b'ab', b'cd', b'ef'])
17877db96d56Sopenharmony_ci        writer = self.MockRawIO()
17887db96d56Sopenharmony_ci        bufio = self.tp(writer, 8)
17897db96d56Sopenharmony_ci        bufio.writelines(l)
17907db96d56Sopenharmony_ci        bufio.flush()
17917db96d56Sopenharmony_ci        self.assertEqual(b''.join(writer._write_stack), b'abcdef')
17927db96d56Sopenharmony_ci
17937db96d56Sopenharmony_ci    def test_writelines_error(self):
17947db96d56Sopenharmony_ci        writer = self.MockRawIO()
17957db96d56Sopenharmony_ci        bufio = self.tp(writer, 8)
17967db96d56Sopenharmony_ci        self.assertRaises(TypeError, bufio.writelines, [1, 2, 3])
17977db96d56Sopenharmony_ci        self.assertRaises(TypeError, bufio.writelines, None)
17987db96d56Sopenharmony_ci        self.assertRaises(TypeError, bufio.writelines, 'abc')
17997db96d56Sopenharmony_ci
18007db96d56Sopenharmony_ci    def test_destructor(self):
18017db96d56Sopenharmony_ci        writer = self.MockRawIO()
18027db96d56Sopenharmony_ci        bufio = self.tp(writer, 8)
18037db96d56Sopenharmony_ci        bufio.write(b"abc")
18047db96d56Sopenharmony_ci        del bufio
18057db96d56Sopenharmony_ci        support.gc_collect()
18067db96d56Sopenharmony_ci        self.assertEqual(b"abc", writer._write_stack[0])
18077db96d56Sopenharmony_ci
18087db96d56Sopenharmony_ci    def test_truncate(self):
18097db96d56Sopenharmony_ci        # Truncate implicitly flushes the buffer.
18107db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
18117db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, self.write_mode, buffering=0) as raw:
18127db96d56Sopenharmony_ci            bufio = self.tp(raw, 8)
18137db96d56Sopenharmony_ci            bufio.write(b"abcdef")
18147db96d56Sopenharmony_ci            self.assertEqual(bufio.truncate(3), 3)
18157db96d56Sopenharmony_ci            self.assertEqual(bufio.tell(), 6)
18167db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "rb", buffering=0) as f:
18177db96d56Sopenharmony_ci            self.assertEqual(f.read(), b"abc")
18187db96d56Sopenharmony_ci
18197db96d56Sopenharmony_ci    def test_truncate_after_write(self):
18207db96d56Sopenharmony_ci        # Ensure that truncate preserves the file position after
18217db96d56Sopenharmony_ci        # writes longer than the buffer size.
18227db96d56Sopenharmony_ci        # Issue: https://bugs.python.org/issue32228
18237db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
18247db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb") as f:
18257db96d56Sopenharmony_ci            # Fill with some buffer
18267db96d56Sopenharmony_ci            f.write(b'\x00' * 10000)
18277db96d56Sopenharmony_ci        buffer_sizes = [8192, 4096, 200]
18287db96d56Sopenharmony_ci        for buffer_size in buffer_sizes:
18297db96d56Sopenharmony_ci            with self.open(os_helper.TESTFN, "r+b", buffering=buffer_size) as f:
18307db96d56Sopenharmony_ci                f.write(b'\x00' * (buffer_size + 1))
18317db96d56Sopenharmony_ci                # After write write_pos and write_end are set to 0
18327db96d56Sopenharmony_ci                f.read(1)
18337db96d56Sopenharmony_ci                # read operation makes sure that pos != raw_pos
18347db96d56Sopenharmony_ci                f.truncate()
18357db96d56Sopenharmony_ci                self.assertEqual(f.tell(), buffer_size + 2)
18367db96d56Sopenharmony_ci
18377db96d56Sopenharmony_ci    @support.requires_resource('cpu')
18387db96d56Sopenharmony_ci    @threading_helper.requires_working_threading()
18397db96d56Sopenharmony_ci    def test_threads(self):
18407db96d56Sopenharmony_ci        try:
18417db96d56Sopenharmony_ci            # Write out many bytes from many threads and test they were
18427db96d56Sopenharmony_ci            # all flushed.
18437db96d56Sopenharmony_ci            N = 1000
18447db96d56Sopenharmony_ci            contents = bytes(range(256)) * N
18457db96d56Sopenharmony_ci            sizes = cycle([1, 19])
18467db96d56Sopenharmony_ci            n = 0
18477db96d56Sopenharmony_ci            queue = deque()
18487db96d56Sopenharmony_ci            while n < len(contents):
18497db96d56Sopenharmony_ci                size = next(sizes)
18507db96d56Sopenharmony_ci                queue.append(contents[n:n+size])
18517db96d56Sopenharmony_ci                n += size
18527db96d56Sopenharmony_ci            del contents
18537db96d56Sopenharmony_ci            # We use a real file object because it allows us to
18547db96d56Sopenharmony_ci            # exercise situations where the GIL is released before
18557db96d56Sopenharmony_ci            # writing the buffer to the raw streams. This is in addition
18567db96d56Sopenharmony_ci            # to concurrency issues due to switching threads in the middle
18577db96d56Sopenharmony_ci            # of Python code.
18587db96d56Sopenharmony_ci            with self.open(os_helper.TESTFN, self.write_mode, buffering=0) as raw:
18597db96d56Sopenharmony_ci                bufio = self.tp(raw, 8)
18607db96d56Sopenharmony_ci                errors = []
18617db96d56Sopenharmony_ci                def f():
18627db96d56Sopenharmony_ci                    try:
18637db96d56Sopenharmony_ci                        while True:
18647db96d56Sopenharmony_ci                            try:
18657db96d56Sopenharmony_ci                                s = queue.popleft()
18667db96d56Sopenharmony_ci                            except IndexError:
18677db96d56Sopenharmony_ci                                return
18687db96d56Sopenharmony_ci                            bufio.write(s)
18697db96d56Sopenharmony_ci                    except Exception as e:
18707db96d56Sopenharmony_ci                        errors.append(e)
18717db96d56Sopenharmony_ci                        raise
18727db96d56Sopenharmony_ci                threads = [threading.Thread(target=f) for x in range(20)]
18737db96d56Sopenharmony_ci                with threading_helper.start_threads(threads):
18747db96d56Sopenharmony_ci                    time.sleep(0.02) # yield
18757db96d56Sopenharmony_ci                self.assertFalse(errors,
18767db96d56Sopenharmony_ci                    "the following exceptions were caught: %r" % errors)
18777db96d56Sopenharmony_ci                bufio.close()
18787db96d56Sopenharmony_ci            with self.open(os_helper.TESTFN, "rb") as f:
18797db96d56Sopenharmony_ci                s = f.read()
18807db96d56Sopenharmony_ci            for i in range(256):
18817db96d56Sopenharmony_ci                self.assertEqual(s.count(bytes([i])), N)
18827db96d56Sopenharmony_ci        finally:
18837db96d56Sopenharmony_ci            os_helper.unlink(os_helper.TESTFN)
18847db96d56Sopenharmony_ci
18857db96d56Sopenharmony_ci    def test_misbehaved_io(self):
18867db96d56Sopenharmony_ci        rawio = self.MisbehavedRawIO()
18877db96d56Sopenharmony_ci        bufio = self.tp(rawio, 5)
18887db96d56Sopenharmony_ci        self.assertRaises(OSError, bufio.seek, 0)
18897db96d56Sopenharmony_ci        self.assertRaises(OSError, bufio.tell)
18907db96d56Sopenharmony_ci        self.assertRaises(OSError, bufio.write, b"abcdef")
18917db96d56Sopenharmony_ci
18927db96d56Sopenharmony_ci        # Silence destructor error
18937db96d56Sopenharmony_ci        bufio.close = lambda: None
18947db96d56Sopenharmony_ci
18957db96d56Sopenharmony_ci    def test_max_buffer_size_removal(self):
18967db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
18977db96d56Sopenharmony_ci            self.tp(self.MockRawIO(), 8, 12)
18987db96d56Sopenharmony_ci
18997db96d56Sopenharmony_ci    def test_write_error_on_close(self):
19007db96d56Sopenharmony_ci        raw = self.MockRawIO()
19017db96d56Sopenharmony_ci        def bad_write(b):
19027db96d56Sopenharmony_ci            raise OSError()
19037db96d56Sopenharmony_ci        raw.write = bad_write
19047db96d56Sopenharmony_ci        b = self.tp(raw)
19057db96d56Sopenharmony_ci        b.write(b'spam')
19067db96d56Sopenharmony_ci        self.assertRaises(OSError, b.close) # exception not swallowed
19077db96d56Sopenharmony_ci        self.assertTrue(b.closed)
19087db96d56Sopenharmony_ci
19097db96d56Sopenharmony_ci    @threading_helper.requires_working_threading()
19107db96d56Sopenharmony_ci    def test_slow_close_from_thread(self):
19117db96d56Sopenharmony_ci        # Issue #31976
19127db96d56Sopenharmony_ci        rawio = self.SlowFlushRawIO()
19137db96d56Sopenharmony_ci        bufio = self.tp(rawio, 8)
19147db96d56Sopenharmony_ci        t = threading.Thread(target=bufio.close)
19157db96d56Sopenharmony_ci        t.start()
19167db96d56Sopenharmony_ci        rawio.in_flush.wait()
19177db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.write, b'spam')
19187db96d56Sopenharmony_ci        self.assertTrue(bufio.closed)
19197db96d56Sopenharmony_ci        t.join()
19207db96d56Sopenharmony_ci
19217db96d56Sopenharmony_ci
19227db96d56Sopenharmony_ci
19237db96d56Sopenharmony_ciclass CBufferedWriterTest(BufferedWriterTest, SizeofTest):
19247db96d56Sopenharmony_ci    tp = io.BufferedWriter
19257db96d56Sopenharmony_ci
19267db96d56Sopenharmony_ci    @skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing "
19277db96d56Sopenharmony_ci                       "instead of returning NULL for malloc failure.")
19287db96d56Sopenharmony_ci    def test_constructor(self):
19297db96d56Sopenharmony_ci        BufferedWriterTest.test_constructor(self)
19307db96d56Sopenharmony_ci        # The allocation can succeed on 32-bit builds, e.g. with more
19317db96d56Sopenharmony_ci        # than 2 GiB RAM and a 64-bit kernel.
19327db96d56Sopenharmony_ci        if sys.maxsize > 0x7FFFFFFF:
19337db96d56Sopenharmony_ci            rawio = self.MockRawIO()
19347db96d56Sopenharmony_ci            bufio = self.tp(rawio)
19357db96d56Sopenharmony_ci            self.assertRaises((OverflowError, MemoryError, ValueError),
19367db96d56Sopenharmony_ci                bufio.__init__, rawio, sys.maxsize)
19377db96d56Sopenharmony_ci
19387db96d56Sopenharmony_ci    def test_initialization(self):
19397db96d56Sopenharmony_ci        rawio = self.MockRawIO()
19407db96d56Sopenharmony_ci        bufio = self.tp(rawio)
19417db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=0)
19427db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.write, b"def")
19437db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-16)
19447db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.write, b"def")
19457db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-1)
19467db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.write, b"def")
19477db96d56Sopenharmony_ci
19487db96d56Sopenharmony_ci    def test_garbage_collection(self):
19497db96d56Sopenharmony_ci        # C BufferedWriter objects are collected, and collecting them flushes
19507db96d56Sopenharmony_ci        # all data to disk.
19517db96d56Sopenharmony_ci        # The Python version has __del__, so it ends into gc.garbage instead
19527db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
19537db96d56Sopenharmony_ci        with warnings_helper.check_warnings(('', ResourceWarning)):
19547db96d56Sopenharmony_ci            rawio = self.FileIO(os_helper.TESTFN, "w+b")
19557db96d56Sopenharmony_ci            f = self.tp(rawio)
19567db96d56Sopenharmony_ci            f.write(b"123xxx")
19577db96d56Sopenharmony_ci            f.x = f
19587db96d56Sopenharmony_ci            wr = weakref.ref(f)
19597db96d56Sopenharmony_ci            del f
19607db96d56Sopenharmony_ci            support.gc_collect()
19617db96d56Sopenharmony_ci        self.assertIsNone(wr(), wr)
19627db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "rb") as f:
19637db96d56Sopenharmony_ci            self.assertEqual(f.read(), b"123xxx")
19647db96d56Sopenharmony_ci
19657db96d56Sopenharmony_ci    def test_args_error(self):
19667db96d56Sopenharmony_ci        # Issue #17275
19677db96d56Sopenharmony_ci        with self.assertRaisesRegex(TypeError, "BufferedWriter"):
19687db96d56Sopenharmony_ci            self.tp(io.BytesIO(), 1024, 1024, 1024)
19697db96d56Sopenharmony_ci
19707db96d56Sopenharmony_ci
19717db96d56Sopenharmony_ciclass PyBufferedWriterTest(BufferedWriterTest):
19727db96d56Sopenharmony_ci    tp = pyio.BufferedWriter
19737db96d56Sopenharmony_ci
19747db96d56Sopenharmony_ciclass BufferedRWPairTest(unittest.TestCase):
19757db96d56Sopenharmony_ci
19767db96d56Sopenharmony_ci    def test_constructor(self):
19777db96d56Sopenharmony_ci        pair = self.tp(self.MockRawIO(), self.MockRawIO())
19787db96d56Sopenharmony_ci        self.assertFalse(pair.closed)
19797db96d56Sopenharmony_ci
19807db96d56Sopenharmony_ci    def test_uninitialized(self):
19817db96d56Sopenharmony_ci        pair = self.tp.__new__(self.tp)
19827db96d56Sopenharmony_ci        del pair
19837db96d56Sopenharmony_ci        pair = self.tp.__new__(self.tp)
19847db96d56Sopenharmony_ci        self.assertRaisesRegex((ValueError, AttributeError),
19857db96d56Sopenharmony_ci                               'uninitialized|has no attribute',
19867db96d56Sopenharmony_ci                               pair.read, 0)
19877db96d56Sopenharmony_ci        self.assertRaisesRegex((ValueError, AttributeError),
19887db96d56Sopenharmony_ci                               'uninitialized|has no attribute',
19897db96d56Sopenharmony_ci                               pair.write, b'')
19907db96d56Sopenharmony_ci        pair.__init__(self.MockRawIO(), self.MockRawIO())
19917db96d56Sopenharmony_ci        self.assertEqual(pair.read(0), b'')
19927db96d56Sopenharmony_ci        self.assertEqual(pair.write(b''), 0)
19937db96d56Sopenharmony_ci
19947db96d56Sopenharmony_ci    def test_detach(self):
19957db96d56Sopenharmony_ci        pair = self.tp(self.MockRawIO(), self.MockRawIO())
19967db96d56Sopenharmony_ci        self.assertRaises(self.UnsupportedOperation, pair.detach)
19977db96d56Sopenharmony_ci
19987db96d56Sopenharmony_ci    def test_constructor_max_buffer_size_removal(self):
19997db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
20007db96d56Sopenharmony_ci            self.tp(self.MockRawIO(), self.MockRawIO(), 8, 12)
20017db96d56Sopenharmony_ci
20027db96d56Sopenharmony_ci    def test_constructor_with_not_readable(self):
20037db96d56Sopenharmony_ci        class NotReadable(MockRawIO):
20047db96d56Sopenharmony_ci            def readable(self):
20057db96d56Sopenharmony_ci                return False
20067db96d56Sopenharmony_ci
20077db96d56Sopenharmony_ci        self.assertRaises(OSError, self.tp, NotReadable(), self.MockRawIO())
20087db96d56Sopenharmony_ci
20097db96d56Sopenharmony_ci    def test_constructor_with_not_writeable(self):
20107db96d56Sopenharmony_ci        class NotWriteable(MockRawIO):
20117db96d56Sopenharmony_ci            def writable(self):
20127db96d56Sopenharmony_ci                return False
20137db96d56Sopenharmony_ci
20147db96d56Sopenharmony_ci        self.assertRaises(OSError, self.tp, self.MockRawIO(), NotWriteable())
20157db96d56Sopenharmony_ci
20167db96d56Sopenharmony_ci    def test_read(self):
20177db96d56Sopenharmony_ci        pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO())
20187db96d56Sopenharmony_ci
20197db96d56Sopenharmony_ci        self.assertEqual(pair.read(3), b"abc")
20207db96d56Sopenharmony_ci        self.assertEqual(pair.read(1), b"d")
20217db96d56Sopenharmony_ci        self.assertEqual(pair.read(), b"ef")
20227db96d56Sopenharmony_ci        pair = self.tp(self.BytesIO(b"abc"), self.MockRawIO())
20237db96d56Sopenharmony_ci        self.assertEqual(pair.read(None), b"abc")
20247db96d56Sopenharmony_ci
20257db96d56Sopenharmony_ci    def test_readlines(self):
20267db96d56Sopenharmony_ci        pair = lambda: self.tp(self.BytesIO(b"abc\ndef\nh"), self.MockRawIO())
20277db96d56Sopenharmony_ci        self.assertEqual(pair().readlines(), [b"abc\n", b"def\n", b"h"])
20287db96d56Sopenharmony_ci        self.assertEqual(pair().readlines(), [b"abc\n", b"def\n", b"h"])
20297db96d56Sopenharmony_ci        self.assertEqual(pair().readlines(5), [b"abc\n", b"def\n"])
20307db96d56Sopenharmony_ci
20317db96d56Sopenharmony_ci    def test_read1(self):
20327db96d56Sopenharmony_ci        # .read1() is delegated to the underlying reader object, so this test
20337db96d56Sopenharmony_ci        # can be shallow.
20347db96d56Sopenharmony_ci        pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO())
20357db96d56Sopenharmony_ci
20367db96d56Sopenharmony_ci        self.assertEqual(pair.read1(3), b"abc")
20377db96d56Sopenharmony_ci        self.assertEqual(pair.read1(), b"def")
20387db96d56Sopenharmony_ci
20397db96d56Sopenharmony_ci    def test_readinto(self):
20407db96d56Sopenharmony_ci        for method in ("readinto", "readinto1"):
20417db96d56Sopenharmony_ci            with self.subTest(method):
20427db96d56Sopenharmony_ci                pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO())
20437db96d56Sopenharmony_ci
20447db96d56Sopenharmony_ci                data = byteslike(b'\0' * 5)
20457db96d56Sopenharmony_ci                self.assertEqual(getattr(pair, method)(data), 5)
20467db96d56Sopenharmony_ci                self.assertEqual(bytes(data), b"abcde")
20477db96d56Sopenharmony_ci
20487db96d56Sopenharmony_ci    def test_write(self):
20497db96d56Sopenharmony_ci        w = self.MockRawIO()
20507db96d56Sopenharmony_ci        pair = self.tp(self.MockRawIO(), w)
20517db96d56Sopenharmony_ci
20527db96d56Sopenharmony_ci        pair.write(b"abc")
20537db96d56Sopenharmony_ci        pair.flush()
20547db96d56Sopenharmony_ci        buffer = bytearray(b"def")
20557db96d56Sopenharmony_ci        pair.write(buffer)
20567db96d56Sopenharmony_ci        buffer[:] = b"***"  # Overwrite our copy of the data
20577db96d56Sopenharmony_ci        pair.flush()
20587db96d56Sopenharmony_ci        self.assertEqual(w._write_stack, [b"abc", b"def"])
20597db96d56Sopenharmony_ci
20607db96d56Sopenharmony_ci    def test_peek(self):
20617db96d56Sopenharmony_ci        pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO())
20627db96d56Sopenharmony_ci
20637db96d56Sopenharmony_ci        self.assertTrue(pair.peek(3).startswith(b"abc"))
20647db96d56Sopenharmony_ci        self.assertEqual(pair.read(3), b"abc")
20657db96d56Sopenharmony_ci
20667db96d56Sopenharmony_ci    def test_readable(self):
20677db96d56Sopenharmony_ci        pair = self.tp(self.MockRawIO(), self.MockRawIO())
20687db96d56Sopenharmony_ci        self.assertTrue(pair.readable())
20697db96d56Sopenharmony_ci
20707db96d56Sopenharmony_ci    def test_writeable(self):
20717db96d56Sopenharmony_ci        pair = self.tp(self.MockRawIO(), self.MockRawIO())
20727db96d56Sopenharmony_ci        self.assertTrue(pair.writable())
20737db96d56Sopenharmony_ci
20747db96d56Sopenharmony_ci    def test_seekable(self):
20757db96d56Sopenharmony_ci        # BufferedRWPairs are never seekable, even if their readers and writers
20767db96d56Sopenharmony_ci        # are.
20777db96d56Sopenharmony_ci        pair = self.tp(self.MockRawIO(), self.MockRawIO())
20787db96d56Sopenharmony_ci        self.assertFalse(pair.seekable())
20797db96d56Sopenharmony_ci
20807db96d56Sopenharmony_ci    # .flush() is delegated to the underlying writer object and has been
20817db96d56Sopenharmony_ci    # tested in the test_write method.
20827db96d56Sopenharmony_ci
20837db96d56Sopenharmony_ci    def test_close_and_closed(self):
20847db96d56Sopenharmony_ci        pair = self.tp(self.MockRawIO(), self.MockRawIO())
20857db96d56Sopenharmony_ci        self.assertFalse(pair.closed)
20867db96d56Sopenharmony_ci        pair.close()
20877db96d56Sopenharmony_ci        self.assertTrue(pair.closed)
20887db96d56Sopenharmony_ci
20897db96d56Sopenharmony_ci    def test_reader_close_error_on_close(self):
20907db96d56Sopenharmony_ci        def reader_close():
20917db96d56Sopenharmony_ci            reader_non_existing
20927db96d56Sopenharmony_ci        reader = self.MockRawIO()
20937db96d56Sopenharmony_ci        reader.close = reader_close
20947db96d56Sopenharmony_ci        writer = self.MockRawIO()
20957db96d56Sopenharmony_ci        pair = self.tp(reader, writer)
20967db96d56Sopenharmony_ci        with self.assertRaises(NameError) as err:
20977db96d56Sopenharmony_ci            pair.close()
20987db96d56Sopenharmony_ci        self.assertIn('reader_non_existing', str(err.exception))
20997db96d56Sopenharmony_ci        self.assertTrue(pair.closed)
21007db96d56Sopenharmony_ci        self.assertFalse(reader.closed)
21017db96d56Sopenharmony_ci        self.assertTrue(writer.closed)
21027db96d56Sopenharmony_ci
21037db96d56Sopenharmony_ci        # Silence destructor error
21047db96d56Sopenharmony_ci        reader.close = lambda: None
21057db96d56Sopenharmony_ci
21067db96d56Sopenharmony_ci    def test_writer_close_error_on_close(self):
21077db96d56Sopenharmony_ci        def writer_close():
21087db96d56Sopenharmony_ci            writer_non_existing
21097db96d56Sopenharmony_ci        reader = self.MockRawIO()
21107db96d56Sopenharmony_ci        writer = self.MockRawIO()
21117db96d56Sopenharmony_ci        writer.close = writer_close
21127db96d56Sopenharmony_ci        pair = self.tp(reader, writer)
21137db96d56Sopenharmony_ci        with self.assertRaises(NameError) as err:
21147db96d56Sopenharmony_ci            pair.close()
21157db96d56Sopenharmony_ci        self.assertIn('writer_non_existing', str(err.exception))
21167db96d56Sopenharmony_ci        self.assertFalse(pair.closed)
21177db96d56Sopenharmony_ci        self.assertTrue(reader.closed)
21187db96d56Sopenharmony_ci        self.assertFalse(writer.closed)
21197db96d56Sopenharmony_ci
21207db96d56Sopenharmony_ci        # Silence destructor error
21217db96d56Sopenharmony_ci        writer.close = lambda: None
21227db96d56Sopenharmony_ci        writer = None
21237db96d56Sopenharmony_ci
21247db96d56Sopenharmony_ci        # Ignore BufferedWriter (of the BufferedRWPair) unraisable exception
21257db96d56Sopenharmony_ci        with support.catch_unraisable_exception():
21267db96d56Sopenharmony_ci            # Ignore BufferedRWPair unraisable exception
21277db96d56Sopenharmony_ci            with support.catch_unraisable_exception():
21287db96d56Sopenharmony_ci                pair = None
21297db96d56Sopenharmony_ci                support.gc_collect()
21307db96d56Sopenharmony_ci            support.gc_collect()
21317db96d56Sopenharmony_ci
21327db96d56Sopenharmony_ci    def test_reader_writer_close_error_on_close(self):
21337db96d56Sopenharmony_ci        def reader_close():
21347db96d56Sopenharmony_ci            reader_non_existing
21357db96d56Sopenharmony_ci        def writer_close():
21367db96d56Sopenharmony_ci            writer_non_existing
21377db96d56Sopenharmony_ci        reader = self.MockRawIO()
21387db96d56Sopenharmony_ci        reader.close = reader_close
21397db96d56Sopenharmony_ci        writer = self.MockRawIO()
21407db96d56Sopenharmony_ci        writer.close = writer_close
21417db96d56Sopenharmony_ci        pair = self.tp(reader, writer)
21427db96d56Sopenharmony_ci        with self.assertRaises(NameError) as err:
21437db96d56Sopenharmony_ci            pair.close()
21447db96d56Sopenharmony_ci        self.assertIn('reader_non_existing', str(err.exception))
21457db96d56Sopenharmony_ci        self.assertIsInstance(err.exception.__context__, NameError)
21467db96d56Sopenharmony_ci        self.assertIn('writer_non_existing', str(err.exception.__context__))
21477db96d56Sopenharmony_ci        self.assertFalse(pair.closed)
21487db96d56Sopenharmony_ci        self.assertFalse(reader.closed)
21497db96d56Sopenharmony_ci        self.assertFalse(writer.closed)
21507db96d56Sopenharmony_ci
21517db96d56Sopenharmony_ci        # Silence destructor error
21527db96d56Sopenharmony_ci        reader.close = lambda: None
21537db96d56Sopenharmony_ci        writer.close = lambda: None
21547db96d56Sopenharmony_ci
21557db96d56Sopenharmony_ci    def test_isatty(self):
21567db96d56Sopenharmony_ci        class SelectableIsAtty(MockRawIO):
21577db96d56Sopenharmony_ci            def __init__(self, isatty):
21587db96d56Sopenharmony_ci                MockRawIO.__init__(self)
21597db96d56Sopenharmony_ci                self._isatty = isatty
21607db96d56Sopenharmony_ci
21617db96d56Sopenharmony_ci            def isatty(self):
21627db96d56Sopenharmony_ci                return self._isatty
21637db96d56Sopenharmony_ci
21647db96d56Sopenharmony_ci        pair = self.tp(SelectableIsAtty(False), SelectableIsAtty(False))
21657db96d56Sopenharmony_ci        self.assertFalse(pair.isatty())
21667db96d56Sopenharmony_ci
21677db96d56Sopenharmony_ci        pair = self.tp(SelectableIsAtty(True), SelectableIsAtty(False))
21687db96d56Sopenharmony_ci        self.assertTrue(pair.isatty())
21697db96d56Sopenharmony_ci
21707db96d56Sopenharmony_ci        pair = self.tp(SelectableIsAtty(False), SelectableIsAtty(True))
21717db96d56Sopenharmony_ci        self.assertTrue(pair.isatty())
21727db96d56Sopenharmony_ci
21737db96d56Sopenharmony_ci        pair = self.tp(SelectableIsAtty(True), SelectableIsAtty(True))
21747db96d56Sopenharmony_ci        self.assertTrue(pair.isatty())
21757db96d56Sopenharmony_ci
21767db96d56Sopenharmony_ci    def test_weakref_clearing(self):
21777db96d56Sopenharmony_ci        brw = self.tp(self.MockRawIO(), self.MockRawIO())
21787db96d56Sopenharmony_ci        ref = weakref.ref(brw)
21797db96d56Sopenharmony_ci        brw = None
21807db96d56Sopenharmony_ci        ref = None # Shouldn't segfault.
21817db96d56Sopenharmony_ci
21827db96d56Sopenharmony_ciclass CBufferedRWPairTest(BufferedRWPairTest):
21837db96d56Sopenharmony_ci    tp = io.BufferedRWPair
21847db96d56Sopenharmony_ci
21857db96d56Sopenharmony_ciclass PyBufferedRWPairTest(BufferedRWPairTest):
21867db96d56Sopenharmony_ci    tp = pyio.BufferedRWPair
21877db96d56Sopenharmony_ci
21887db96d56Sopenharmony_ci
21897db96d56Sopenharmony_ciclass BufferedRandomTest(BufferedReaderTest, BufferedWriterTest):
21907db96d56Sopenharmony_ci    read_mode = "rb+"
21917db96d56Sopenharmony_ci    write_mode = "wb+"
21927db96d56Sopenharmony_ci
21937db96d56Sopenharmony_ci    def test_constructor(self):
21947db96d56Sopenharmony_ci        BufferedReaderTest.test_constructor(self)
21957db96d56Sopenharmony_ci        BufferedWriterTest.test_constructor(self)
21967db96d56Sopenharmony_ci
21977db96d56Sopenharmony_ci    def test_uninitialized(self):
21987db96d56Sopenharmony_ci        BufferedReaderTest.test_uninitialized(self)
21997db96d56Sopenharmony_ci        BufferedWriterTest.test_uninitialized(self)
22007db96d56Sopenharmony_ci
22017db96d56Sopenharmony_ci    def test_read_and_write(self):
22027db96d56Sopenharmony_ci        raw = self.MockRawIO((b"asdf", b"ghjk"))
22037db96d56Sopenharmony_ci        rw = self.tp(raw, 8)
22047db96d56Sopenharmony_ci
22057db96d56Sopenharmony_ci        self.assertEqual(b"as", rw.read(2))
22067db96d56Sopenharmony_ci        rw.write(b"ddd")
22077db96d56Sopenharmony_ci        rw.write(b"eee")
22087db96d56Sopenharmony_ci        self.assertFalse(raw._write_stack) # Buffer writes
22097db96d56Sopenharmony_ci        self.assertEqual(b"ghjk", rw.read())
22107db96d56Sopenharmony_ci        self.assertEqual(b"dddeee", raw._write_stack[0])
22117db96d56Sopenharmony_ci
22127db96d56Sopenharmony_ci    def test_seek_and_tell(self):
22137db96d56Sopenharmony_ci        raw = self.BytesIO(b"asdfghjkl")
22147db96d56Sopenharmony_ci        rw = self.tp(raw)
22157db96d56Sopenharmony_ci
22167db96d56Sopenharmony_ci        self.assertEqual(b"as", rw.read(2))
22177db96d56Sopenharmony_ci        self.assertEqual(2, rw.tell())
22187db96d56Sopenharmony_ci        rw.seek(0, 0)
22197db96d56Sopenharmony_ci        self.assertEqual(b"asdf", rw.read(4))
22207db96d56Sopenharmony_ci
22217db96d56Sopenharmony_ci        rw.write(b"123f")
22227db96d56Sopenharmony_ci        rw.seek(0, 0)
22237db96d56Sopenharmony_ci        self.assertEqual(b"asdf123fl", rw.read())
22247db96d56Sopenharmony_ci        self.assertEqual(9, rw.tell())
22257db96d56Sopenharmony_ci        rw.seek(-4, 2)
22267db96d56Sopenharmony_ci        self.assertEqual(5, rw.tell())
22277db96d56Sopenharmony_ci        rw.seek(2, 1)
22287db96d56Sopenharmony_ci        self.assertEqual(7, rw.tell())
22297db96d56Sopenharmony_ci        self.assertEqual(b"fl", rw.read(11))
22307db96d56Sopenharmony_ci        rw.flush()
22317db96d56Sopenharmony_ci        self.assertEqual(b"asdf123fl", raw.getvalue())
22327db96d56Sopenharmony_ci
22337db96d56Sopenharmony_ci        self.assertRaises(TypeError, rw.seek, 0.0)
22347db96d56Sopenharmony_ci
22357db96d56Sopenharmony_ci    def check_flush_and_read(self, read_func):
22367db96d56Sopenharmony_ci        raw = self.BytesIO(b"abcdefghi")
22377db96d56Sopenharmony_ci        bufio = self.tp(raw)
22387db96d56Sopenharmony_ci
22397db96d56Sopenharmony_ci        self.assertEqual(b"ab", read_func(bufio, 2))
22407db96d56Sopenharmony_ci        bufio.write(b"12")
22417db96d56Sopenharmony_ci        self.assertEqual(b"ef", read_func(bufio, 2))
22427db96d56Sopenharmony_ci        self.assertEqual(6, bufio.tell())
22437db96d56Sopenharmony_ci        bufio.flush()
22447db96d56Sopenharmony_ci        self.assertEqual(6, bufio.tell())
22457db96d56Sopenharmony_ci        self.assertEqual(b"ghi", read_func(bufio))
22467db96d56Sopenharmony_ci        raw.seek(0, 0)
22477db96d56Sopenharmony_ci        raw.write(b"XYZ")
22487db96d56Sopenharmony_ci        # flush() resets the read buffer
22497db96d56Sopenharmony_ci        bufio.flush()
22507db96d56Sopenharmony_ci        bufio.seek(0, 0)
22517db96d56Sopenharmony_ci        self.assertEqual(b"XYZ", read_func(bufio, 3))
22527db96d56Sopenharmony_ci
22537db96d56Sopenharmony_ci    def test_flush_and_read(self):
22547db96d56Sopenharmony_ci        self.check_flush_and_read(lambda bufio, *args: bufio.read(*args))
22557db96d56Sopenharmony_ci
22567db96d56Sopenharmony_ci    def test_flush_and_readinto(self):
22577db96d56Sopenharmony_ci        def _readinto(bufio, n=-1):
22587db96d56Sopenharmony_ci            b = bytearray(n if n >= 0 else 9999)
22597db96d56Sopenharmony_ci            n = bufio.readinto(b)
22607db96d56Sopenharmony_ci            return bytes(b[:n])
22617db96d56Sopenharmony_ci        self.check_flush_and_read(_readinto)
22627db96d56Sopenharmony_ci
22637db96d56Sopenharmony_ci    def test_flush_and_peek(self):
22647db96d56Sopenharmony_ci        def _peek(bufio, n=-1):
22657db96d56Sopenharmony_ci            # This relies on the fact that the buffer can contain the whole
22667db96d56Sopenharmony_ci            # raw stream, otherwise peek() can return less.
22677db96d56Sopenharmony_ci            b = bufio.peek(n)
22687db96d56Sopenharmony_ci            if n != -1:
22697db96d56Sopenharmony_ci                b = b[:n]
22707db96d56Sopenharmony_ci            bufio.seek(len(b), 1)
22717db96d56Sopenharmony_ci            return b
22727db96d56Sopenharmony_ci        self.check_flush_and_read(_peek)
22737db96d56Sopenharmony_ci
22747db96d56Sopenharmony_ci    def test_flush_and_write(self):
22757db96d56Sopenharmony_ci        raw = self.BytesIO(b"abcdefghi")
22767db96d56Sopenharmony_ci        bufio = self.tp(raw)
22777db96d56Sopenharmony_ci
22787db96d56Sopenharmony_ci        bufio.write(b"123")
22797db96d56Sopenharmony_ci        bufio.flush()
22807db96d56Sopenharmony_ci        bufio.write(b"45")
22817db96d56Sopenharmony_ci        bufio.flush()
22827db96d56Sopenharmony_ci        bufio.seek(0, 0)
22837db96d56Sopenharmony_ci        self.assertEqual(b"12345fghi", raw.getvalue())
22847db96d56Sopenharmony_ci        self.assertEqual(b"12345fghi", bufio.read())
22857db96d56Sopenharmony_ci
22867db96d56Sopenharmony_ci    def test_threads(self):
22877db96d56Sopenharmony_ci        BufferedReaderTest.test_threads(self)
22887db96d56Sopenharmony_ci        BufferedWriterTest.test_threads(self)
22897db96d56Sopenharmony_ci
22907db96d56Sopenharmony_ci    def test_writes_and_peek(self):
22917db96d56Sopenharmony_ci        def _peek(bufio):
22927db96d56Sopenharmony_ci            bufio.peek(1)
22937db96d56Sopenharmony_ci        self.check_writes(_peek)
22947db96d56Sopenharmony_ci        def _peek(bufio):
22957db96d56Sopenharmony_ci            pos = bufio.tell()
22967db96d56Sopenharmony_ci            bufio.seek(-1, 1)
22977db96d56Sopenharmony_ci            bufio.peek(1)
22987db96d56Sopenharmony_ci            bufio.seek(pos, 0)
22997db96d56Sopenharmony_ci        self.check_writes(_peek)
23007db96d56Sopenharmony_ci
23017db96d56Sopenharmony_ci    def test_writes_and_reads(self):
23027db96d56Sopenharmony_ci        def _read(bufio):
23037db96d56Sopenharmony_ci            bufio.seek(-1, 1)
23047db96d56Sopenharmony_ci            bufio.read(1)
23057db96d56Sopenharmony_ci        self.check_writes(_read)
23067db96d56Sopenharmony_ci
23077db96d56Sopenharmony_ci    def test_writes_and_read1s(self):
23087db96d56Sopenharmony_ci        def _read1(bufio):
23097db96d56Sopenharmony_ci            bufio.seek(-1, 1)
23107db96d56Sopenharmony_ci            bufio.read1(1)
23117db96d56Sopenharmony_ci        self.check_writes(_read1)
23127db96d56Sopenharmony_ci
23137db96d56Sopenharmony_ci    def test_writes_and_readintos(self):
23147db96d56Sopenharmony_ci        def _read(bufio):
23157db96d56Sopenharmony_ci            bufio.seek(-1, 1)
23167db96d56Sopenharmony_ci            bufio.readinto(bytearray(1))
23177db96d56Sopenharmony_ci        self.check_writes(_read)
23187db96d56Sopenharmony_ci
23197db96d56Sopenharmony_ci    def test_write_after_readahead(self):
23207db96d56Sopenharmony_ci        # Issue #6629: writing after the buffer was filled by readahead should
23217db96d56Sopenharmony_ci        # first rewind the raw stream.
23227db96d56Sopenharmony_ci        for overwrite_size in [1, 5]:
23237db96d56Sopenharmony_ci            raw = self.BytesIO(b"A" * 10)
23247db96d56Sopenharmony_ci            bufio = self.tp(raw, 4)
23257db96d56Sopenharmony_ci            # Trigger readahead
23267db96d56Sopenharmony_ci            self.assertEqual(bufio.read(1), b"A")
23277db96d56Sopenharmony_ci            self.assertEqual(bufio.tell(), 1)
23287db96d56Sopenharmony_ci            # Overwriting should rewind the raw stream if it needs so
23297db96d56Sopenharmony_ci            bufio.write(b"B" * overwrite_size)
23307db96d56Sopenharmony_ci            self.assertEqual(bufio.tell(), overwrite_size + 1)
23317db96d56Sopenharmony_ci            # If the write size was smaller than the buffer size, flush() and
23327db96d56Sopenharmony_ci            # check that rewind happens.
23337db96d56Sopenharmony_ci            bufio.flush()
23347db96d56Sopenharmony_ci            self.assertEqual(bufio.tell(), overwrite_size + 1)
23357db96d56Sopenharmony_ci            s = raw.getvalue()
23367db96d56Sopenharmony_ci            self.assertEqual(s,
23377db96d56Sopenharmony_ci                b"A" + b"B" * overwrite_size + b"A" * (9 - overwrite_size))
23387db96d56Sopenharmony_ci
23397db96d56Sopenharmony_ci    def test_write_rewind_write(self):
23407db96d56Sopenharmony_ci        # Various combinations of reading / writing / seeking backwards / writing again
23417db96d56Sopenharmony_ci        def mutate(bufio, pos1, pos2):
23427db96d56Sopenharmony_ci            assert pos2 >= pos1
23437db96d56Sopenharmony_ci            # Fill the buffer
23447db96d56Sopenharmony_ci            bufio.seek(pos1)
23457db96d56Sopenharmony_ci            bufio.read(pos2 - pos1)
23467db96d56Sopenharmony_ci            bufio.write(b'\x02')
23477db96d56Sopenharmony_ci            # This writes earlier than the previous write, but still inside
23487db96d56Sopenharmony_ci            # the buffer.
23497db96d56Sopenharmony_ci            bufio.seek(pos1)
23507db96d56Sopenharmony_ci            bufio.write(b'\x01')
23517db96d56Sopenharmony_ci
23527db96d56Sopenharmony_ci        b = b"\x80\x81\x82\x83\x84"
23537db96d56Sopenharmony_ci        for i in range(0, len(b)):
23547db96d56Sopenharmony_ci            for j in range(i, len(b)):
23557db96d56Sopenharmony_ci                raw = self.BytesIO(b)
23567db96d56Sopenharmony_ci                bufio = self.tp(raw, 100)
23577db96d56Sopenharmony_ci                mutate(bufio, i, j)
23587db96d56Sopenharmony_ci                bufio.flush()
23597db96d56Sopenharmony_ci                expected = bytearray(b)
23607db96d56Sopenharmony_ci                expected[j] = 2
23617db96d56Sopenharmony_ci                expected[i] = 1
23627db96d56Sopenharmony_ci                self.assertEqual(raw.getvalue(), expected,
23637db96d56Sopenharmony_ci                                 "failed result for i=%d, j=%d" % (i, j))
23647db96d56Sopenharmony_ci
23657db96d56Sopenharmony_ci    def test_truncate_after_read_or_write(self):
23667db96d56Sopenharmony_ci        raw = self.BytesIO(b"A" * 10)
23677db96d56Sopenharmony_ci        bufio = self.tp(raw, 100)
23687db96d56Sopenharmony_ci        self.assertEqual(bufio.read(2), b"AA") # the read buffer gets filled
23697db96d56Sopenharmony_ci        self.assertEqual(bufio.truncate(), 2)
23707db96d56Sopenharmony_ci        self.assertEqual(bufio.write(b"BB"), 2) # the write buffer increases
23717db96d56Sopenharmony_ci        self.assertEqual(bufio.truncate(), 4)
23727db96d56Sopenharmony_ci
23737db96d56Sopenharmony_ci    def test_misbehaved_io(self):
23747db96d56Sopenharmony_ci        BufferedReaderTest.test_misbehaved_io(self)
23757db96d56Sopenharmony_ci        BufferedWriterTest.test_misbehaved_io(self)
23767db96d56Sopenharmony_ci
23777db96d56Sopenharmony_ci    def test_interleaved_read_write(self):
23787db96d56Sopenharmony_ci        # Test for issue #12213
23797db96d56Sopenharmony_ci        with self.BytesIO(b'abcdefgh') as raw:
23807db96d56Sopenharmony_ci            with self.tp(raw, 100) as f:
23817db96d56Sopenharmony_ci                f.write(b"1")
23827db96d56Sopenharmony_ci                self.assertEqual(f.read(1), b'b')
23837db96d56Sopenharmony_ci                f.write(b'2')
23847db96d56Sopenharmony_ci                self.assertEqual(f.read1(1), b'd')
23857db96d56Sopenharmony_ci                f.write(b'3')
23867db96d56Sopenharmony_ci                buf = bytearray(1)
23877db96d56Sopenharmony_ci                f.readinto(buf)
23887db96d56Sopenharmony_ci                self.assertEqual(buf, b'f')
23897db96d56Sopenharmony_ci                f.write(b'4')
23907db96d56Sopenharmony_ci                self.assertEqual(f.peek(1), b'h')
23917db96d56Sopenharmony_ci                f.flush()
23927db96d56Sopenharmony_ci                self.assertEqual(raw.getvalue(), b'1b2d3f4h')
23937db96d56Sopenharmony_ci
23947db96d56Sopenharmony_ci        with self.BytesIO(b'abc') as raw:
23957db96d56Sopenharmony_ci            with self.tp(raw, 100) as f:
23967db96d56Sopenharmony_ci                self.assertEqual(f.read(1), b'a')
23977db96d56Sopenharmony_ci                f.write(b"2")
23987db96d56Sopenharmony_ci                self.assertEqual(f.read(1), b'c')
23997db96d56Sopenharmony_ci                f.flush()
24007db96d56Sopenharmony_ci                self.assertEqual(raw.getvalue(), b'a2c')
24017db96d56Sopenharmony_ci
24027db96d56Sopenharmony_ci    def test_interleaved_readline_write(self):
24037db96d56Sopenharmony_ci        with self.BytesIO(b'ab\ncdef\ng\n') as raw:
24047db96d56Sopenharmony_ci            with self.tp(raw) as f:
24057db96d56Sopenharmony_ci                f.write(b'1')
24067db96d56Sopenharmony_ci                self.assertEqual(f.readline(), b'b\n')
24077db96d56Sopenharmony_ci                f.write(b'2')
24087db96d56Sopenharmony_ci                self.assertEqual(f.readline(), b'def\n')
24097db96d56Sopenharmony_ci                f.write(b'3')
24107db96d56Sopenharmony_ci                self.assertEqual(f.readline(), b'\n')
24117db96d56Sopenharmony_ci                f.flush()
24127db96d56Sopenharmony_ci                self.assertEqual(raw.getvalue(), b'1b\n2def\n3\n')
24137db96d56Sopenharmony_ci
24147db96d56Sopenharmony_ci    # You can't construct a BufferedRandom over a non-seekable stream.
24157db96d56Sopenharmony_ci    test_unseekable = None
24167db96d56Sopenharmony_ci
24177db96d56Sopenharmony_ci    # writable() returns True, so there's no point to test it over
24187db96d56Sopenharmony_ci    # a writable stream.
24197db96d56Sopenharmony_ci    test_truncate_on_read_only = None
24207db96d56Sopenharmony_ci
24217db96d56Sopenharmony_ci
24227db96d56Sopenharmony_ciclass CBufferedRandomTest(BufferedRandomTest, SizeofTest):
24237db96d56Sopenharmony_ci    tp = io.BufferedRandom
24247db96d56Sopenharmony_ci
24257db96d56Sopenharmony_ci    @skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing "
24267db96d56Sopenharmony_ci                       "instead of returning NULL for malloc failure.")
24277db96d56Sopenharmony_ci    def test_constructor(self):
24287db96d56Sopenharmony_ci        BufferedRandomTest.test_constructor(self)
24297db96d56Sopenharmony_ci        # The allocation can succeed on 32-bit builds, e.g. with more
24307db96d56Sopenharmony_ci        # than 2 GiB RAM and a 64-bit kernel.
24317db96d56Sopenharmony_ci        if sys.maxsize > 0x7FFFFFFF:
24327db96d56Sopenharmony_ci            rawio = self.MockRawIO()
24337db96d56Sopenharmony_ci            bufio = self.tp(rawio)
24347db96d56Sopenharmony_ci            self.assertRaises((OverflowError, MemoryError, ValueError),
24357db96d56Sopenharmony_ci                bufio.__init__, rawio, sys.maxsize)
24367db96d56Sopenharmony_ci
24377db96d56Sopenharmony_ci    def test_garbage_collection(self):
24387db96d56Sopenharmony_ci        CBufferedReaderTest.test_garbage_collection(self)
24397db96d56Sopenharmony_ci        CBufferedWriterTest.test_garbage_collection(self)
24407db96d56Sopenharmony_ci
24417db96d56Sopenharmony_ci    def test_args_error(self):
24427db96d56Sopenharmony_ci        # Issue #17275
24437db96d56Sopenharmony_ci        with self.assertRaisesRegex(TypeError, "BufferedRandom"):
24447db96d56Sopenharmony_ci            self.tp(io.BytesIO(), 1024, 1024, 1024)
24457db96d56Sopenharmony_ci
24467db96d56Sopenharmony_ci
24477db96d56Sopenharmony_ciclass PyBufferedRandomTest(BufferedRandomTest):
24487db96d56Sopenharmony_ci    tp = pyio.BufferedRandom
24497db96d56Sopenharmony_ci
24507db96d56Sopenharmony_ci
24517db96d56Sopenharmony_ci# To fully exercise seek/tell, the StatefulIncrementalDecoder has these
24527db96d56Sopenharmony_ci# properties:
24537db96d56Sopenharmony_ci#   - A single output character can correspond to many bytes of input.
24547db96d56Sopenharmony_ci#   - The number of input bytes to complete the character can be
24557db96d56Sopenharmony_ci#     undetermined until the last input byte is received.
24567db96d56Sopenharmony_ci#   - The number of input bytes can vary depending on previous input.
24577db96d56Sopenharmony_ci#   - A single input byte can correspond to many characters of output.
24587db96d56Sopenharmony_ci#   - The number of output characters can be undetermined until the
24597db96d56Sopenharmony_ci#     last input byte is received.
24607db96d56Sopenharmony_ci#   - The number of output characters can vary depending on previous input.
24617db96d56Sopenharmony_ci
24627db96d56Sopenharmony_ciclass StatefulIncrementalDecoder(codecs.IncrementalDecoder):
24637db96d56Sopenharmony_ci    """
24647db96d56Sopenharmony_ci    For testing seek/tell behavior with a stateful, buffering decoder.
24657db96d56Sopenharmony_ci
24667db96d56Sopenharmony_ci    Input is a sequence of words.  Words may be fixed-length (length set
24677db96d56Sopenharmony_ci    by input) or variable-length (period-terminated).  In variable-length
24687db96d56Sopenharmony_ci    mode, extra periods are ignored.  Possible words are:
24697db96d56Sopenharmony_ci      - 'i' followed by a number sets the input length, I (maximum 99).
24707db96d56Sopenharmony_ci        When I is set to 0, words are space-terminated.
24717db96d56Sopenharmony_ci      - 'o' followed by a number sets the output length, O (maximum 99).
24727db96d56Sopenharmony_ci      - Any other word is converted into a word followed by a period on
24737db96d56Sopenharmony_ci        the output.  The output word consists of the input word truncated
24747db96d56Sopenharmony_ci        or padded out with hyphens to make its length equal to O.  If O
24757db96d56Sopenharmony_ci        is 0, the word is output verbatim without truncating or padding.
24767db96d56Sopenharmony_ci    I and O are initially set to 1.  When I changes, any buffered input is
24777db96d56Sopenharmony_ci    re-scanned according to the new I.  EOF also terminates the last word.
24787db96d56Sopenharmony_ci    """
24797db96d56Sopenharmony_ci
24807db96d56Sopenharmony_ci    def __init__(self, errors='strict'):
24817db96d56Sopenharmony_ci        codecs.IncrementalDecoder.__init__(self, errors)
24827db96d56Sopenharmony_ci        self.reset()
24837db96d56Sopenharmony_ci
24847db96d56Sopenharmony_ci    def __repr__(self):
24857db96d56Sopenharmony_ci        return '<SID %x>' % id(self)
24867db96d56Sopenharmony_ci
24877db96d56Sopenharmony_ci    def reset(self):
24887db96d56Sopenharmony_ci        self.i = 1
24897db96d56Sopenharmony_ci        self.o = 1
24907db96d56Sopenharmony_ci        self.buffer = bytearray()
24917db96d56Sopenharmony_ci
24927db96d56Sopenharmony_ci    def getstate(self):
24937db96d56Sopenharmony_ci        i, o = self.i ^ 1, self.o ^ 1 # so that flags = 0 after reset()
24947db96d56Sopenharmony_ci        return bytes(self.buffer), i*100 + o
24957db96d56Sopenharmony_ci
24967db96d56Sopenharmony_ci    def setstate(self, state):
24977db96d56Sopenharmony_ci        buffer, io = state
24987db96d56Sopenharmony_ci        self.buffer = bytearray(buffer)
24997db96d56Sopenharmony_ci        i, o = divmod(io, 100)
25007db96d56Sopenharmony_ci        self.i, self.o = i ^ 1, o ^ 1
25017db96d56Sopenharmony_ci
25027db96d56Sopenharmony_ci    def decode(self, input, final=False):
25037db96d56Sopenharmony_ci        output = ''
25047db96d56Sopenharmony_ci        for b in input:
25057db96d56Sopenharmony_ci            if self.i == 0: # variable-length, terminated with period
25067db96d56Sopenharmony_ci                if b == ord('.'):
25077db96d56Sopenharmony_ci                    if self.buffer:
25087db96d56Sopenharmony_ci                        output += self.process_word()
25097db96d56Sopenharmony_ci                else:
25107db96d56Sopenharmony_ci                    self.buffer.append(b)
25117db96d56Sopenharmony_ci            else: # fixed-length, terminate after self.i bytes
25127db96d56Sopenharmony_ci                self.buffer.append(b)
25137db96d56Sopenharmony_ci                if len(self.buffer) == self.i:
25147db96d56Sopenharmony_ci                    output += self.process_word()
25157db96d56Sopenharmony_ci        if final and self.buffer: # EOF terminates the last word
25167db96d56Sopenharmony_ci            output += self.process_word()
25177db96d56Sopenharmony_ci        return output
25187db96d56Sopenharmony_ci
25197db96d56Sopenharmony_ci    def process_word(self):
25207db96d56Sopenharmony_ci        output = ''
25217db96d56Sopenharmony_ci        if self.buffer[0] == ord('i'):
25227db96d56Sopenharmony_ci            self.i = min(99, int(self.buffer[1:] or 0)) # set input length
25237db96d56Sopenharmony_ci        elif self.buffer[0] == ord('o'):
25247db96d56Sopenharmony_ci            self.o = min(99, int(self.buffer[1:] or 0)) # set output length
25257db96d56Sopenharmony_ci        else:
25267db96d56Sopenharmony_ci            output = self.buffer.decode('ascii')
25277db96d56Sopenharmony_ci            if len(output) < self.o:
25287db96d56Sopenharmony_ci                output += '-'*self.o # pad out with hyphens
25297db96d56Sopenharmony_ci            if self.o:
25307db96d56Sopenharmony_ci                output = output[:self.o] # truncate to output length
25317db96d56Sopenharmony_ci            output += '.'
25327db96d56Sopenharmony_ci        self.buffer = bytearray()
25337db96d56Sopenharmony_ci        return output
25347db96d56Sopenharmony_ci
25357db96d56Sopenharmony_ci    codecEnabled = False
25367db96d56Sopenharmony_ci
25377db96d56Sopenharmony_ci
25387db96d56Sopenharmony_ci# bpo-41919: This method is separated from StatefulIncrementalDecoder to avoid a resource leak
25397db96d56Sopenharmony_ci# when registering codecs and cleanup functions.
25407db96d56Sopenharmony_cidef lookupTestDecoder(name):
25417db96d56Sopenharmony_ci    if StatefulIncrementalDecoder.codecEnabled and name == 'test_decoder':
25427db96d56Sopenharmony_ci        latin1 = codecs.lookup('latin-1')
25437db96d56Sopenharmony_ci        return codecs.CodecInfo(
25447db96d56Sopenharmony_ci            name='test_decoder', encode=latin1.encode, decode=None,
25457db96d56Sopenharmony_ci            incrementalencoder=None,
25467db96d56Sopenharmony_ci            streamreader=None, streamwriter=None,
25477db96d56Sopenharmony_ci            incrementaldecoder=StatefulIncrementalDecoder)
25487db96d56Sopenharmony_ci
25497db96d56Sopenharmony_ci
25507db96d56Sopenharmony_ciclass StatefulIncrementalDecoderTest(unittest.TestCase):
25517db96d56Sopenharmony_ci    """
25527db96d56Sopenharmony_ci    Make sure the StatefulIncrementalDecoder actually works.
25537db96d56Sopenharmony_ci    """
25547db96d56Sopenharmony_ci
25557db96d56Sopenharmony_ci    test_cases = [
25567db96d56Sopenharmony_ci        # I=1, O=1 (fixed-length input == fixed-length output)
25577db96d56Sopenharmony_ci        (b'abcd', False, 'a.b.c.d.'),
25587db96d56Sopenharmony_ci        # I=0, O=0 (variable-length input, variable-length output)
25597db96d56Sopenharmony_ci        (b'oiabcd', True, 'abcd.'),
25607db96d56Sopenharmony_ci        # I=0, O=0 (should ignore extra periods)
25617db96d56Sopenharmony_ci        (b'oi...abcd...', True, 'abcd.'),
25627db96d56Sopenharmony_ci        # I=0, O=6 (variable-length input, fixed-length output)
25637db96d56Sopenharmony_ci        (b'i.o6.x.xyz.toolongtofit.', False, 'x-----.xyz---.toolon.'),
25647db96d56Sopenharmony_ci        # I=2, O=6 (fixed-length input < fixed-length output)
25657db96d56Sopenharmony_ci        (b'i.i2.o6xyz', True, 'xy----.z-----.'),
25667db96d56Sopenharmony_ci        # I=6, O=3 (fixed-length input > fixed-length output)
25677db96d56Sopenharmony_ci        (b'i.o3.i6.abcdefghijklmnop', True, 'abc.ghi.mno.'),
25687db96d56Sopenharmony_ci        # I=0, then 3; O=29, then 15 (with longer output)
25697db96d56Sopenharmony_ci        (b'i.o29.a.b.cde.o15.abcdefghijabcdefghij.i3.a.b.c.d.ei00k.l.m', True,
25707db96d56Sopenharmony_ci         'a----------------------------.' +
25717db96d56Sopenharmony_ci         'b----------------------------.' +
25727db96d56Sopenharmony_ci         'cde--------------------------.' +
25737db96d56Sopenharmony_ci         'abcdefghijabcde.' +
25747db96d56Sopenharmony_ci         'a.b------------.' +
25757db96d56Sopenharmony_ci         '.c.------------.' +
25767db96d56Sopenharmony_ci         'd.e------------.' +
25777db96d56Sopenharmony_ci         'k--------------.' +
25787db96d56Sopenharmony_ci         'l--------------.' +
25797db96d56Sopenharmony_ci         'm--------------.')
25807db96d56Sopenharmony_ci    ]
25817db96d56Sopenharmony_ci
25827db96d56Sopenharmony_ci    def test_decoder(self):
25837db96d56Sopenharmony_ci        # Try a few one-shot test cases.
25847db96d56Sopenharmony_ci        for input, eof, output in self.test_cases:
25857db96d56Sopenharmony_ci            d = StatefulIncrementalDecoder()
25867db96d56Sopenharmony_ci            self.assertEqual(d.decode(input, eof), output)
25877db96d56Sopenharmony_ci
25887db96d56Sopenharmony_ci        # Also test an unfinished decode, followed by forcing EOF.
25897db96d56Sopenharmony_ci        d = StatefulIncrementalDecoder()
25907db96d56Sopenharmony_ci        self.assertEqual(d.decode(b'oiabcd'), '')
25917db96d56Sopenharmony_ci        self.assertEqual(d.decode(b'', 1), 'abcd.')
25927db96d56Sopenharmony_ci
25937db96d56Sopenharmony_ciclass TextIOWrapperTest(unittest.TestCase):
25947db96d56Sopenharmony_ci
25957db96d56Sopenharmony_ci    def setUp(self):
25967db96d56Sopenharmony_ci        self.testdata = b"AAA\r\nBBB\rCCC\r\nDDD\nEEE\r\n"
25977db96d56Sopenharmony_ci        self.normalized = b"AAA\nBBB\nCCC\nDDD\nEEE\n".decode("ascii")
25987db96d56Sopenharmony_ci        os_helper.unlink(os_helper.TESTFN)
25997db96d56Sopenharmony_ci        codecs.register(lookupTestDecoder)
26007db96d56Sopenharmony_ci        self.addCleanup(codecs.unregister, lookupTestDecoder)
26017db96d56Sopenharmony_ci
26027db96d56Sopenharmony_ci    def tearDown(self):
26037db96d56Sopenharmony_ci        os_helper.unlink(os_helper.TESTFN)
26047db96d56Sopenharmony_ci
26057db96d56Sopenharmony_ci    def test_constructor(self):
26067db96d56Sopenharmony_ci        r = self.BytesIO(b"\xc3\xa9\n\n")
26077db96d56Sopenharmony_ci        b = self.BufferedReader(r, 1000)
26087db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="utf-8")
26097db96d56Sopenharmony_ci        t.__init__(b, encoding="latin-1", newline="\r\n")
26107db96d56Sopenharmony_ci        self.assertEqual(t.encoding, "latin-1")
26117db96d56Sopenharmony_ci        self.assertEqual(t.line_buffering, False)
26127db96d56Sopenharmony_ci        t.__init__(b, encoding="utf-8", line_buffering=True)
26137db96d56Sopenharmony_ci        self.assertEqual(t.encoding, "utf-8")
26147db96d56Sopenharmony_ci        self.assertEqual(t.line_buffering, True)
26157db96d56Sopenharmony_ci        self.assertEqual("\xe9\n", t.readline())
26167db96d56Sopenharmony_ci        self.assertRaises(TypeError, t.__init__, b, encoding="utf-8", newline=42)
26177db96d56Sopenharmony_ci        self.assertRaises(ValueError, t.__init__, b, encoding="utf-8", newline='xyzzy')
26187db96d56Sopenharmony_ci
26197db96d56Sopenharmony_ci    def test_uninitialized(self):
26207db96d56Sopenharmony_ci        t = self.TextIOWrapper.__new__(self.TextIOWrapper)
26217db96d56Sopenharmony_ci        del t
26227db96d56Sopenharmony_ci        t = self.TextIOWrapper.__new__(self.TextIOWrapper)
26237db96d56Sopenharmony_ci        self.assertRaises(Exception, repr, t)
26247db96d56Sopenharmony_ci        self.assertRaisesRegex((ValueError, AttributeError),
26257db96d56Sopenharmony_ci                               'uninitialized|has no attribute',
26267db96d56Sopenharmony_ci                               t.read, 0)
26277db96d56Sopenharmony_ci        t.__init__(self.MockRawIO(), encoding="utf-8")
26287db96d56Sopenharmony_ci        self.assertEqual(t.read(0), '')
26297db96d56Sopenharmony_ci
26307db96d56Sopenharmony_ci    def test_non_text_encoding_codecs_are_rejected(self):
26317db96d56Sopenharmony_ci        # Ensure the constructor complains if passed a codec that isn't
26327db96d56Sopenharmony_ci        # marked as a text encoding
26337db96d56Sopenharmony_ci        # http://bugs.python.org/issue20404
26347db96d56Sopenharmony_ci        r = self.BytesIO()
26357db96d56Sopenharmony_ci        b = self.BufferedWriter(r)
26367db96d56Sopenharmony_ci        with self.assertRaisesRegex(LookupError, "is not a text encoding"):
26377db96d56Sopenharmony_ci            self.TextIOWrapper(b, encoding="hex")
26387db96d56Sopenharmony_ci
26397db96d56Sopenharmony_ci    def test_detach(self):
26407db96d56Sopenharmony_ci        r = self.BytesIO()
26417db96d56Sopenharmony_ci        b = self.BufferedWriter(r)
26427db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="ascii")
26437db96d56Sopenharmony_ci        self.assertIs(t.detach(), b)
26447db96d56Sopenharmony_ci
26457db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="ascii")
26467db96d56Sopenharmony_ci        t.write("howdy")
26477db96d56Sopenharmony_ci        self.assertFalse(r.getvalue())
26487db96d56Sopenharmony_ci        t.detach()
26497db96d56Sopenharmony_ci        self.assertEqual(r.getvalue(), b"howdy")
26507db96d56Sopenharmony_ci        self.assertRaises(ValueError, t.detach)
26517db96d56Sopenharmony_ci
26527db96d56Sopenharmony_ci        # Operations independent of the detached stream should still work
26537db96d56Sopenharmony_ci        repr(t)
26547db96d56Sopenharmony_ci        self.assertEqual(t.encoding, "ascii")
26557db96d56Sopenharmony_ci        self.assertEqual(t.errors, "strict")
26567db96d56Sopenharmony_ci        self.assertFalse(t.line_buffering)
26577db96d56Sopenharmony_ci        self.assertFalse(t.write_through)
26587db96d56Sopenharmony_ci
26597db96d56Sopenharmony_ci    def test_repr(self):
26607db96d56Sopenharmony_ci        raw = self.BytesIO("hello".encode("utf-8"))
26617db96d56Sopenharmony_ci        b = self.BufferedReader(raw)
26627db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="utf-8")
26637db96d56Sopenharmony_ci        modname = self.TextIOWrapper.__module__
26647db96d56Sopenharmony_ci        self.assertRegex(repr(t),
26657db96d56Sopenharmony_ci                         r"<(%s\.)?TextIOWrapper encoding='utf-8'>" % modname)
26667db96d56Sopenharmony_ci        raw.name = "dummy"
26677db96d56Sopenharmony_ci        self.assertRegex(repr(t),
26687db96d56Sopenharmony_ci                         r"<(%s\.)?TextIOWrapper name='dummy' encoding='utf-8'>" % modname)
26697db96d56Sopenharmony_ci        t.mode = "r"
26707db96d56Sopenharmony_ci        self.assertRegex(repr(t),
26717db96d56Sopenharmony_ci                         r"<(%s\.)?TextIOWrapper name='dummy' mode='r' encoding='utf-8'>" % modname)
26727db96d56Sopenharmony_ci        raw.name = b"dummy"
26737db96d56Sopenharmony_ci        self.assertRegex(repr(t),
26747db96d56Sopenharmony_ci                         r"<(%s\.)?TextIOWrapper name=b'dummy' mode='r' encoding='utf-8'>" % modname)
26757db96d56Sopenharmony_ci
26767db96d56Sopenharmony_ci        t.buffer.detach()
26777db96d56Sopenharmony_ci        repr(t)  # Should not raise an exception
26787db96d56Sopenharmony_ci
26797db96d56Sopenharmony_ci    def test_recursive_repr(self):
26807db96d56Sopenharmony_ci        # Issue #25455
26817db96d56Sopenharmony_ci        raw = self.BytesIO()
26827db96d56Sopenharmony_ci        t = self.TextIOWrapper(raw, encoding="utf-8")
26837db96d56Sopenharmony_ci        with support.swap_attr(raw, 'name', t):
26847db96d56Sopenharmony_ci            try:
26857db96d56Sopenharmony_ci                repr(t)  # Should not crash
26867db96d56Sopenharmony_ci            except RuntimeError:
26877db96d56Sopenharmony_ci                pass
26887db96d56Sopenharmony_ci
26897db96d56Sopenharmony_ci    def test_line_buffering(self):
26907db96d56Sopenharmony_ci        r = self.BytesIO()
26917db96d56Sopenharmony_ci        b = self.BufferedWriter(r, 1000)
26927db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="utf-8", newline="\n", line_buffering=True)
26937db96d56Sopenharmony_ci        t.write("X")
26947db96d56Sopenharmony_ci        self.assertEqual(r.getvalue(), b"")  # No flush happened
26957db96d56Sopenharmony_ci        t.write("Y\nZ")
26967db96d56Sopenharmony_ci        self.assertEqual(r.getvalue(), b"XY\nZ")  # All got flushed
26977db96d56Sopenharmony_ci        t.write("A\rB")
26987db96d56Sopenharmony_ci        self.assertEqual(r.getvalue(), b"XY\nZA\rB")
26997db96d56Sopenharmony_ci
27007db96d56Sopenharmony_ci    def test_reconfigure_line_buffering(self):
27017db96d56Sopenharmony_ci        r = self.BytesIO()
27027db96d56Sopenharmony_ci        b = self.BufferedWriter(r, 1000)
27037db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="utf-8", newline="\n", line_buffering=False)
27047db96d56Sopenharmony_ci        t.write("AB\nC")
27057db96d56Sopenharmony_ci        self.assertEqual(r.getvalue(), b"")
27067db96d56Sopenharmony_ci
27077db96d56Sopenharmony_ci        t.reconfigure(line_buffering=True)   # implicit flush
27087db96d56Sopenharmony_ci        self.assertEqual(r.getvalue(), b"AB\nC")
27097db96d56Sopenharmony_ci        t.write("DEF\nG")
27107db96d56Sopenharmony_ci        self.assertEqual(r.getvalue(), b"AB\nCDEF\nG")
27117db96d56Sopenharmony_ci        t.write("H")
27127db96d56Sopenharmony_ci        self.assertEqual(r.getvalue(), b"AB\nCDEF\nG")
27137db96d56Sopenharmony_ci        t.reconfigure(line_buffering=False)   # implicit flush
27147db96d56Sopenharmony_ci        self.assertEqual(r.getvalue(), b"AB\nCDEF\nGH")
27157db96d56Sopenharmony_ci        t.write("IJ")
27167db96d56Sopenharmony_ci        self.assertEqual(r.getvalue(), b"AB\nCDEF\nGH")
27177db96d56Sopenharmony_ci
27187db96d56Sopenharmony_ci        # Keeping default value
27197db96d56Sopenharmony_ci        t.reconfigure()
27207db96d56Sopenharmony_ci        t.reconfigure(line_buffering=None)
27217db96d56Sopenharmony_ci        self.assertEqual(t.line_buffering, False)
27227db96d56Sopenharmony_ci        t.reconfigure(line_buffering=True)
27237db96d56Sopenharmony_ci        t.reconfigure()
27247db96d56Sopenharmony_ci        t.reconfigure(line_buffering=None)
27257db96d56Sopenharmony_ci        self.assertEqual(t.line_buffering, True)
27267db96d56Sopenharmony_ci
27277db96d56Sopenharmony_ci    @unittest.skipIf(sys.flags.utf8_mode, "utf-8 mode is enabled")
27287db96d56Sopenharmony_ci    def test_default_encoding(self):
27297db96d56Sopenharmony_ci        old_environ = dict(os.environ)
27307db96d56Sopenharmony_ci        try:
27317db96d56Sopenharmony_ci            # try to get a user preferred encoding different than the current
27327db96d56Sopenharmony_ci            # locale encoding to check that TextIOWrapper() uses the current
27337db96d56Sopenharmony_ci            # locale encoding and not the user preferred encoding
27347db96d56Sopenharmony_ci            for key in ('LC_ALL', 'LANG', 'LC_CTYPE'):
27357db96d56Sopenharmony_ci                if key in os.environ:
27367db96d56Sopenharmony_ci                    del os.environ[key]
27377db96d56Sopenharmony_ci
27387db96d56Sopenharmony_ci            current_locale_encoding = locale.getencoding()
27397db96d56Sopenharmony_ci            b = self.BytesIO()
27407db96d56Sopenharmony_ci            with warnings.catch_warnings():
27417db96d56Sopenharmony_ci                warnings.simplefilter("ignore", EncodingWarning)
27427db96d56Sopenharmony_ci                t = self.TextIOWrapper(b)
27437db96d56Sopenharmony_ci            self.assertEqual(t.encoding, current_locale_encoding)
27447db96d56Sopenharmony_ci        finally:
27457db96d56Sopenharmony_ci            os.environ.clear()
27467db96d56Sopenharmony_ci            os.environ.update(old_environ)
27477db96d56Sopenharmony_ci
27487db96d56Sopenharmony_ci    def test_encoding(self):
27497db96d56Sopenharmony_ci        # Check the encoding attribute is always set, and valid
27507db96d56Sopenharmony_ci        b = self.BytesIO()
27517db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="utf-8")
27527db96d56Sopenharmony_ci        self.assertEqual(t.encoding, "utf-8")
27537db96d56Sopenharmony_ci        with warnings.catch_warnings():
27547db96d56Sopenharmony_ci            warnings.simplefilter("ignore", EncodingWarning)
27557db96d56Sopenharmony_ci            t = self.TextIOWrapper(b)
27567db96d56Sopenharmony_ci        self.assertIsNotNone(t.encoding)
27577db96d56Sopenharmony_ci        codecs.lookup(t.encoding)
27587db96d56Sopenharmony_ci
27597db96d56Sopenharmony_ci    def test_encoding_errors_reading(self):
27607db96d56Sopenharmony_ci        # (1) default
27617db96d56Sopenharmony_ci        b = self.BytesIO(b"abc\n\xff\n")
27627db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="ascii")
27637db96d56Sopenharmony_ci        self.assertRaises(UnicodeError, t.read)
27647db96d56Sopenharmony_ci        # (2) explicit strict
27657db96d56Sopenharmony_ci        b = self.BytesIO(b"abc\n\xff\n")
27667db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="ascii", errors="strict")
27677db96d56Sopenharmony_ci        self.assertRaises(UnicodeError, t.read)
27687db96d56Sopenharmony_ci        # (3) ignore
27697db96d56Sopenharmony_ci        b = self.BytesIO(b"abc\n\xff\n")
27707db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="ascii", errors="ignore")
27717db96d56Sopenharmony_ci        self.assertEqual(t.read(), "abc\n\n")
27727db96d56Sopenharmony_ci        # (4) replace
27737db96d56Sopenharmony_ci        b = self.BytesIO(b"abc\n\xff\n")
27747db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="ascii", errors="replace")
27757db96d56Sopenharmony_ci        self.assertEqual(t.read(), "abc\n\ufffd\n")
27767db96d56Sopenharmony_ci
27777db96d56Sopenharmony_ci    def test_encoding_errors_writing(self):
27787db96d56Sopenharmony_ci        # (1) default
27797db96d56Sopenharmony_ci        b = self.BytesIO()
27807db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="ascii")
27817db96d56Sopenharmony_ci        self.assertRaises(UnicodeError, t.write, "\xff")
27827db96d56Sopenharmony_ci        # (2) explicit strict
27837db96d56Sopenharmony_ci        b = self.BytesIO()
27847db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="ascii", errors="strict")
27857db96d56Sopenharmony_ci        self.assertRaises(UnicodeError, t.write, "\xff")
27867db96d56Sopenharmony_ci        # (3) ignore
27877db96d56Sopenharmony_ci        b = self.BytesIO()
27887db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="ascii", errors="ignore",
27897db96d56Sopenharmony_ci                             newline="\n")
27907db96d56Sopenharmony_ci        t.write("abc\xffdef\n")
27917db96d56Sopenharmony_ci        t.flush()
27927db96d56Sopenharmony_ci        self.assertEqual(b.getvalue(), b"abcdef\n")
27937db96d56Sopenharmony_ci        # (4) replace
27947db96d56Sopenharmony_ci        b = self.BytesIO()
27957db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="ascii", errors="replace",
27967db96d56Sopenharmony_ci                             newline="\n")
27977db96d56Sopenharmony_ci        t.write("abc\xffdef\n")
27987db96d56Sopenharmony_ci        t.flush()
27997db96d56Sopenharmony_ci        self.assertEqual(b.getvalue(), b"abc?def\n")
28007db96d56Sopenharmony_ci
28017db96d56Sopenharmony_ci    def test_newlines(self):
28027db96d56Sopenharmony_ci        input_lines = [ "unix\n", "windows\r\n", "os9\r", "last\n", "nonl" ]
28037db96d56Sopenharmony_ci
28047db96d56Sopenharmony_ci        tests = [
28057db96d56Sopenharmony_ci            [ None, [ 'unix\n', 'windows\n', 'os9\n', 'last\n', 'nonl' ] ],
28067db96d56Sopenharmony_ci            [ '', input_lines ],
28077db96d56Sopenharmony_ci            [ '\n', [ "unix\n", "windows\r\n", "os9\rlast\n", "nonl" ] ],
28087db96d56Sopenharmony_ci            [ '\r\n', [ "unix\nwindows\r\n", "os9\rlast\nnonl" ] ],
28097db96d56Sopenharmony_ci            [ '\r', [ "unix\nwindows\r", "\nos9\r", "last\nnonl" ] ],
28107db96d56Sopenharmony_ci        ]
28117db96d56Sopenharmony_ci        encodings = (
28127db96d56Sopenharmony_ci            'utf-8', 'latin-1',
28137db96d56Sopenharmony_ci            'utf-16', 'utf-16-le', 'utf-16-be',
28147db96d56Sopenharmony_ci            'utf-32', 'utf-32-le', 'utf-32-be',
28157db96d56Sopenharmony_ci        )
28167db96d56Sopenharmony_ci
28177db96d56Sopenharmony_ci        # Try a range of buffer sizes to test the case where \r is the last
28187db96d56Sopenharmony_ci        # character in TextIOWrapper._pending_line.
28197db96d56Sopenharmony_ci        for encoding in encodings:
28207db96d56Sopenharmony_ci            # XXX: str.encode() should return bytes
28217db96d56Sopenharmony_ci            data = bytes(''.join(input_lines).encode(encoding))
28227db96d56Sopenharmony_ci            for do_reads in (False, True):
28237db96d56Sopenharmony_ci                for bufsize in range(1, 10):
28247db96d56Sopenharmony_ci                    for newline, exp_lines in tests:
28257db96d56Sopenharmony_ci                        bufio = self.BufferedReader(self.BytesIO(data), bufsize)
28267db96d56Sopenharmony_ci                        textio = self.TextIOWrapper(bufio, newline=newline,
28277db96d56Sopenharmony_ci                                                  encoding=encoding)
28287db96d56Sopenharmony_ci                        if do_reads:
28297db96d56Sopenharmony_ci                            got_lines = []
28307db96d56Sopenharmony_ci                            while True:
28317db96d56Sopenharmony_ci                                c2 = textio.read(2)
28327db96d56Sopenharmony_ci                                if c2 == '':
28337db96d56Sopenharmony_ci                                    break
28347db96d56Sopenharmony_ci                                self.assertEqual(len(c2), 2)
28357db96d56Sopenharmony_ci                                got_lines.append(c2 + textio.readline())
28367db96d56Sopenharmony_ci                        else:
28377db96d56Sopenharmony_ci                            got_lines = list(textio)
28387db96d56Sopenharmony_ci
28397db96d56Sopenharmony_ci                        for got_line, exp_line in zip(got_lines, exp_lines):
28407db96d56Sopenharmony_ci                            self.assertEqual(got_line, exp_line)
28417db96d56Sopenharmony_ci                        self.assertEqual(len(got_lines), len(exp_lines))
28427db96d56Sopenharmony_ci
28437db96d56Sopenharmony_ci    def test_newlines_input(self):
28447db96d56Sopenharmony_ci        testdata = b"AAA\nBB\x00B\nCCC\rDDD\rEEE\r\nFFF\r\nGGG"
28457db96d56Sopenharmony_ci        normalized = testdata.replace(b"\r\n", b"\n").replace(b"\r", b"\n")
28467db96d56Sopenharmony_ci        for newline, expected in [
28477db96d56Sopenharmony_ci            (None, normalized.decode("ascii").splitlines(keepends=True)),
28487db96d56Sopenharmony_ci            ("", testdata.decode("ascii").splitlines(keepends=True)),
28497db96d56Sopenharmony_ci            ("\n", ["AAA\n", "BB\x00B\n", "CCC\rDDD\rEEE\r\n", "FFF\r\n", "GGG"]),
28507db96d56Sopenharmony_ci            ("\r\n", ["AAA\nBB\x00B\nCCC\rDDD\rEEE\r\n", "FFF\r\n", "GGG"]),
28517db96d56Sopenharmony_ci            ("\r",  ["AAA\nBB\x00B\nCCC\r", "DDD\r", "EEE\r", "\nFFF\r", "\nGGG"]),
28527db96d56Sopenharmony_ci            ]:
28537db96d56Sopenharmony_ci            buf = self.BytesIO(testdata)
28547db96d56Sopenharmony_ci            txt = self.TextIOWrapper(buf, encoding="ascii", newline=newline)
28557db96d56Sopenharmony_ci            self.assertEqual(txt.readlines(), expected)
28567db96d56Sopenharmony_ci            txt.seek(0)
28577db96d56Sopenharmony_ci            self.assertEqual(txt.read(), "".join(expected))
28587db96d56Sopenharmony_ci
28597db96d56Sopenharmony_ci    def test_newlines_output(self):
28607db96d56Sopenharmony_ci        testdict = {
28617db96d56Sopenharmony_ci            "": b"AAA\nBBB\nCCC\nX\rY\r\nZ",
28627db96d56Sopenharmony_ci            "\n": b"AAA\nBBB\nCCC\nX\rY\r\nZ",
28637db96d56Sopenharmony_ci            "\r": b"AAA\rBBB\rCCC\rX\rY\r\rZ",
28647db96d56Sopenharmony_ci            "\r\n": b"AAA\r\nBBB\r\nCCC\r\nX\rY\r\r\nZ",
28657db96d56Sopenharmony_ci            }
28667db96d56Sopenharmony_ci        tests = [(None, testdict[os.linesep])] + sorted(testdict.items())
28677db96d56Sopenharmony_ci        for newline, expected in tests:
28687db96d56Sopenharmony_ci            buf = self.BytesIO()
28697db96d56Sopenharmony_ci            txt = self.TextIOWrapper(buf, encoding="ascii", newline=newline)
28707db96d56Sopenharmony_ci            txt.write("AAA\nB")
28717db96d56Sopenharmony_ci            txt.write("BB\nCCC\n")
28727db96d56Sopenharmony_ci            txt.write("X\rY\r\nZ")
28737db96d56Sopenharmony_ci            txt.flush()
28747db96d56Sopenharmony_ci            self.assertEqual(buf.closed, False)
28757db96d56Sopenharmony_ci            self.assertEqual(buf.getvalue(), expected)
28767db96d56Sopenharmony_ci
28777db96d56Sopenharmony_ci    def test_destructor(self):
28787db96d56Sopenharmony_ci        l = []
28797db96d56Sopenharmony_ci        base = self.BytesIO
28807db96d56Sopenharmony_ci        class MyBytesIO(base):
28817db96d56Sopenharmony_ci            def close(self):
28827db96d56Sopenharmony_ci                l.append(self.getvalue())
28837db96d56Sopenharmony_ci                base.close(self)
28847db96d56Sopenharmony_ci        b = MyBytesIO()
28857db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="ascii")
28867db96d56Sopenharmony_ci        t.write("abc")
28877db96d56Sopenharmony_ci        del t
28887db96d56Sopenharmony_ci        support.gc_collect()
28897db96d56Sopenharmony_ci        self.assertEqual([b"abc"], l)
28907db96d56Sopenharmony_ci
28917db96d56Sopenharmony_ci    def test_override_destructor(self):
28927db96d56Sopenharmony_ci        record = []
28937db96d56Sopenharmony_ci        class MyTextIO(self.TextIOWrapper):
28947db96d56Sopenharmony_ci            def __del__(self):
28957db96d56Sopenharmony_ci                record.append(1)
28967db96d56Sopenharmony_ci                try:
28977db96d56Sopenharmony_ci                    f = super().__del__
28987db96d56Sopenharmony_ci                except AttributeError:
28997db96d56Sopenharmony_ci                    pass
29007db96d56Sopenharmony_ci                else:
29017db96d56Sopenharmony_ci                    f()
29027db96d56Sopenharmony_ci            def close(self):
29037db96d56Sopenharmony_ci                record.append(2)
29047db96d56Sopenharmony_ci                super().close()
29057db96d56Sopenharmony_ci            def flush(self):
29067db96d56Sopenharmony_ci                record.append(3)
29077db96d56Sopenharmony_ci                super().flush()
29087db96d56Sopenharmony_ci        b = self.BytesIO()
29097db96d56Sopenharmony_ci        t = MyTextIO(b, encoding="ascii")
29107db96d56Sopenharmony_ci        del t
29117db96d56Sopenharmony_ci        support.gc_collect()
29127db96d56Sopenharmony_ci        self.assertEqual(record, [1, 2, 3])
29137db96d56Sopenharmony_ci
29147db96d56Sopenharmony_ci    def test_error_through_destructor(self):
29157db96d56Sopenharmony_ci        # Test that the exception state is not modified by a destructor,
29167db96d56Sopenharmony_ci        # even if close() fails.
29177db96d56Sopenharmony_ci        rawio = self.CloseFailureIO()
29187db96d56Sopenharmony_ci        with support.catch_unraisable_exception() as cm:
29197db96d56Sopenharmony_ci            with self.assertRaises(AttributeError):
29207db96d56Sopenharmony_ci                self.TextIOWrapper(rawio, encoding="utf-8").xyzzy
29217db96d56Sopenharmony_ci
29227db96d56Sopenharmony_ci            if not IOBASE_EMITS_UNRAISABLE:
29237db96d56Sopenharmony_ci                self.assertIsNone(cm.unraisable)
29247db96d56Sopenharmony_ci            elif cm.unraisable is not None:
29257db96d56Sopenharmony_ci                self.assertEqual(cm.unraisable.exc_type, OSError)
29267db96d56Sopenharmony_ci
29277db96d56Sopenharmony_ci    # Systematic tests of the text I/O API
29287db96d56Sopenharmony_ci
29297db96d56Sopenharmony_ci    def test_basic_io(self):
29307db96d56Sopenharmony_ci        for chunksize in (1, 2, 3, 4, 5, 15, 16, 17, 31, 32, 33, 63, 64, 65):
29317db96d56Sopenharmony_ci            for enc in "ascii", "latin-1", "utf-8" :# , "utf-16-be", "utf-16-le":
29327db96d56Sopenharmony_ci                f = self.open(os_helper.TESTFN, "w+", encoding=enc)
29337db96d56Sopenharmony_ci                f._CHUNK_SIZE = chunksize
29347db96d56Sopenharmony_ci                self.assertEqual(f.write("abc"), 3)
29357db96d56Sopenharmony_ci                f.close()
29367db96d56Sopenharmony_ci                f = self.open(os_helper.TESTFN, "r+", encoding=enc)
29377db96d56Sopenharmony_ci                f._CHUNK_SIZE = chunksize
29387db96d56Sopenharmony_ci                self.assertEqual(f.tell(), 0)
29397db96d56Sopenharmony_ci                self.assertEqual(f.read(), "abc")
29407db96d56Sopenharmony_ci                cookie = f.tell()
29417db96d56Sopenharmony_ci                self.assertEqual(f.seek(0), 0)
29427db96d56Sopenharmony_ci                self.assertEqual(f.read(None), "abc")
29437db96d56Sopenharmony_ci                f.seek(0)
29447db96d56Sopenharmony_ci                self.assertEqual(f.read(2), "ab")
29457db96d56Sopenharmony_ci                self.assertEqual(f.read(1), "c")
29467db96d56Sopenharmony_ci                self.assertEqual(f.read(1), "")
29477db96d56Sopenharmony_ci                self.assertEqual(f.read(), "")
29487db96d56Sopenharmony_ci                self.assertEqual(f.tell(), cookie)
29497db96d56Sopenharmony_ci                self.assertEqual(f.seek(0), 0)
29507db96d56Sopenharmony_ci                self.assertEqual(f.seek(0, 2), cookie)
29517db96d56Sopenharmony_ci                self.assertEqual(f.write("def"), 3)
29527db96d56Sopenharmony_ci                self.assertEqual(f.seek(cookie), cookie)
29537db96d56Sopenharmony_ci                self.assertEqual(f.read(), "def")
29547db96d56Sopenharmony_ci                if enc.startswith("utf"):
29557db96d56Sopenharmony_ci                    self.multi_line_test(f, enc)
29567db96d56Sopenharmony_ci                f.close()
29577db96d56Sopenharmony_ci
29587db96d56Sopenharmony_ci    def multi_line_test(self, f, enc):
29597db96d56Sopenharmony_ci        f.seek(0)
29607db96d56Sopenharmony_ci        f.truncate()
29617db96d56Sopenharmony_ci        sample = "s\xff\u0fff\uffff"
29627db96d56Sopenharmony_ci        wlines = []
29637db96d56Sopenharmony_ci        for size in (0, 1, 2, 3, 4, 5, 30, 31, 32, 33, 62, 63, 64, 65, 1000):
29647db96d56Sopenharmony_ci            chars = []
29657db96d56Sopenharmony_ci            for i in range(size):
29667db96d56Sopenharmony_ci                chars.append(sample[i % len(sample)])
29677db96d56Sopenharmony_ci            line = "".join(chars) + "\n"
29687db96d56Sopenharmony_ci            wlines.append((f.tell(), line))
29697db96d56Sopenharmony_ci            f.write(line)
29707db96d56Sopenharmony_ci        f.seek(0)
29717db96d56Sopenharmony_ci        rlines = []
29727db96d56Sopenharmony_ci        while True:
29737db96d56Sopenharmony_ci            pos = f.tell()
29747db96d56Sopenharmony_ci            line = f.readline()
29757db96d56Sopenharmony_ci            if not line:
29767db96d56Sopenharmony_ci                break
29777db96d56Sopenharmony_ci            rlines.append((pos, line))
29787db96d56Sopenharmony_ci        self.assertEqual(rlines, wlines)
29797db96d56Sopenharmony_ci
29807db96d56Sopenharmony_ci    def test_telling(self):
29817db96d56Sopenharmony_ci        f = self.open(os_helper.TESTFN, "w+", encoding="utf-8")
29827db96d56Sopenharmony_ci        p0 = f.tell()
29837db96d56Sopenharmony_ci        f.write("\xff\n")
29847db96d56Sopenharmony_ci        p1 = f.tell()
29857db96d56Sopenharmony_ci        f.write("\xff\n")
29867db96d56Sopenharmony_ci        p2 = f.tell()
29877db96d56Sopenharmony_ci        f.seek(0)
29887db96d56Sopenharmony_ci        self.assertEqual(f.tell(), p0)
29897db96d56Sopenharmony_ci        self.assertEqual(f.readline(), "\xff\n")
29907db96d56Sopenharmony_ci        self.assertEqual(f.tell(), p1)
29917db96d56Sopenharmony_ci        self.assertEqual(f.readline(), "\xff\n")
29927db96d56Sopenharmony_ci        self.assertEqual(f.tell(), p2)
29937db96d56Sopenharmony_ci        f.seek(0)
29947db96d56Sopenharmony_ci        for line in f:
29957db96d56Sopenharmony_ci            self.assertEqual(line, "\xff\n")
29967db96d56Sopenharmony_ci            self.assertRaises(OSError, f.tell)
29977db96d56Sopenharmony_ci        self.assertEqual(f.tell(), p2)
29987db96d56Sopenharmony_ci        f.close()
29997db96d56Sopenharmony_ci
30007db96d56Sopenharmony_ci    def test_seeking(self):
30017db96d56Sopenharmony_ci        chunk_size = _default_chunk_size()
30027db96d56Sopenharmony_ci        prefix_size = chunk_size - 2
30037db96d56Sopenharmony_ci        u_prefix = "a" * prefix_size
30047db96d56Sopenharmony_ci        prefix = bytes(u_prefix.encode("utf-8"))
30057db96d56Sopenharmony_ci        self.assertEqual(len(u_prefix), len(prefix))
30067db96d56Sopenharmony_ci        u_suffix = "\u8888\n"
30077db96d56Sopenharmony_ci        suffix = bytes(u_suffix.encode("utf-8"))
30087db96d56Sopenharmony_ci        line = prefix + suffix
30097db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb") as f:
30107db96d56Sopenharmony_ci            f.write(line*2)
30117db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "r", encoding="utf-8") as f:
30127db96d56Sopenharmony_ci            s = f.read(prefix_size)
30137db96d56Sopenharmony_ci            self.assertEqual(s, str(prefix, "ascii"))
30147db96d56Sopenharmony_ci            self.assertEqual(f.tell(), prefix_size)
30157db96d56Sopenharmony_ci            self.assertEqual(f.readline(), u_suffix)
30167db96d56Sopenharmony_ci
30177db96d56Sopenharmony_ci    def test_seeking_too(self):
30187db96d56Sopenharmony_ci        # Regression test for a specific bug
30197db96d56Sopenharmony_ci        data = b'\xe0\xbf\xbf\n'
30207db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb") as f:
30217db96d56Sopenharmony_ci            f.write(data)
30227db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "r", encoding="utf-8") as f:
30237db96d56Sopenharmony_ci            f._CHUNK_SIZE  # Just test that it exists
30247db96d56Sopenharmony_ci            f._CHUNK_SIZE = 2
30257db96d56Sopenharmony_ci            f.readline()
30267db96d56Sopenharmony_ci            f.tell()
30277db96d56Sopenharmony_ci
30287db96d56Sopenharmony_ci    def test_seek_and_tell(self):
30297db96d56Sopenharmony_ci        #Test seek/tell using the StatefulIncrementalDecoder.
30307db96d56Sopenharmony_ci        # Make test faster by doing smaller seeks
30317db96d56Sopenharmony_ci        CHUNK_SIZE = 128
30327db96d56Sopenharmony_ci
30337db96d56Sopenharmony_ci        def test_seek_and_tell_with_data(data, min_pos=0):
30347db96d56Sopenharmony_ci            """Tell/seek to various points within a data stream and ensure
30357db96d56Sopenharmony_ci            that the decoded data returned by read() is consistent."""
30367db96d56Sopenharmony_ci            f = self.open(os_helper.TESTFN, 'wb')
30377db96d56Sopenharmony_ci            f.write(data)
30387db96d56Sopenharmony_ci            f.close()
30397db96d56Sopenharmony_ci            f = self.open(os_helper.TESTFN, encoding='test_decoder')
30407db96d56Sopenharmony_ci            f._CHUNK_SIZE = CHUNK_SIZE
30417db96d56Sopenharmony_ci            decoded = f.read()
30427db96d56Sopenharmony_ci            f.close()
30437db96d56Sopenharmony_ci
30447db96d56Sopenharmony_ci            for i in range(min_pos, len(decoded) + 1): # seek positions
30457db96d56Sopenharmony_ci                for j in [1, 5, len(decoded) - i]: # read lengths
30467db96d56Sopenharmony_ci                    f = self.open(os_helper.TESTFN, encoding='test_decoder')
30477db96d56Sopenharmony_ci                    self.assertEqual(f.read(i), decoded[:i])
30487db96d56Sopenharmony_ci                    cookie = f.tell()
30497db96d56Sopenharmony_ci                    self.assertEqual(f.read(j), decoded[i:i + j])
30507db96d56Sopenharmony_ci                    f.seek(cookie)
30517db96d56Sopenharmony_ci                    self.assertEqual(f.read(), decoded[i:])
30527db96d56Sopenharmony_ci                    f.close()
30537db96d56Sopenharmony_ci
30547db96d56Sopenharmony_ci        # Enable the test decoder.
30557db96d56Sopenharmony_ci        StatefulIncrementalDecoder.codecEnabled = 1
30567db96d56Sopenharmony_ci
30577db96d56Sopenharmony_ci        # Run the tests.
30587db96d56Sopenharmony_ci        try:
30597db96d56Sopenharmony_ci            # Try each test case.
30607db96d56Sopenharmony_ci            for input, _, _ in StatefulIncrementalDecoderTest.test_cases:
30617db96d56Sopenharmony_ci                test_seek_and_tell_with_data(input)
30627db96d56Sopenharmony_ci
30637db96d56Sopenharmony_ci            # Position each test case so that it crosses a chunk boundary.
30647db96d56Sopenharmony_ci            for input, _, _ in StatefulIncrementalDecoderTest.test_cases:
30657db96d56Sopenharmony_ci                offset = CHUNK_SIZE - len(input)//2
30667db96d56Sopenharmony_ci                prefix = b'.'*offset
30677db96d56Sopenharmony_ci                # Don't bother seeking into the prefix (takes too long).
30687db96d56Sopenharmony_ci                min_pos = offset*2
30697db96d56Sopenharmony_ci                test_seek_and_tell_with_data(prefix + input, min_pos)
30707db96d56Sopenharmony_ci
30717db96d56Sopenharmony_ci        # Ensure our test decoder won't interfere with subsequent tests.
30727db96d56Sopenharmony_ci        finally:
30737db96d56Sopenharmony_ci            StatefulIncrementalDecoder.codecEnabled = 0
30747db96d56Sopenharmony_ci
30757db96d56Sopenharmony_ci    def test_multibyte_seek_and_tell(self):
30767db96d56Sopenharmony_ci        f = self.open(os_helper.TESTFN, "w", encoding="euc_jp")
30777db96d56Sopenharmony_ci        f.write("AB\n\u3046\u3048\n")
30787db96d56Sopenharmony_ci        f.close()
30797db96d56Sopenharmony_ci
30807db96d56Sopenharmony_ci        f = self.open(os_helper.TESTFN, "r", encoding="euc_jp")
30817db96d56Sopenharmony_ci        self.assertEqual(f.readline(), "AB\n")
30827db96d56Sopenharmony_ci        p0 = f.tell()
30837db96d56Sopenharmony_ci        self.assertEqual(f.readline(), "\u3046\u3048\n")
30847db96d56Sopenharmony_ci        p1 = f.tell()
30857db96d56Sopenharmony_ci        f.seek(p0)
30867db96d56Sopenharmony_ci        self.assertEqual(f.readline(), "\u3046\u3048\n")
30877db96d56Sopenharmony_ci        self.assertEqual(f.tell(), p1)
30887db96d56Sopenharmony_ci        f.close()
30897db96d56Sopenharmony_ci
30907db96d56Sopenharmony_ci    def test_seek_with_encoder_state(self):
30917db96d56Sopenharmony_ci        f = self.open(os_helper.TESTFN, "w", encoding="euc_jis_2004")
30927db96d56Sopenharmony_ci        f.write("\u00e6\u0300")
30937db96d56Sopenharmony_ci        p0 = f.tell()
30947db96d56Sopenharmony_ci        f.write("\u00e6")
30957db96d56Sopenharmony_ci        f.seek(p0)
30967db96d56Sopenharmony_ci        f.write("\u0300")
30977db96d56Sopenharmony_ci        f.close()
30987db96d56Sopenharmony_ci
30997db96d56Sopenharmony_ci        f = self.open(os_helper.TESTFN, "r", encoding="euc_jis_2004")
31007db96d56Sopenharmony_ci        self.assertEqual(f.readline(), "\u00e6\u0300\u0300")
31017db96d56Sopenharmony_ci        f.close()
31027db96d56Sopenharmony_ci
31037db96d56Sopenharmony_ci    def test_encoded_writes(self):
31047db96d56Sopenharmony_ci        data = "1234567890"
31057db96d56Sopenharmony_ci        tests = ("utf-16",
31067db96d56Sopenharmony_ci                 "utf-16-le",
31077db96d56Sopenharmony_ci                 "utf-16-be",
31087db96d56Sopenharmony_ci                 "utf-32",
31097db96d56Sopenharmony_ci                 "utf-32-le",
31107db96d56Sopenharmony_ci                 "utf-32-be")
31117db96d56Sopenharmony_ci        for encoding in tests:
31127db96d56Sopenharmony_ci            buf = self.BytesIO()
31137db96d56Sopenharmony_ci            f = self.TextIOWrapper(buf, encoding=encoding)
31147db96d56Sopenharmony_ci            # Check if the BOM is written only once (see issue1753).
31157db96d56Sopenharmony_ci            f.write(data)
31167db96d56Sopenharmony_ci            f.write(data)
31177db96d56Sopenharmony_ci            f.seek(0)
31187db96d56Sopenharmony_ci            self.assertEqual(f.read(), data * 2)
31197db96d56Sopenharmony_ci            f.seek(0)
31207db96d56Sopenharmony_ci            self.assertEqual(f.read(), data * 2)
31217db96d56Sopenharmony_ci            self.assertEqual(buf.getvalue(), (data * 2).encode(encoding))
31227db96d56Sopenharmony_ci
31237db96d56Sopenharmony_ci    def test_unreadable(self):
31247db96d56Sopenharmony_ci        class UnReadable(self.BytesIO):
31257db96d56Sopenharmony_ci            def readable(self):
31267db96d56Sopenharmony_ci                return False
31277db96d56Sopenharmony_ci        txt = self.TextIOWrapper(UnReadable(), encoding="utf-8")
31287db96d56Sopenharmony_ci        self.assertRaises(OSError, txt.read)
31297db96d56Sopenharmony_ci
31307db96d56Sopenharmony_ci    def test_read_one_by_one(self):
31317db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(b"AA\r\nBB"), encoding="utf-8")
31327db96d56Sopenharmony_ci        reads = ""
31337db96d56Sopenharmony_ci        while True:
31347db96d56Sopenharmony_ci            c = txt.read(1)
31357db96d56Sopenharmony_ci            if not c:
31367db96d56Sopenharmony_ci                break
31377db96d56Sopenharmony_ci            reads += c
31387db96d56Sopenharmony_ci        self.assertEqual(reads, "AA\nBB")
31397db96d56Sopenharmony_ci
31407db96d56Sopenharmony_ci    def test_readlines(self):
31417db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(b"AA\nBB\nCC"), encoding="utf-8")
31427db96d56Sopenharmony_ci        self.assertEqual(txt.readlines(), ["AA\n", "BB\n", "CC"])
31437db96d56Sopenharmony_ci        txt.seek(0)
31447db96d56Sopenharmony_ci        self.assertEqual(txt.readlines(None), ["AA\n", "BB\n", "CC"])
31457db96d56Sopenharmony_ci        txt.seek(0)
31467db96d56Sopenharmony_ci        self.assertEqual(txt.readlines(5), ["AA\n", "BB\n"])
31477db96d56Sopenharmony_ci
31487db96d56Sopenharmony_ci    # read in amounts equal to TextIOWrapper._CHUNK_SIZE which is 128.
31497db96d56Sopenharmony_ci    def test_read_by_chunk(self):
31507db96d56Sopenharmony_ci        # make sure "\r\n" straddles 128 char boundary.
31517db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(b"A" * 127 + b"\r\nB"), encoding="utf-8")
31527db96d56Sopenharmony_ci        reads = ""
31537db96d56Sopenharmony_ci        while True:
31547db96d56Sopenharmony_ci            c = txt.read(128)
31557db96d56Sopenharmony_ci            if not c:
31567db96d56Sopenharmony_ci                break
31577db96d56Sopenharmony_ci            reads += c
31587db96d56Sopenharmony_ci        self.assertEqual(reads, "A"*127+"\nB")
31597db96d56Sopenharmony_ci
31607db96d56Sopenharmony_ci    def test_writelines(self):
31617db96d56Sopenharmony_ci        l = ['ab', 'cd', 'ef']
31627db96d56Sopenharmony_ci        buf = self.BytesIO()
31637db96d56Sopenharmony_ci        txt = self.TextIOWrapper(buf, encoding="utf-8")
31647db96d56Sopenharmony_ci        txt.writelines(l)
31657db96d56Sopenharmony_ci        txt.flush()
31667db96d56Sopenharmony_ci        self.assertEqual(buf.getvalue(), b'abcdef')
31677db96d56Sopenharmony_ci
31687db96d56Sopenharmony_ci    def test_writelines_userlist(self):
31697db96d56Sopenharmony_ci        l = UserList(['ab', 'cd', 'ef'])
31707db96d56Sopenharmony_ci        buf = self.BytesIO()
31717db96d56Sopenharmony_ci        txt = self.TextIOWrapper(buf, encoding="utf-8")
31727db96d56Sopenharmony_ci        txt.writelines(l)
31737db96d56Sopenharmony_ci        txt.flush()
31747db96d56Sopenharmony_ci        self.assertEqual(buf.getvalue(), b'abcdef')
31757db96d56Sopenharmony_ci
31767db96d56Sopenharmony_ci    def test_writelines_error(self):
31777db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(), encoding="utf-8")
31787db96d56Sopenharmony_ci        self.assertRaises(TypeError, txt.writelines, [1, 2, 3])
31797db96d56Sopenharmony_ci        self.assertRaises(TypeError, txt.writelines, None)
31807db96d56Sopenharmony_ci        self.assertRaises(TypeError, txt.writelines, b'abc')
31817db96d56Sopenharmony_ci
31827db96d56Sopenharmony_ci    def test_issue1395_1(self):
31837db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii")
31847db96d56Sopenharmony_ci
31857db96d56Sopenharmony_ci        # read one char at a time
31867db96d56Sopenharmony_ci        reads = ""
31877db96d56Sopenharmony_ci        while True:
31887db96d56Sopenharmony_ci            c = txt.read(1)
31897db96d56Sopenharmony_ci            if not c:
31907db96d56Sopenharmony_ci                break
31917db96d56Sopenharmony_ci            reads += c
31927db96d56Sopenharmony_ci        self.assertEqual(reads, self.normalized)
31937db96d56Sopenharmony_ci
31947db96d56Sopenharmony_ci    def test_issue1395_2(self):
31957db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii")
31967db96d56Sopenharmony_ci        txt._CHUNK_SIZE = 4
31977db96d56Sopenharmony_ci
31987db96d56Sopenharmony_ci        reads = ""
31997db96d56Sopenharmony_ci        while True:
32007db96d56Sopenharmony_ci            c = txt.read(4)
32017db96d56Sopenharmony_ci            if not c:
32027db96d56Sopenharmony_ci                break
32037db96d56Sopenharmony_ci            reads += c
32047db96d56Sopenharmony_ci        self.assertEqual(reads, self.normalized)
32057db96d56Sopenharmony_ci
32067db96d56Sopenharmony_ci    def test_issue1395_3(self):
32077db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii")
32087db96d56Sopenharmony_ci        txt._CHUNK_SIZE = 4
32097db96d56Sopenharmony_ci
32107db96d56Sopenharmony_ci        reads = txt.read(4)
32117db96d56Sopenharmony_ci        reads += txt.read(4)
32127db96d56Sopenharmony_ci        reads += txt.readline()
32137db96d56Sopenharmony_ci        reads += txt.readline()
32147db96d56Sopenharmony_ci        reads += txt.readline()
32157db96d56Sopenharmony_ci        self.assertEqual(reads, self.normalized)
32167db96d56Sopenharmony_ci
32177db96d56Sopenharmony_ci    def test_issue1395_4(self):
32187db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii")
32197db96d56Sopenharmony_ci        txt._CHUNK_SIZE = 4
32207db96d56Sopenharmony_ci
32217db96d56Sopenharmony_ci        reads = txt.read(4)
32227db96d56Sopenharmony_ci        reads += txt.read()
32237db96d56Sopenharmony_ci        self.assertEqual(reads, self.normalized)
32247db96d56Sopenharmony_ci
32257db96d56Sopenharmony_ci    def test_issue1395_5(self):
32267db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii")
32277db96d56Sopenharmony_ci        txt._CHUNK_SIZE = 4
32287db96d56Sopenharmony_ci
32297db96d56Sopenharmony_ci        reads = txt.read(4)
32307db96d56Sopenharmony_ci        pos = txt.tell()
32317db96d56Sopenharmony_ci        txt.seek(0)
32327db96d56Sopenharmony_ci        txt.seek(pos)
32337db96d56Sopenharmony_ci        self.assertEqual(txt.read(4), "BBB\n")
32347db96d56Sopenharmony_ci
32357db96d56Sopenharmony_ci    def test_issue2282(self):
32367db96d56Sopenharmony_ci        buffer = self.BytesIO(self.testdata)
32377db96d56Sopenharmony_ci        txt = self.TextIOWrapper(buffer, encoding="ascii")
32387db96d56Sopenharmony_ci
32397db96d56Sopenharmony_ci        self.assertEqual(buffer.seekable(), txt.seekable())
32407db96d56Sopenharmony_ci
32417db96d56Sopenharmony_ci    def test_append_bom(self):
32427db96d56Sopenharmony_ci        # The BOM is not written again when appending to a non-empty file
32437db96d56Sopenharmony_ci        filename = os_helper.TESTFN
32447db96d56Sopenharmony_ci        for charset in ('utf-8-sig', 'utf-16', 'utf-32'):
32457db96d56Sopenharmony_ci            with self.open(filename, 'w', encoding=charset) as f:
32467db96d56Sopenharmony_ci                f.write('aaa')
32477db96d56Sopenharmony_ci                pos = f.tell()
32487db96d56Sopenharmony_ci            with self.open(filename, 'rb') as f:
32497db96d56Sopenharmony_ci                self.assertEqual(f.read(), 'aaa'.encode(charset))
32507db96d56Sopenharmony_ci
32517db96d56Sopenharmony_ci            with self.open(filename, 'a', encoding=charset) as f:
32527db96d56Sopenharmony_ci                f.write('xxx')
32537db96d56Sopenharmony_ci            with self.open(filename, 'rb') as f:
32547db96d56Sopenharmony_ci                self.assertEqual(f.read(), 'aaaxxx'.encode(charset))
32557db96d56Sopenharmony_ci
32567db96d56Sopenharmony_ci    def test_seek_bom(self):
32577db96d56Sopenharmony_ci        # Same test, but when seeking manually
32587db96d56Sopenharmony_ci        filename = os_helper.TESTFN
32597db96d56Sopenharmony_ci        for charset in ('utf-8-sig', 'utf-16', 'utf-32'):
32607db96d56Sopenharmony_ci            with self.open(filename, 'w', encoding=charset) as f:
32617db96d56Sopenharmony_ci                f.write('aaa')
32627db96d56Sopenharmony_ci                pos = f.tell()
32637db96d56Sopenharmony_ci            with self.open(filename, 'r+', encoding=charset) as f:
32647db96d56Sopenharmony_ci                f.seek(pos)
32657db96d56Sopenharmony_ci                f.write('zzz')
32667db96d56Sopenharmony_ci                f.seek(0)
32677db96d56Sopenharmony_ci                f.write('bbb')
32687db96d56Sopenharmony_ci            with self.open(filename, 'rb') as f:
32697db96d56Sopenharmony_ci                self.assertEqual(f.read(), 'bbbzzz'.encode(charset))
32707db96d56Sopenharmony_ci
32717db96d56Sopenharmony_ci    def test_seek_append_bom(self):
32727db96d56Sopenharmony_ci        # Same test, but first seek to the start and then to the end
32737db96d56Sopenharmony_ci        filename = os_helper.TESTFN
32747db96d56Sopenharmony_ci        for charset in ('utf-8-sig', 'utf-16', 'utf-32'):
32757db96d56Sopenharmony_ci            with self.open(filename, 'w', encoding=charset) as f:
32767db96d56Sopenharmony_ci                f.write('aaa')
32777db96d56Sopenharmony_ci            with self.open(filename, 'a', encoding=charset) as f:
32787db96d56Sopenharmony_ci                f.seek(0)
32797db96d56Sopenharmony_ci                f.seek(0, self.SEEK_END)
32807db96d56Sopenharmony_ci                f.write('xxx')
32817db96d56Sopenharmony_ci            with self.open(filename, 'rb') as f:
32827db96d56Sopenharmony_ci                self.assertEqual(f.read(), 'aaaxxx'.encode(charset))
32837db96d56Sopenharmony_ci
32847db96d56Sopenharmony_ci    def test_errors_property(self):
32857db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "w", encoding="utf-8") as f:
32867db96d56Sopenharmony_ci            self.assertEqual(f.errors, "strict")
32877db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "w", encoding="utf-8", errors="replace") as f:
32887db96d56Sopenharmony_ci            self.assertEqual(f.errors, "replace")
32897db96d56Sopenharmony_ci
32907db96d56Sopenharmony_ci    @support.no_tracing
32917db96d56Sopenharmony_ci    @threading_helper.requires_working_threading()
32927db96d56Sopenharmony_ci    def test_threads_write(self):
32937db96d56Sopenharmony_ci        # Issue6750: concurrent writes could duplicate data
32947db96d56Sopenharmony_ci        event = threading.Event()
32957db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "w", encoding="utf-8", buffering=1) as f:
32967db96d56Sopenharmony_ci            def run(n):
32977db96d56Sopenharmony_ci                text = "Thread%03d\n" % n
32987db96d56Sopenharmony_ci                event.wait()
32997db96d56Sopenharmony_ci                f.write(text)
33007db96d56Sopenharmony_ci            threads = [threading.Thread(target=run, args=(x,))
33017db96d56Sopenharmony_ci                       for x in range(20)]
33027db96d56Sopenharmony_ci            with threading_helper.start_threads(threads, event.set):
33037db96d56Sopenharmony_ci                time.sleep(0.02)
33047db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, encoding="utf-8") as f:
33057db96d56Sopenharmony_ci            content = f.read()
33067db96d56Sopenharmony_ci            for n in range(20):
33077db96d56Sopenharmony_ci                self.assertEqual(content.count("Thread%03d\n" % n), 1)
33087db96d56Sopenharmony_ci
33097db96d56Sopenharmony_ci    def test_flush_error_on_close(self):
33107db96d56Sopenharmony_ci        # Test that text file is closed despite failed flush
33117db96d56Sopenharmony_ci        # and that flush() is called before file closed.
33127db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii")
33137db96d56Sopenharmony_ci        closed = []
33147db96d56Sopenharmony_ci        def bad_flush():
33157db96d56Sopenharmony_ci            closed[:] = [txt.closed, txt.buffer.closed]
33167db96d56Sopenharmony_ci            raise OSError()
33177db96d56Sopenharmony_ci        txt.flush = bad_flush
33187db96d56Sopenharmony_ci        self.assertRaises(OSError, txt.close) # exception not swallowed
33197db96d56Sopenharmony_ci        self.assertTrue(txt.closed)
33207db96d56Sopenharmony_ci        self.assertTrue(txt.buffer.closed)
33217db96d56Sopenharmony_ci        self.assertTrue(closed)      # flush() called
33227db96d56Sopenharmony_ci        self.assertFalse(closed[0])  # flush() called before file closed
33237db96d56Sopenharmony_ci        self.assertFalse(closed[1])
33247db96d56Sopenharmony_ci        txt.flush = lambda: None  # break reference loop
33257db96d56Sopenharmony_ci
33267db96d56Sopenharmony_ci    def test_close_error_on_close(self):
33277db96d56Sopenharmony_ci        buffer = self.BytesIO(self.testdata)
33287db96d56Sopenharmony_ci        def bad_flush():
33297db96d56Sopenharmony_ci            raise OSError('flush')
33307db96d56Sopenharmony_ci        def bad_close():
33317db96d56Sopenharmony_ci            raise OSError('close')
33327db96d56Sopenharmony_ci        buffer.close = bad_close
33337db96d56Sopenharmony_ci        txt = self.TextIOWrapper(buffer, encoding="ascii")
33347db96d56Sopenharmony_ci        txt.flush = bad_flush
33357db96d56Sopenharmony_ci        with self.assertRaises(OSError) as err: # exception not swallowed
33367db96d56Sopenharmony_ci            txt.close()
33377db96d56Sopenharmony_ci        self.assertEqual(err.exception.args, ('close',))
33387db96d56Sopenharmony_ci        self.assertIsInstance(err.exception.__context__, OSError)
33397db96d56Sopenharmony_ci        self.assertEqual(err.exception.__context__.args, ('flush',))
33407db96d56Sopenharmony_ci        self.assertFalse(txt.closed)
33417db96d56Sopenharmony_ci
33427db96d56Sopenharmony_ci        # Silence destructor error
33437db96d56Sopenharmony_ci        buffer.close = lambda: None
33447db96d56Sopenharmony_ci        txt.flush = lambda: None
33457db96d56Sopenharmony_ci
33467db96d56Sopenharmony_ci    def test_nonnormalized_close_error_on_close(self):
33477db96d56Sopenharmony_ci        # Issue #21677
33487db96d56Sopenharmony_ci        buffer = self.BytesIO(self.testdata)
33497db96d56Sopenharmony_ci        def bad_flush():
33507db96d56Sopenharmony_ci            raise non_existing_flush
33517db96d56Sopenharmony_ci        def bad_close():
33527db96d56Sopenharmony_ci            raise non_existing_close
33537db96d56Sopenharmony_ci        buffer.close = bad_close
33547db96d56Sopenharmony_ci        txt = self.TextIOWrapper(buffer, encoding="ascii")
33557db96d56Sopenharmony_ci        txt.flush = bad_flush
33567db96d56Sopenharmony_ci        with self.assertRaises(NameError) as err: # exception not swallowed
33577db96d56Sopenharmony_ci            txt.close()
33587db96d56Sopenharmony_ci        self.assertIn('non_existing_close', str(err.exception))
33597db96d56Sopenharmony_ci        self.assertIsInstance(err.exception.__context__, NameError)
33607db96d56Sopenharmony_ci        self.assertIn('non_existing_flush', str(err.exception.__context__))
33617db96d56Sopenharmony_ci        self.assertFalse(txt.closed)
33627db96d56Sopenharmony_ci
33637db96d56Sopenharmony_ci        # Silence destructor error
33647db96d56Sopenharmony_ci        buffer.close = lambda: None
33657db96d56Sopenharmony_ci        txt.flush = lambda: None
33667db96d56Sopenharmony_ci
33677db96d56Sopenharmony_ci    def test_multi_close(self):
33687db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii")
33697db96d56Sopenharmony_ci        txt.close()
33707db96d56Sopenharmony_ci        txt.close()
33717db96d56Sopenharmony_ci        txt.close()
33727db96d56Sopenharmony_ci        self.assertRaises(ValueError, txt.flush)
33737db96d56Sopenharmony_ci
33747db96d56Sopenharmony_ci    def test_unseekable(self):
33757db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.MockUnseekableIO(self.testdata), encoding="utf-8")
33767db96d56Sopenharmony_ci        self.assertRaises(self.UnsupportedOperation, txt.tell)
33777db96d56Sopenharmony_ci        self.assertRaises(self.UnsupportedOperation, txt.seek, 0)
33787db96d56Sopenharmony_ci
33797db96d56Sopenharmony_ci    def test_readonly_attributes(self):
33807db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii")
33817db96d56Sopenharmony_ci        buf = self.BytesIO(self.testdata)
33827db96d56Sopenharmony_ci        with self.assertRaises(AttributeError):
33837db96d56Sopenharmony_ci            txt.buffer = buf
33847db96d56Sopenharmony_ci
33857db96d56Sopenharmony_ci    def test_rawio(self):
33867db96d56Sopenharmony_ci        # Issue #12591: TextIOWrapper must work with raw I/O objects, so
33877db96d56Sopenharmony_ci        # that subprocess.Popen() can have the required unbuffered
33887db96d56Sopenharmony_ci        # semantics with universal_newlines=True.
33897db96d56Sopenharmony_ci        raw = self.MockRawIO([b'abc', b'def', b'ghi\njkl\nopq\n'])
33907db96d56Sopenharmony_ci        txt = self.TextIOWrapper(raw, encoding='ascii', newline='\n')
33917db96d56Sopenharmony_ci        # Reads
33927db96d56Sopenharmony_ci        self.assertEqual(txt.read(4), 'abcd')
33937db96d56Sopenharmony_ci        self.assertEqual(txt.readline(), 'efghi\n')
33947db96d56Sopenharmony_ci        self.assertEqual(list(txt), ['jkl\n', 'opq\n'])
33957db96d56Sopenharmony_ci
33967db96d56Sopenharmony_ci    def test_rawio_write_through(self):
33977db96d56Sopenharmony_ci        # Issue #12591: with write_through=True, writes don't need a flush
33987db96d56Sopenharmony_ci        raw = self.MockRawIO([b'abc', b'def', b'ghi\njkl\nopq\n'])
33997db96d56Sopenharmony_ci        txt = self.TextIOWrapper(raw, encoding='ascii', newline='\n',
34007db96d56Sopenharmony_ci                                 write_through=True)
34017db96d56Sopenharmony_ci        txt.write('1')
34027db96d56Sopenharmony_ci        txt.write('23\n4')
34037db96d56Sopenharmony_ci        txt.write('5')
34047db96d56Sopenharmony_ci        self.assertEqual(b''.join(raw._write_stack), b'123\n45')
34057db96d56Sopenharmony_ci
34067db96d56Sopenharmony_ci    def test_bufio_write_through(self):
34077db96d56Sopenharmony_ci        # Issue #21396: write_through=True doesn't force a flush()
34087db96d56Sopenharmony_ci        # on the underlying binary buffered object.
34097db96d56Sopenharmony_ci        flush_called, write_called = [], []
34107db96d56Sopenharmony_ci        class BufferedWriter(self.BufferedWriter):
34117db96d56Sopenharmony_ci            def flush(self, *args, **kwargs):
34127db96d56Sopenharmony_ci                flush_called.append(True)
34137db96d56Sopenharmony_ci                return super().flush(*args, **kwargs)
34147db96d56Sopenharmony_ci            def write(self, *args, **kwargs):
34157db96d56Sopenharmony_ci                write_called.append(True)
34167db96d56Sopenharmony_ci                return super().write(*args, **kwargs)
34177db96d56Sopenharmony_ci
34187db96d56Sopenharmony_ci        rawio = self.BytesIO()
34197db96d56Sopenharmony_ci        data = b"a"
34207db96d56Sopenharmony_ci        bufio = BufferedWriter(rawio, len(data)*2)
34217db96d56Sopenharmony_ci        textio = self.TextIOWrapper(bufio, encoding='ascii',
34227db96d56Sopenharmony_ci                                    write_through=True)
34237db96d56Sopenharmony_ci        # write to the buffered io but don't overflow the buffer
34247db96d56Sopenharmony_ci        text = data.decode('ascii')
34257db96d56Sopenharmony_ci        textio.write(text)
34267db96d56Sopenharmony_ci
34277db96d56Sopenharmony_ci        # buffer.flush is not called with write_through=True
34287db96d56Sopenharmony_ci        self.assertFalse(flush_called)
34297db96d56Sopenharmony_ci        # buffer.write *is* called with write_through=True
34307db96d56Sopenharmony_ci        self.assertTrue(write_called)
34317db96d56Sopenharmony_ci        self.assertEqual(rawio.getvalue(), b"") # no flush
34327db96d56Sopenharmony_ci
34337db96d56Sopenharmony_ci        write_called = [] # reset
34347db96d56Sopenharmony_ci        textio.write(text * 10) # total content is larger than bufio buffer
34357db96d56Sopenharmony_ci        self.assertTrue(write_called)
34367db96d56Sopenharmony_ci        self.assertEqual(rawio.getvalue(), data * 11) # all flushed
34377db96d56Sopenharmony_ci
34387db96d56Sopenharmony_ci    def test_reconfigure_write_through(self):
34397db96d56Sopenharmony_ci        raw = self.MockRawIO([])
34407db96d56Sopenharmony_ci        t = self.TextIOWrapper(raw, encoding='ascii', newline='\n')
34417db96d56Sopenharmony_ci        t.write('1')
34427db96d56Sopenharmony_ci        t.reconfigure(write_through=True)  # implied flush
34437db96d56Sopenharmony_ci        self.assertEqual(t.write_through, True)
34447db96d56Sopenharmony_ci        self.assertEqual(b''.join(raw._write_stack), b'1')
34457db96d56Sopenharmony_ci        t.write('23')
34467db96d56Sopenharmony_ci        self.assertEqual(b''.join(raw._write_stack), b'123')
34477db96d56Sopenharmony_ci        t.reconfigure(write_through=False)
34487db96d56Sopenharmony_ci        self.assertEqual(t.write_through, False)
34497db96d56Sopenharmony_ci        t.write('45')
34507db96d56Sopenharmony_ci        t.flush()
34517db96d56Sopenharmony_ci        self.assertEqual(b''.join(raw._write_stack), b'12345')
34527db96d56Sopenharmony_ci        # Keeping default value
34537db96d56Sopenharmony_ci        t.reconfigure()
34547db96d56Sopenharmony_ci        t.reconfigure(write_through=None)
34557db96d56Sopenharmony_ci        self.assertEqual(t.write_through, False)
34567db96d56Sopenharmony_ci        t.reconfigure(write_through=True)
34577db96d56Sopenharmony_ci        t.reconfigure()
34587db96d56Sopenharmony_ci        t.reconfigure(write_through=None)
34597db96d56Sopenharmony_ci        self.assertEqual(t.write_through, True)
34607db96d56Sopenharmony_ci
34617db96d56Sopenharmony_ci    def test_read_nonbytes(self):
34627db96d56Sopenharmony_ci        # Issue #17106
34637db96d56Sopenharmony_ci        # Crash when underlying read() returns non-bytes
34647db96d56Sopenharmony_ci        t = self.TextIOWrapper(self.StringIO('a'), encoding="utf-8")
34657db96d56Sopenharmony_ci        self.assertRaises(TypeError, t.read, 1)
34667db96d56Sopenharmony_ci        t = self.TextIOWrapper(self.StringIO('a'), encoding="utf-8")
34677db96d56Sopenharmony_ci        self.assertRaises(TypeError, t.readline)
34687db96d56Sopenharmony_ci        t = self.TextIOWrapper(self.StringIO('a'), encoding="utf-8")
34697db96d56Sopenharmony_ci        self.assertRaises(TypeError, t.read)
34707db96d56Sopenharmony_ci
34717db96d56Sopenharmony_ci    def test_illegal_encoder(self):
34727db96d56Sopenharmony_ci        # Issue 31271: Calling write() while the return value of encoder's
34737db96d56Sopenharmony_ci        # encode() is invalid shouldn't cause an assertion failure.
34747db96d56Sopenharmony_ci        rot13 = codecs.lookup("rot13")
34757db96d56Sopenharmony_ci        with support.swap_attr(rot13, '_is_text_encoding', True):
34767db96d56Sopenharmony_ci            t = io.TextIOWrapper(io.BytesIO(b'foo'), encoding="rot13")
34777db96d56Sopenharmony_ci        self.assertRaises(TypeError, t.write, 'bar')
34787db96d56Sopenharmony_ci
34797db96d56Sopenharmony_ci    def test_illegal_decoder(self):
34807db96d56Sopenharmony_ci        # Issue #17106
34817db96d56Sopenharmony_ci        # Bypass the early encoding check added in issue 20404
34827db96d56Sopenharmony_ci        def _make_illegal_wrapper():
34837db96d56Sopenharmony_ci            quopri = codecs.lookup("quopri")
34847db96d56Sopenharmony_ci            quopri._is_text_encoding = True
34857db96d56Sopenharmony_ci            try:
34867db96d56Sopenharmony_ci                t = self.TextIOWrapper(self.BytesIO(b'aaaaaa'),
34877db96d56Sopenharmony_ci                                       newline='\n', encoding="quopri")
34887db96d56Sopenharmony_ci            finally:
34897db96d56Sopenharmony_ci                quopri._is_text_encoding = False
34907db96d56Sopenharmony_ci            return t
34917db96d56Sopenharmony_ci        # Crash when decoder returns non-string
34927db96d56Sopenharmony_ci        t = _make_illegal_wrapper()
34937db96d56Sopenharmony_ci        self.assertRaises(TypeError, t.read, 1)
34947db96d56Sopenharmony_ci        t = _make_illegal_wrapper()
34957db96d56Sopenharmony_ci        self.assertRaises(TypeError, t.readline)
34967db96d56Sopenharmony_ci        t = _make_illegal_wrapper()
34977db96d56Sopenharmony_ci        self.assertRaises(TypeError, t.read)
34987db96d56Sopenharmony_ci
34997db96d56Sopenharmony_ci        # Issue 31243: calling read() while the return value of decoder's
35007db96d56Sopenharmony_ci        # getstate() is invalid should neither crash the interpreter nor
35017db96d56Sopenharmony_ci        # raise a SystemError.
35027db96d56Sopenharmony_ci        def _make_very_illegal_wrapper(getstate_ret_val):
35037db96d56Sopenharmony_ci            class BadDecoder:
35047db96d56Sopenharmony_ci                def getstate(self):
35057db96d56Sopenharmony_ci                    return getstate_ret_val
35067db96d56Sopenharmony_ci            def _get_bad_decoder(dummy):
35077db96d56Sopenharmony_ci                return BadDecoder()
35087db96d56Sopenharmony_ci            quopri = codecs.lookup("quopri")
35097db96d56Sopenharmony_ci            with support.swap_attr(quopri, 'incrementaldecoder',
35107db96d56Sopenharmony_ci                                   _get_bad_decoder):
35117db96d56Sopenharmony_ci                return _make_illegal_wrapper()
35127db96d56Sopenharmony_ci        t = _make_very_illegal_wrapper(42)
35137db96d56Sopenharmony_ci        self.assertRaises(TypeError, t.read, 42)
35147db96d56Sopenharmony_ci        t = _make_very_illegal_wrapper(())
35157db96d56Sopenharmony_ci        self.assertRaises(TypeError, t.read, 42)
35167db96d56Sopenharmony_ci        t = _make_very_illegal_wrapper((1, 2))
35177db96d56Sopenharmony_ci        self.assertRaises(TypeError, t.read, 42)
35187db96d56Sopenharmony_ci
35197db96d56Sopenharmony_ci    def _check_create_at_shutdown(self, **kwargs):
35207db96d56Sopenharmony_ci        # Issue #20037: creating a TextIOWrapper at shutdown
35217db96d56Sopenharmony_ci        # shouldn't crash the interpreter.
35227db96d56Sopenharmony_ci        iomod = self.io.__name__
35237db96d56Sopenharmony_ci        code = """if 1:
35247db96d56Sopenharmony_ci            import codecs
35257db96d56Sopenharmony_ci            import {iomod} as io
35267db96d56Sopenharmony_ci
35277db96d56Sopenharmony_ci            # Avoid looking up codecs at shutdown
35287db96d56Sopenharmony_ci            codecs.lookup('utf-8')
35297db96d56Sopenharmony_ci
35307db96d56Sopenharmony_ci            class C:
35317db96d56Sopenharmony_ci                def __init__(self):
35327db96d56Sopenharmony_ci                    self.buf = io.BytesIO()
35337db96d56Sopenharmony_ci                def __del__(self):
35347db96d56Sopenharmony_ci                    io.TextIOWrapper(self.buf, **{kwargs})
35357db96d56Sopenharmony_ci                    print("ok")
35367db96d56Sopenharmony_ci            c = C()
35377db96d56Sopenharmony_ci            """.format(iomod=iomod, kwargs=kwargs)
35387db96d56Sopenharmony_ci        return assert_python_ok("-c", code)
35397db96d56Sopenharmony_ci
35407db96d56Sopenharmony_ci    def test_create_at_shutdown_without_encoding(self):
35417db96d56Sopenharmony_ci        rc, out, err = self._check_create_at_shutdown()
35427db96d56Sopenharmony_ci        if err:
35437db96d56Sopenharmony_ci            # Can error out with a RuntimeError if the module state
35447db96d56Sopenharmony_ci            # isn't found.
35457db96d56Sopenharmony_ci            self.assertIn(self.shutdown_error, err.decode())
35467db96d56Sopenharmony_ci        else:
35477db96d56Sopenharmony_ci            self.assertEqual("ok", out.decode().strip())
35487db96d56Sopenharmony_ci
35497db96d56Sopenharmony_ci    def test_create_at_shutdown_with_encoding(self):
35507db96d56Sopenharmony_ci        rc, out, err = self._check_create_at_shutdown(encoding='utf-8',
35517db96d56Sopenharmony_ci                                                      errors='strict')
35527db96d56Sopenharmony_ci        self.assertFalse(err)
35537db96d56Sopenharmony_ci        self.assertEqual("ok", out.decode().strip())
35547db96d56Sopenharmony_ci
35557db96d56Sopenharmony_ci    def test_read_byteslike(self):
35567db96d56Sopenharmony_ci        r = MemviewBytesIO(b'Just some random string\n')
35577db96d56Sopenharmony_ci        t = self.TextIOWrapper(r, 'utf-8')
35587db96d56Sopenharmony_ci
35597db96d56Sopenharmony_ci        # TextIOwrapper will not read the full string, because
35607db96d56Sopenharmony_ci        # we truncate it to a multiple of the native int size
35617db96d56Sopenharmony_ci        # so that we can construct a more complex memoryview.
35627db96d56Sopenharmony_ci        bytes_val =  _to_memoryview(r.getvalue()).tobytes()
35637db96d56Sopenharmony_ci
35647db96d56Sopenharmony_ci        self.assertEqual(t.read(200), bytes_val.decode('utf-8'))
35657db96d56Sopenharmony_ci
35667db96d56Sopenharmony_ci    def test_issue22849(self):
35677db96d56Sopenharmony_ci        class F(object):
35687db96d56Sopenharmony_ci            def readable(self): return True
35697db96d56Sopenharmony_ci            def writable(self): return True
35707db96d56Sopenharmony_ci            def seekable(self): return True
35717db96d56Sopenharmony_ci
35727db96d56Sopenharmony_ci        for i in range(10):
35737db96d56Sopenharmony_ci            try:
35747db96d56Sopenharmony_ci                self.TextIOWrapper(F(), encoding='utf-8')
35757db96d56Sopenharmony_ci            except Exception:
35767db96d56Sopenharmony_ci                pass
35777db96d56Sopenharmony_ci
35787db96d56Sopenharmony_ci        F.tell = lambda x: 0
35797db96d56Sopenharmony_ci        t = self.TextIOWrapper(F(), encoding='utf-8')
35807db96d56Sopenharmony_ci
35817db96d56Sopenharmony_ci    def test_reconfigure_locale(self):
35827db96d56Sopenharmony_ci        wrapper = io.TextIOWrapper(io.BytesIO(b"test"))
35837db96d56Sopenharmony_ci        wrapper.reconfigure(encoding="locale")
35847db96d56Sopenharmony_ci
35857db96d56Sopenharmony_ci    def test_reconfigure_encoding_read(self):
35867db96d56Sopenharmony_ci        # latin1 -> utf8
35877db96d56Sopenharmony_ci        # (latin1 can decode utf-8 encoded string)
35887db96d56Sopenharmony_ci        data = 'abc\xe9\n'.encode('latin1') + 'd\xe9f\n'.encode('utf8')
35897db96d56Sopenharmony_ci        raw = self.BytesIO(data)
35907db96d56Sopenharmony_ci        txt = self.TextIOWrapper(raw, encoding='latin1', newline='\n')
35917db96d56Sopenharmony_ci        self.assertEqual(txt.readline(), 'abc\xe9\n')
35927db96d56Sopenharmony_ci        with self.assertRaises(self.UnsupportedOperation):
35937db96d56Sopenharmony_ci            txt.reconfigure(encoding='utf-8')
35947db96d56Sopenharmony_ci        with self.assertRaises(self.UnsupportedOperation):
35957db96d56Sopenharmony_ci            txt.reconfigure(newline=None)
35967db96d56Sopenharmony_ci
35977db96d56Sopenharmony_ci    def test_reconfigure_write_fromascii(self):
35987db96d56Sopenharmony_ci        # ascii has a specific encodefunc in the C implementation,
35997db96d56Sopenharmony_ci        # but utf-8-sig has not. Make sure that we get rid of the
36007db96d56Sopenharmony_ci        # cached encodefunc when we switch encoders.
36017db96d56Sopenharmony_ci        raw = self.BytesIO()
36027db96d56Sopenharmony_ci        txt = self.TextIOWrapper(raw, encoding='ascii', newline='\n')
36037db96d56Sopenharmony_ci        txt.write('foo\n')
36047db96d56Sopenharmony_ci        txt.reconfigure(encoding='utf-8-sig')
36057db96d56Sopenharmony_ci        txt.write('\xe9\n')
36067db96d56Sopenharmony_ci        txt.flush()
36077db96d56Sopenharmony_ci        self.assertEqual(raw.getvalue(), b'foo\n\xc3\xa9\n')
36087db96d56Sopenharmony_ci
36097db96d56Sopenharmony_ci    def test_reconfigure_write(self):
36107db96d56Sopenharmony_ci        # latin -> utf8
36117db96d56Sopenharmony_ci        raw = self.BytesIO()
36127db96d56Sopenharmony_ci        txt = self.TextIOWrapper(raw, encoding='latin1', newline='\n')
36137db96d56Sopenharmony_ci        txt.write('abc\xe9\n')
36147db96d56Sopenharmony_ci        txt.reconfigure(encoding='utf-8')
36157db96d56Sopenharmony_ci        self.assertEqual(raw.getvalue(), b'abc\xe9\n')
36167db96d56Sopenharmony_ci        txt.write('d\xe9f\n')
36177db96d56Sopenharmony_ci        txt.flush()
36187db96d56Sopenharmony_ci        self.assertEqual(raw.getvalue(), b'abc\xe9\nd\xc3\xa9f\n')
36197db96d56Sopenharmony_ci
36207db96d56Sopenharmony_ci        # ascii -> utf-8-sig: ensure that no BOM is written in the middle of
36217db96d56Sopenharmony_ci        # the file
36227db96d56Sopenharmony_ci        raw = self.BytesIO()
36237db96d56Sopenharmony_ci        txt = self.TextIOWrapper(raw, encoding='ascii', newline='\n')
36247db96d56Sopenharmony_ci        txt.write('abc\n')
36257db96d56Sopenharmony_ci        txt.reconfigure(encoding='utf-8-sig')
36267db96d56Sopenharmony_ci        txt.write('d\xe9f\n')
36277db96d56Sopenharmony_ci        txt.flush()
36287db96d56Sopenharmony_ci        self.assertEqual(raw.getvalue(), b'abc\nd\xc3\xa9f\n')
36297db96d56Sopenharmony_ci
36307db96d56Sopenharmony_ci    def test_reconfigure_write_non_seekable(self):
36317db96d56Sopenharmony_ci        raw = self.BytesIO()
36327db96d56Sopenharmony_ci        raw.seekable = lambda: False
36337db96d56Sopenharmony_ci        raw.seek = None
36347db96d56Sopenharmony_ci        txt = self.TextIOWrapper(raw, encoding='ascii', newline='\n')
36357db96d56Sopenharmony_ci        txt.write('abc\n')
36367db96d56Sopenharmony_ci        txt.reconfigure(encoding='utf-8-sig')
36377db96d56Sopenharmony_ci        txt.write('d\xe9f\n')
36387db96d56Sopenharmony_ci        txt.flush()
36397db96d56Sopenharmony_ci
36407db96d56Sopenharmony_ci        # If the raw stream is not seekable, there'll be a BOM
36417db96d56Sopenharmony_ci        self.assertEqual(raw.getvalue(),  b'abc\n\xef\xbb\xbfd\xc3\xa9f\n')
36427db96d56Sopenharmony_ci
36437db96d56Sopenharmony_ci    def test_reconfigure_defaults(self):
36447db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(), 'ascii', 'replace', '\n')
36457db96d56Sopenharmony_ci        txt.reconfigure(encoding=None)
36467db96d56Sopenharmony_ci        self.assertEqual(txt.encoding, 'ascii')
36477db96d56Sopenharmony_ci        self.assertEqual(txt.errors, 'replace')
36487db96d56Sopenharmony_ci        txt.write('LF\n')
36497db96d56Sopenharmony_ci
36507db96d56Sopenharmony_ci        txt.reconfigure(newline='\r\n')
36517db96d56Sopenharmony_ci        self.assertEqual(txt.encoding, 'ascii')
36527db96d56Sopenharmony_ci        self.assertEqual(txt.errors, 'replace')
36537db96d56Sopenharmony_ci
36547db96d56Sopenharmony_ci        txt.reconfigure(errors='ignore')
36557db96d56Sopenharmony_ci        self.assertEqual(txt.encoding, 'ascii')
36567db96d56Sopenharmony_ci        self.assertEqual(txt.errors, 'ignore')
36577db96d56Sopenharmony_ci        txt.write('CRLF\n')
36587db96d56Sopenharmony_ci
36597db96d56Sopenharmony_ci        txt.reconfigure(encoding='utf-8', newline=None)
36607db96d56Sopenharmony_ci        self.assertEqual(txt.errors, 'strict')
36617db96d56Sopenharmony_ci        txt.seek(0)
36627db96d56Sopenharmony_ci        self.assertEqual(txt.read(), 'LF\nCRLF\n')
36637db96d56Sopenharmony_ci
36647db96d56Sopenharmony_ci        self.assertEqual(txt.detach().getvalue(), b'LF\nCRLF\r\n')
36657db96d56Sopenharmony_ci
36667db96d56Sopenharmony_ci    def test_reconfigure_newline(self):
36677db96d56Sopenharmony_ci        raw = self.BytesIO(b'CR\rEOF')
36687db96d56Sopenharmony_ci        txt = self.TextIOWrapper(raw, 'ascii', newline='\n')
36697db96d56Sopenharmony_ci        txt.reconfigure(newline=None)
36707db96d56Sopenharmony_ci        self.assertEqual(txt.readline(), 'CR\n')
36717db96d56Sopenharmony_ci        raw = self.BytesIO(b'CR\rEOF')
36727db96d56Sopenharmony_ci        txt = self.TextIOWrapper(raw, 'ascii', newline='\n')
36737db96d56Sopenharmony_ci        txt.reconfigure(newline='')
36747db96d56Sopenharmony_ci        self.assertEqual(txt.readline(), 'CR\r')
36757db96d56Sopenharmony_ci        raw = self.BytesIO(b'CR\rLF\nEOF')
36767db96d56Sopenharmony_ci        txt = self.TextIOWrapper(raw, 'ascii', newline='\r')
36777db96d56Sopenharmony_ci        txt.reconfigure(newline='\n')
36787db96d56Sopenharmony_ci        self.assertEqual(txt.readline(), 'CR\rLF\n')
36797db96d56Sopenharmony_ci        raw = self.BytesIO(b'LF\nCR\rEOF')
36807db96d56Sopenharmony_ci        txt = self.TextIOWrapper(raw, 'ascii', newline='\n')
36817db96d56Sopenharmony_ci        txt.reconfigure(newline='\r')
36827db96d56Sopenharmony_ci        self.assertEqual(txt.readline(), 'LF\nCR\r')
36837db96d56Sopenharmony_ci        raw = self.BytesIO(b'CR\rCRLF\r\nEOF')
36847db96d56Sopenharmony_ci        txt = self.TextIOWrapper(raw, 'ascii', newline='\r')
36857db96d56Sopenharmony_ci        txt.reconfigure(newline='\r\n')
36867db96d56Sopenharmony_ci        self.assertEqual(txt.readline(), 'CR\rCRLF\r\n')
36877db96d56Sopenharmony_ci
36887db96d56Sopenharmony_ci        txt = self.TextIOWrapper(self.BytesIO(), 'ascii', newline='\r')
36897db96d56Sopenharmony_ci        txt.reconfigure(newline=None)
36907db96d56Sopenharmony_ci        txt.write('linesep\n')
36917db96d56Sopenharmony_ci        txt.reconfigure(newline='')
36927db96d56Sopenharmony_ci        txt.write('LF\n')
36937db96d56Sopenharmony_ci        txt.reconfigure(newline='\n')
36947db96d56Sopenharmony_ci        txt.write('LF\n')
36957db96d56Sopenharmony_ci        txt.reconfigure(newline='\r')
36967db96d56Sopenharmony_ci        txt.write('CR\n')
36977db96d56Sopenharmony_ci        txt.reconfigure(newline='\r\n')
36987db96d56Sopenharmony_ci        txt.write('CRLF\n')
36997db96d56Sopenharmony_ci        expected = 'linesep' + os.linesep + 'LF\nLF\nCR\rCRLF\r\n'
37007db96d56Sopenharmony_ci        self.assertEqual(txt.detach().getvalue().decode('ascii'), expected)
37017db96d56Sopenharmony_ci
37027db96d56Sopenharmony_ci    def test_issue25862(self):
37037db96d56Sopenharmony_ci        # Assertion failures occurred in tell() after read() and write().
37047db96d56Sopenharmony_ci        t = self.TextIOWrapper(self.BytesIO(b'test'), encoding='ascii')
37057db96d56Sopenharmony_ci        t.read(1)
37067db96d56Sopenharmony_ci        t.read()
37077db96d56Sopenharmony_ci        t.tell()
37087db96d56Sopenharmony_ci        t = self.TextIOWrapper(self.BytesIO(b'test'), encoding='ascii')
37097db96d56Sopenharmony_ci        t.read(1)
37107db96d56Sopenharmony_ci        t.write('x')
37117db96d56Sopenharmony_ci        t.tell()
37127db96d56Sopenharmony_ci
37137db96d56Sopenharmony_ci
37147db96d56Sopenharmony_ciclass MemviewBytesIO(io.BytesIO):
37157db96d56Sopenharmony_ci    '''A BytesIO object whose read method returns memoryviews
37167db96d56Sopenharmony_ci       rather than bytes'''
37177db96d56Sopenharmony_ci
37187db96d56Sopenharmony_ci    def read1(self, len_):
37197db96d56Sopenharmony_ci        return _to_memoryview(super().read1(len_))
37207db96d56Sopenharmony_ci
37217db96d56Sopenharmony_ci    def read(self, len_):
37227db96d56Sopenharmony_ci        return _to_memoryview(super().read(len_))
37237db96d56Sopenharmony_ci
37247db96d56Sopenharmony_cidef _to_memoryview(buf):
37257db96d56Sopenharmony_ci    '''Convert bytes-object *buf* to a non-trivial memoryview'''
37267db96d56Sopenharmony_ci
37277db96d56Sopenharmony_ci    arr = array.array('i')
37287db96d56Sopenharmony_ci    idx = len(buf) - len(buf) % arr.itemsize
37297db96d56Sopenharmony_ci    arr.frombytes(buf[:idx])
37307db96d56Sopenharmony_ci    return memoryview(arr)
37317db96d56Sopenharmony_ci
37327db96d56Sopenharmony_ci
37337db96d56Sopenharmony_ciclass CTextIOWrapperTest(TextIOWrapperTest):
37347db96d56Sopenharmony_ci    io = io
37357db96d56Sopenharmony_ci    shutdown_error = "LookupError: unknown encoding: ascii"
37367db96d56Sopenharmony_ci
37377db96d56Sopenharmony_ci    def test_initialization(self):
37387db96d56Sopenharmony_ci        r = self.BytesIO(b"\xc3\xa9\n\n")
37397db96d56Sopenharmony_ci        b = self.BufferedReader(r, 1000)
37407db96d56Sopenharmony_ci        t = self.TextIOWrapper(b, encoding="utf-8")
37417db96d56Sopenharmony_ci        self.assertRaises(ValueError, t.__init__, b, encoding="utf-8", newline='xyzzy')
37427db96d56Sopenharmony_ci        self.assertRaises(ValueError, t.read)
37437db96d56Sopenharmony_ci
37447db96d56Sopenharmony_ci        t = self.TextIOWrapper.__new__(self.TextIOWrapper)
37457db96d56Sopenharmony_ci        self.assertRaises(Exception, repr, t)
37467db96d56Sopenharmony_ci
37477db96d56Sopenharmony_ci    def test_garbage_collection(self):
37487db96d56Sopenharmony_ci        # C TextIOWrapper objects are collected, and collecting them flushes
37497db96d56Sopenharmony_ci        # all data to disk.
37507db96d56Sopenharmony_ci        # The Python version has __del__, so it ends in gc.garbage instead.
37517db96d56Sopenharmony_ci        with warnings_helper.check_warnings(('', ResourceWarning)):
37527db96d56Sopenharmony_ci            rawio = io.FileIO(os_helper.TESTFN, "wb")
37537db96d56Sopenharmony_ci            b = self.BufferedWriter(rawio)
37547db96d56Sopenharmony_ci            t = self.TextIOWrapper(b, encoding="ascii")
37557db96d56Sopenharmony_ci            t.write("456def")
37567db96d56Sopenharmony_ci            t.x = t
37577db96d56Sopenharmony_ci            wr = weakref.ref(t)
37587db96d56Sopenharmony_ci            del t
37597db96d56Sopenharmony_ci            support.gc_collect()
37607db96d56Sopenharmony_ci        self.assertIsNone(wr(), wr)
37617db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "rb") as f:
37627db96d56Sopenharmony_ci            self.assertEqual(f.read(), b"456def")
37637db96d56Sopenharmony_ci
37647db96d56Sopenharmony_ci    def test_rwpair_cleared_before_textio(self):
37657db96d56Sopenharmony_ci        # Issue 13070: TextIOWrapper's finalization would crash when called
37667db96d56Sopenharmony_ci        # after the reference to the underlying BufferedRWPair's writer got
37677db96d56Sopenharmony_ci        # cleared by the GC.
37687db96d56Sopenharmony_ci        for i in range(1000):
37697db96d56Sopenharmony_ci            b1 = self.BufferedRWPair(self.MockRawIO(), self.MockRawIO())
37707db96d56Sopenharmony_ci            t1 = self.TextIOWrapper(b1, encoding="ascii")
37717db96d56Sopenharmony_ci            b2 = self.BufferedRWPair(self.MockRawIO(), self.MockRawIO())
37727db96d56Sopenharmony_ci            t2 = self.TextIOWrapper(b2, encoding="ascii")
37737db96d56Sopenharmony_ci            # circular references
37747db96d56Sopenharmony_ci            t1.buddy = t2
37757db96d56Sopenharmony_ci            t2.buddy = t1
37767db96d56Sopenharmony_ci        support.gc_collect()
37777db96d56Sopenharmony_ci
37787db96d56Sopenharmony_ci    def test_del__CHUNK_SIZE_SystemError(self):
37797db96d56Sopenharmony_ci        t = self.TextIOWrapper(self.BytesIO(), encoding='ascii')
37807db96d56Sopenharmony_ci        with self.assertRaises(AttributeError):
37817db96d56Sopenharmony_ci            del t._CHUNK_SIZE
37827db96d56Sopenharmony_ci
37837db96d56Sopenharmony_ci    def test_internal_buffer_size(self):
37847db96d56Sopenharmony_ci        # bpo-43260: TextIOWrapper's internal buffer should not store
37857db96d56Sopenharmony_ci        # data larger than chunk size.
37867db96d56Sopenharmony_ci        chunk_size = 8192  # default chunk size, updated later
37877db96d56Sopenharmony_ci
37887db96d56Sopenharmony_ci        class MockIO(self.MockRawIO):
37897db96d56Sopenharmony_ci            def write(self, data):
37907db96d56Sopenharmony_ci                if len(data) > chunk_size:
37917db96d56Sopenharmony_ci                    raise RuntimeError
37927db96d56Sopenharmony_ci                return super().write(data)
37937db96d56Sopenharmony_ci
37947db96d56Sopenharmony_ci        buf = MockIO()
37957db96d56Sopenharmony_ci        t = self.TextIOWrapper(buf, encoding="ascii")
37967db96d56Sopenharmony_ci        chunk_size = t._CHUNK_SIZE
37977db96d56Sopenharmony_ci        t.write("abc")
37987db96d56Sopenharmony_ci        t.write("def")
37997db96d56Sopenharmony_ci        # default chunk size is 8192 bytes so t don't write data to buf.
38007db96d56Sopenharmony_ci        self.assertEqual([], buf._write_stack)
38017db96d56Sopenharmony_ci
38027db96d56Sopenharmony_ci        with self.assertRaises(RuntimeError):
38037db96d56Sopenharmony_ci            t.write("x"*(chunk_size+1))
38047db96d56Sopenharmony_ci
38057db96d56Sopenharmony_ci        self.assertEqual([b"abcdef"], buf._write_stack)
38067db96d56Sopenharmony_ci        t.write("ghi")
38077db96d56Sopenharmony_ci        t.write("x"*chunk_size)
38087db96d56Sopenharmony_ci        self.assertEqual([b"abcdef", b"ghi", b"x"*chunk_size], buf._write_stack)
38097db96d56Sopenharmony_ci
38107db96d56Sopenharmony_ci
38117db96d56Sopenharmony_ciclass PyTextIOWrapperTest(TextIOWrapperTest):
38127db96d56Sopenharmony_ci    io = pyio
38137db96d56Sopenharmony_ci    shutdown_error = "LookupError: unknown encoding: ascii"
38147db96d56Sopenharmony_ci
38157db96d56Sopenharmony_ci
38167db96d56Sopenharmony_ciclass IncrementalNewlineDecoderTest(unittest.TestCase):
38177db96d56Sopenharmony_ci
38187db96d56Sopenharmony_ci    def check_newline_decoding_utf8(self, decoder):
38197db96d56Sopenharmony_ci        # UTF-8 specific tests for a newline decoder
38207db96d56Sopenharmony_ci        def _check_decode(b, s, **kwargs):
38217db96d56Sopenharmony_ci            # We exercise getstate() / setstate() as well as decode()
38227db96d56Sopenharmony_ci            state = decoder.getstate()
38237db96d56Sopenharmony_ci            self.assertEqual(decoder.decode(b, **kwargs), s)
38247db96d56Sopenharmony_ci            decoder.setstate(state)
38257db96d56Sopenharmony_ci            self.assertEqual(decoder.decode(b, **kwargs), s)
38267db96d56Sopenharmony_ci
38277db96d56Sopenharmony_ci        _check_decode(b'\xe8\xa2\x88', "\u8888")
38287db96d56Sopenharmony_ci
38297db96d56Sopenharmony_ci        _check_decode(b'\xe8', "")
38307db96d56Sopenharmony_ci        _check_decode(b'\xa2', "")
38317db96d56Sopenharmony_ci        _check_decode(b'\x88', "\u8888")
38327db96d56Sopenharmony_ci
38337db96d56Sopenharmony_ci        _check_decode(b'\xe8', "")
38347db96d56Sopenharmony_ci        _check_decode(b'\xa2', "")
38357db96d56Sopenharmony_ci        _check_decode(b'\x88', "\u8888")
38367db96d56Sopenharmony_ci
38377db96d56Sopenharmony_ci        _check_decode(b'\xe8', "")
38387db96d56Sopenharmony_ci        self.assertRaises(UnicodeDecodeError, decoder.decode, b'', final=True)
38397db96d56Sopenharmony_ci
38407db96d56Sopenharmony_ci        decoder.reset()
38417db96d56Sopenharmony_ci        _check_decode(b'\n', "\n")
38427db96d56Sopenharmony_ci        _check_decode(b'\r', "")
38437db96d56Sopenharmony_ci        _check_decode(b'', "\n", final=True)
38447db96d56Sopenharmony_ci        _check_decode(b'\r', "\n", final=True)
38457db96d56Sopenharmony_ci
38467db96d56Sopenharmony_ci        _check_decode(b'\r', "")
38477db96d56Sopenharmony_ci        _check_decode(b'a', "\na")
38487db96d56Sopenharmony_ci
38497db96d56Sopenharmony_ci        _check_decode(b'\r\r\n', "\n\n")
38507db96d56Sopenharmony_ci        _check_decode(b'\r', "")
38517db96d56Sopenharmony_ci        _check_decode(b'\r', "\n")
38527db96d56Sopenharmony_ci        _check_decode(b'\na', "\na")
38537db96d56Sopenharmony_ci
38547db96d56Sopenharmony_ci        _check_decode(b'\xe8\xa2\x88\r\n', "\u8888\n")
38557db96d56Sopenharmony_ci        _check_decode(b'\xe8\xa2\x88', "\u8888")
38567db96d56Sopenharmony_ci        _check_decode(b'\n', "\n")
38577db96d56Sopenharmony_ci        _check_decode(b'\xe8\xa2\x88\r', "\u8888")
38587db96d56Sopenharmony_ci        _check_decode(b'\n', "\n")
38597db96d56Sopenharmony_ci
38607db96d56Sopenharmony_ci    def check_newline_decoding(self, decoder, encoding):
38617db96d56Sopenharmony_ci        result = []
38627db96d56Sopenharmony_ci        if encoding is not None:
38637db96d56Sopenharmony_ci            encoder = codecs.getincrementalencoder(encoding)()
38647db96d56Sopenharmony_ci            def _decode_bytewise(s):
38657db96d56Sopenharmony_ci                # Decode one byte at a time
38667db96d56Sopenharmony_ci                for b in encoder.encode(s):
38677db96d56Sopenharmony_ci                    result.append(decoder.decode(bytes([b])))
38687db96d56Sopenharmony_ci        else:
38697db96d56Sopenharmony_ci            encoder = None
38707db96d56Sopenharmony_ci            def _decode_bytewise(s):
38717db96d56Sopenharmony_ci                # Decode one char at a time
38727db96d56Sopenharmony_ci                for c in s:
38737db96d56Sopenharmony_ci                    result.append(decoder.decode(c))
38747db96d56Sopenharmony_ci        self.assertEqual(decoder.newlines, None)
38757db96d56Sopenharmony_ci        _decode_bytewise("abc\n\r")
38767db96d56Sopenharmony_ci        self.assertEqual(decoder.newlines, '\n')
38777db96d56Sopenharmony_ci        _decode_bytewise("\nabc")
38787db96d56Sopenharmony_ci        self.assertEqual(decoder.newlines, ('\n', '\r\n'))
38797db96d56Sopenharmony_ci        _decode_bytewise("abc\r")
38807db96d56Sopenharmony_ci        self.assertEqual(decoder.newlines, ('\n', '\r\n'))
38817db96d56Sopenharmony_ci        _decode_bytewise("abc")
38827db96d56Sopenharmony_ci        self.assertEqual(decoder.newlines, ('\r', '\n', '\r\n'))
38837db96d56Sopenharmony_ci        _decode_bytewise("abc\r")
38847db96d56Sopenharmony_ci        self.assertEqual("".join(result), "abc\n\nabcabc\nabcabc")
38857db96d56Sopenharmony_ci        decoder.reset()
38867db96d56Sopenharmony_ci        input = "abc"
38877db96d56Sopenharmony_ci        if encoder is not None:
38887db96d56Sopenharmony_ci            encoder.reset()
38897db96d56Sopenharmony_ci            input = encoder.encode(input)
38907db96d56Sopenharmony_ci        self.assertEqual(decoder.decode(input), "abc")
38917db96d56Sopenharmony_ci        self.assertEqual(decoder.newlines, None)
38927db96d56Sopenharmony_ci
38937db96d56Sopenharmony_ci    def test_newline_decoder(self):
38947db96d56Sopenharmony_ci        encodings = (
38957db96d56Sopenharmony_ci            # None meaning the IncrementalNewlineDecoder takes unicode input
38967db96d56Sopenharmony_ci            # rather than bytes input
38977db96d56Sopenharmony_ci            None, 'utf-8', 'latin-1',
38987db96d56Sopenharmony_ci            'utf-16', 'utf-16-le', 'utf-16-be',
38997db96d56Sopenharmony_ci            'utf-32', 'utf-32-le', 'utf-32-be',
39007db96d56Sopenharmony_ci        )
39017db96d56Sopenharmony_ci        for enc in encodings:
39027db96d56Sopenharmony_ci            decoder = enc and codecs.getincrementaldecoder(enc)()
39037db96d56Sopenharmony_ci            decoder = self.IncrementalNewlineDecoder(decoder, translate=True)
39047db96d56Sopenharmony_ci            self.check_newline_decoding(decoder, enc)
39057db96d56Sopenharmony_ci        decoder = codecs.getincrementaldecoder("utf-8")()
39067db96d56Sopenharmony_ci        decoder = self.IncrementalNewlineDecoder(decoder, translate=True)
39077db96d56Sopenharmony_ci        self.check_newline_decoding_utf8(decoder)
39087db96d56Sopenharmony_ci        self.assertRaises(TypeError, decoder.setstate, 42)
39097db96d56Sopenharmony_ci
39107db96d56Sopenharmony_ci    def test_newline_bytes(self):
39117db96d56Sopenharmony_ci        # Issue 5433: Excessive optimization in IncrementalNewlineDecoder
39127db96d56Sopenharmony_ci        def _check(dec):
39137db96d56Sopenharmony_ci            self.assertEqual(dec.newlines, None)
39147db96d56Sopenharmony_ci            self.assertEqual(dec.decode("\u0D00"), "\u0D00")
39157db96d56Sopenharmony_ci            self.assertEqual(dec.newlines, None)
39167db96d56Sopenharmony_ci            self.assertEqual(dec.decode("\u0A00"), "\u0A00")
39177db96d56Sopenharmony_ci            self.assertEqual(dec.newlines, None)
39187db96d56Sopenharmony_ci        dec = self.IncrementalNewlineDecoder(None, translate=False)
39197db96d56Sopenharmony_ci        _check(dec)
39207db96d56Sopenharmony_ci        dec = self.IncrementalNewlineDecoder(None, translate=True)
39217db96d56Sopenharmony_ci        _check(dec)
39227db96d56Sopenharmony_ci
39237db96d56Sopenharmony_ci    def test_translate(self):
39247db96d56Sopenharmony_ci        # issue 35062
39257db96d56Sopenharmony_ci        for translate in (-2, -1, 1, 2):
39267db96d56Sopenharmony_ci            decoder = codecs.getincrementaldecoder("utf-8")()
39277db96d56Sopenharmony_ci            decoder = self.IncrementalNewlineDecoder(decoder, translate)
39287db96d56Sopenharmony_ci            self.check_newline_decoding_utf8(decoder)
39297db96d56Sopenharmony_ci        decoder = codecs.getincrementaldecoder("utf-8")()
39307db96d56Sopenharmony_ci        decoder = self.IncrementalNewlineDecoder(decoder, translate=0)
39317db96d56Sopenharmony_ci        self.assertEqual(decoder.decode(b"\r\r\n"), "\r\r\n")
39327db96d56Sopenharmony_ci
39337db96d56Sopenharmony_ciclass CIncrementalNewlineDecoderTest(IncrementalNewlineDecoderTest):
39347db96d56Sopenharmony_ci    @support.cpython_only
39357db96d56Sopenharmony_ci    def test_uninitialized(self):
39367db96d56Sopenharmony_ci        uninitialized = self.IncrementalNewlineDecoder.__new__(
39377db96d56Sopenharmony_ci            self.IncrementalNewlineDecoder)
39387db96d56Sopenharmony_ci        self.assertRaises(ValueError, uninitialized.decode, b'bar')
39397db96d56Sopenharmony_ci        self.assertRaises(ValueError, uninitialized.getstate)
39407db96d56Sopenharmony_ci        self.assertRaises(ValueError, uninitialized.setstate, (b'foo', 0))
39417db96d56Sopenharmony_ci        self.assertRaises(ValueError, uninitialized.reset)
39427db96d56Sopenharmony_ci
39437db96d56Sopenharmony_ci
39447db96d56Sopenharmony_ciclass PyIncrementalNewlineDecoderTest(IncrementalNewlineDecoderTest):
39457db96d56Sopenharmony_ci    pass
39467db96d56Sopenharmony_ci
39477db96d56Sopenharmony_ci
39487db96d56Sopenharmony_ci# XXX Tests for open()
39497db96d56Sopenharmony_ci
39507db96d56Sopenharmony_ciclass MiscIOTest(unittest.TestCase):
39517db96d56Sopenharmony_ci
39527db96d56Sopenharmony_ci    def tearDown(self):
39537db96d56Sopenharmony_ci        os_helper.unlink(os_helper.TESTFN)
39547db96d56Sopenharmony_ci
39557db96d56Sopenharmony_ci    def test___all__(self):
39567db96d56Sopenharmony_ci        for name in self.io.__all__:
39577db96d56Sopenharmony_ci            obj = getattr(self.io, name, None)
39587db96d56Sopenharmony_ci            self.assertIsNotNone(obj, name)
39597db96d56Sopenharmony_ci            if name in ("open", "open_code"):
39607db96d56Sopenharmony_ci                continue
39617db96d56Sopenharmony_ci            elif "error" in name.lower() or name == "UnsupportedOperation":
39627db96d56Sopenharmony_ci                self.assertTrue(issubclass(obj, Exception), name)
39637db96d56Sopenharmony_ci            elif not name.startswith("SEEK_"):
39647db96d56Sopenharmony_ci                self.assertTrue(issubclass(obj, self.IOBase))
39657db96d56Sopenharmony_ci
39667db96d56Sopenharmony_ci    def test_attributes(self):
39677db96d56Sopenharmony_ci        f = self.open(os_helper.TESTFN, "wb", buffering=0)
39687db96d56Sopenharmony_ci        self.assertEqual(f.mode, "wb")
39697db96d56Sopenharmony_ci        f.close()
39707db96d56Sopenharmony_ci
39717db96d56Sopenharmony_ci        f = self.open(os_helper.TESTFN, "w+", encoding="utf-8")
39727db96d56Sopenharmony_ci        self.assertEqual(f.mode,            "w+")
39737db96d56Sopenharmony_ci        self.assertEqual(f.buffer.mode,     "rb+") # Does it really matter?
39747db96d56Sopenharmony_ci        self.assertEqual(f.buffer.raw.mode, "rb+")
39757db96d56Sopenharmony_ci
39767db96d56Sopenharmony_ci        g = self.open(f.fileno(), "wb", closefd=False)
39777db96d56Sopenharmony_ci        self.assertEqual(g.mode,     "wb")
39787db96d56Sopenharmony_ci        self.assertEqual(g.raw.mode, "wb")
39797db96d56Sopenharmony_ci        self.assertEqual(g.name,     f.fileno())
39807db96d56Sopenharmony_ci        self.assertEqual(g.raw.name, f.fileno())
39817db96d56Sopenharmony_ci        f.close()
39827db96d56Sopenharmony_ci        g.close()
39837db96d56Sopenharmony_ci
39847db96d56Sopenharmony_ci    def test_removed_u_mode(self):
39857db96d56Sopenharmony_ci        # bpo-37330: The "U" mode has been removed in Python 3.11
39867db96d56Sopenharmony_ci        for mode in ("U", "rU", "r+U"):
39877db96d56Sopenharmony_ci            with self.assertRaises(ValueError) as cm:
39887db96d56Sopenharmony_ci                self.open(os_helper.TESTFN, mode)
39897db96d56Sopenharmony_ci            self.assertIn('invalid mode', str(cm.exception))
39907db96d56Sopenharmony_ci
39917db96d56Sopenharmony_ci    @unittest.skipIf(
39927db96d56Sopenharmony_ci        support.is_emscripten, "fstat() of a pipe fd is not supported"
39937db96d56Sopenharmony_ci    )
39947db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
39957db96d56Sopenharmony_ci    def test_open_pipe_with_append(self):
39967db96d56Sopenharmony_ci        # bpo-27805: Ignore ESPIPE from lseek() in open().
39977db96d56Sopenharmony_ci        r, w = os.pipe()
39987db96d56Sopenharmony_ci        self.addCleanup(os.close, r)
39997db96d56Sopenharmony_ci        f = self.open(w, 'a', encoding="utf-8")
40007db96d56Sopenharmony_ci        self.addCleanup(f.close)
40017db96d56Sopenharmony_ci        # Check that the file is marked non-seekable. On Windows, however, lseek
40027db96d56Sopenharmony_ci        # somehow succeeds on pipes.
40037db96d56Sopenharmony_ci        if sys.platform != 'win32':
40047db96d56Sopenharmony_ci            self.assertFalse(f.seekable())
40057db96d56Sopenharmony_ci
40067db96d56Sopenharmony_ci    def test_io_after_close(self):
40077db96d56Sopenharmony_ci        for kwargs in [
40087db96d56Sopenharmony_ci                {"mode": "w"},
40097db96d56Sopenharmony_ci                {"mode": "wb"},
40107db96d56Sopenharmony_ci                {"mode": "w", "buffering": 1},
40117db96d56Sopenharmony_ci                {"mode": "w", "buffering": 2},
40127db96d56Sopenharmony_ci                {"mode": "wb", "buffering": 0},
40137db96d56Sopenharmony_ci                {"mode": "r"},
40147db96d56Sopenharmony_ci                {"mode": "rb"},
40157db96d56Sopenharmony_ci                {"mode": "r", "buffering": 1},
40167db96d56Sopenharmony_ci                {"mode": "r", "buffering": 2},
40177db96d56Sopenharmony_ci                {"mode": "rb", "buffering": 0},
40187db96d56Sopenharmony_ci                {"mode": "w+"},
40197db96d56Sopenharmony_ci                {"mode": "w+b"},
40207db96d56Sopenharmony_ci                {"mode": "w+", "buffering": 1},
40217db96d56Sopenharmony_ci                {"mode": "w+", "buffering": 2},
40227db96d56Sopenharmony_ci                {"mode": "w+b", "buffering": 0},
40237db96d56Sopenharmony_ci            ]:
40247db96d56Sopenharmony_ci            if "b" not in kwargs["mode"]:
40257db96d56Sopenharmony_ci                kwargs["encoding"] = "utf-8"
40267db96d56Sopenharmony_ci            f = self.open(os_helper.TESTFN, **kwargs)
40277db96d56Sopenharmony_ci            f.close()
40287db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.flush)
40297db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.fileno)
40307db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.isatty)
40317db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.__iter__)
40327db96d56Sopenharmony_ci            if hasattr(f, "peek"):
40337db96d56Sopenharmony_ci                self.assertRaises(ValueError, f.peek, 1)
40347db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.read)
40357db96d56Sopenharmony_ci            if hasattr(f, "read1"):
40367db96d56Sopenharmony_ci                self.assertRaises(ValueError, f.read1, 1024)
40377db96d56Sopenharmony_ci                self.assertRaises(ValueError, f.read1)
40387db96d56Sopenharmony_ci            if hasattr(f, "readall"):
40397db96d56Sopenharmony_ci                self.assertRaises(ValueError, f.readall)
40407db96d56Sopenharmony_ci            if hasattr(f, "readinto"):
40417db96d56Sopenharmony_ci                self.assertRaises(ValueError, f.readinto, bytearray(1024))
40427db96d56Sopenharmony_ci            if hasattr(f, "readinto1"):
40437db96d56Sopenharmony_ci                self.assertRaises(ValueError, f.readinto1, bytearray(1024))
40447db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.readline)
40457db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.readlines)
40467db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.readlines, 1)
40477db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.seek, 0)
40487db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.tell)
40497db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.truncate)
40507db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.write,
40517db96d56Sopenharmony_ci                              b"" if "b" in kwargs['mode'] else "")
40527db96d56Sopenharmony_ci            self.assertRaises(ValueError, f.writelines, [])
40537db96d56Sopenharmony_ci            self.assertRaises(ValueError, next, f)
40547db96d56Sopenharmony_ci
40557db96d56Sopenharmony_ci    def test_blockingioerror(self):
40567db96d56Sopenharmony_ci        # Various BlockingIOError issues
40577db96d56Sopenharmony_ci        class C(str):
40587db96d56Sopenharmony_ci            pass
40597db96d56Sopenharmony_ci        c = C("")
40607db96d56Sopenharmony_ci        b = self.BlockingIOError(1, c)
40617db96d56Sopenharmony_ci        c.b = b
40627db96d56Sopenharmony_ci        b.c = c
40637db96d56Sopenharmony_ci        wr = weakref.ref(c)
40647db96d56Sopenharmony_ci        del c, b
40657db96d56Sopenharmony_ci        support.gc_collect()
40667db96d56Sopenharmony_ci        self.assertIsNone(wr(), wr)
40677db96d56Sopenharmony_ci
40687db96d56Sopenharmony_ci    def test_abcs(self):
40697db96d56Sopenharmony_ci        # Test the visible base classes are ABCs.
40707db96d56Sopenharmony_ci        self.assertIsInstance(self.IOBase, abc.ABCMeta)
40717db96d56Sopenharmony_ci        self.assertIsInstance(self.RawIOBase, abc.ABCMeta)
40727db96d56Sopenharmony_ci        self.assertIsInstance(self.BufferedIOBase, abc.ABCMeta)
40737db96d56Sopenharmony_ci        self.assertIsInstance(self.TextIOBase, abc.ABCMeta)
40747db96d56Sopenharmony_ci
40757db96d56Sopenharmony_ci    def _check_abc_inheritance(self, abcmodule):
40767db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb", buffering=0) as f:
40777db96d56Sopenharmony_ci            self.assertIsInstance(f, abcmodule.IOBase)
40787db96d56Sopenharmony_ci            self.assertIsInstance(f, abcmodule.RawIOBase)
40797db96d56Sopenharmony_ci            self.assertNotIsInstance(f, abcmodule.BufferedIOBase)
40807db96d56Sopenharmony_ci            self.assertNotIsInstance(f, abcmodule.TextIOBase)
40817db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "wb") as f:
40827db96d56Sopenharmony_ci            self.assertIsInstance(f, abcmodule.IOBase)
40837db96d56Sopenharmony_ci            self.assertNotIsInstance(f, abcmodule.RawIOBase)
40847db96d56Sopenharmony_ci            self.assertIsInstance(f, abcmodule.BufferedIOBase)
40857db96d56Sopenharmony_ci            self.assertNotIsInstance(f, abcmodule.TextIOBase)
40867db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, "w", encoding="utf-8") as f:
40877db96d56Sopenharmony_ci            self.assertIsInstance(f, abcmodule.IOBase)
40887db96d56Sopenharmony_ci            self.assertNotIsInstance(f, abcmodule.RawIOBase)
40897db96d56Sopenharmony_ci            self.assertNotIsInstance(f, abcmodule.BufferedIOBase)
40907db96d56Sopenharmony_ci            self.assertIsInstance(f, abcmodule.TextIOBase)
40917db96d56Sopenharmony_ci
40927db96d56Sopenharmony_ci    def test_abc_inheritance(self):
40937db96d56Sopenharmony_ci        # Test implementations inherit from their respective ABCs
40947db96d56Sopenharmony_ci        self._check_abc_inheritance(self)
40957db96d56Sopenharmony_ci
40967db96d56Sopenharmony_ci    def test_abc_inheritance_official(self):
40977db96d56Sopenharmony_ci        # Test implementations inherit from the official ABCs of the
40987db96d56Sopenharmony_ci        # baseline "io" module.
40997db96d56Sopenharmony_ci        self._check_abc_inheritance(io)
41007db96d56Sopenharmony_ci
41017db96d56Sopenharmony_ci    def _check_warn_on_dealloc(self, *args, **kwargs):
41027db96d56Sopenharmony_ci        f = open(*args, **kwargs)
41037db96d56Sopenharmony_ci        r = repr(f)
41047db96d56Sopenharmony_ci        with self.assertWarns(ResourceWarning) as cm:
41057db96d56Sopenharmony_ci            f = None
41067db96d56Sopenharmony_ci            support.gc_collect()
41077db96d56Sopenharmony_ci        self.assertIn(r, str(cm.warning.args[0]))
41087db96d56Sopenharmony_ci
41097db96d56Sopenharmony_ci    def test_warn_on_dealloc(self):
41107db96d56Sopenharmony_ci        self._check_warn_on_dealloc(os_helper.TESTFN, "wb", buffering=0)
41117db96d56Sopenharmony_ci        self._check_warn_on_dealloc(os_helper.TESTFN, "wb")
41127db96d56Sopenharmony_ci        self._check_warn_on_dealloc(os_helper.TESTFN, "w", encoding="utf-8")
41137db96d56Sopenharmony_ci
41147db96d56Sopenharmony_ci    def _check_warn_on_dealloc_fd(self, *args, **kwargs):
41157db96d56Sopenharmony_ci        fds = []
41167db96d56Sopenharmony_ci        def cleanup_fds():
41177db96d56Sopenharmony_ci            for fd in fds:
41187db96d56Sopenharmony_ci                try:
41197db96d56Sopenharmony_ci                    os.close(fd)
41207db96d56Sopenharmony_ci                except OSError as e:
41217db96d56Sopenharmony_ci                    if e.errno != errno.EBADF:
41227db96d56Sopenharmony_ci                        raise
41237db96d56Sopenharmony_ci        self.addCleanup(cleanup_fds)
41247db96d56Sopenharmony_ci        r, w = os.pipe()
41257db96d56Sopenharmony_ci        fds += r, w
41267db96d56Sopenharmony_ci        self._check_warn_on_dealloc(r, *args, **kwargs)
41277db96d56Sopenharmony_ci        # When using closefd=False, there's no warning
41287db96d56Sopenharmony_ci        r, w = os.pipe()
41297db96d56Sopenharmony_ci        fds += r, w
41307db96d56Sopenharmony_ci        with warnings_helper.check_no_resource_warning(self):
41317db96d56Sopenharmony_ci            open(r, *args, closefd=False, **kwargs)
41327db96d56Sopenharmony_ci
41337db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
41347db96d56Sopenharmony_ci    def test_warn_on_dealloc_fd(self):
41357db96d56Sopenharmony_ci        self._check_warn_on_dealloc_fd("rb", buffering=0)
41367db96d56Sopenharmony_ci        self._check_warn_on_dealloc_fd("rb")
41377db96d56Sopenharmony_ci        self._check_warn_on_dealloc_fd("r", encoding="utf-8")
41387db96d56Sopenharmony_ci
41397db96d56Sopenharmony_ci
41407db96d56Sopenharmony_ci    def test_pickling(self):
41417db96d56Sopenharmony_ci        # Pickling file objects is forbidden
41427db96d56Sopenharmony_ci        for kwargs in [
41437db96d56Sopenharmony_ci                {"mode": "w"},
41447db96d56Sopenharmony_ci                {"mode": "wb"},
41457db96d56Sopenharmony_ci                {"mode": "wb", "buffering": 0},
41467db96d56Sopenharmony_ci                {"mode": "r"},
41477db96d56Sopenharmony_ci                {"mode": "rb"},
41487db96d56Sopenharmony_ci                {"mode": "rb", "buffering": 0},
41497db96d56Sopenharmony_ci                {"mode": "w+"},
41507db96d56Sopenharmony_ci                {"mode": "w+b"},
41517db96d56Sopenharmony_ci                {"mode": "w+b", "buffering": 0},
41527db96d56Sopenharmony_ci            ]:
41537db96d56Sopenharmony_ci            if "b" not in kwargs["mode"]:
41547db96d56Sopenharmony_ci                kwargs["encoding"] = "utf-8"
41557db96d56Sopenharmony_ci            for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
41567db96d56Sopenharmony_ci                with self.open(os_helper.TESTFN, **kwargs) as f:
41577db96d56Sopenharmony_ci                    self.assertRaises(TypeError, pickle.dumps, f, protocol)
41587db96d56Sopenharmony_ci
41597db96d56Sopenharmony_ci    @unittest.skipIf(
41607db96d56Sopenharmony_ci        support.is_emscripten, "fstat() of a pipe fd is not supported"
41617db96d56Sopenharmony_ci    )
41627db96d56Sopenharmony_ci    def test_nonblock_pipe_write_bigbuf(self):
41637db96d56Sopenharmony_ci        self._test_nonblock_pipe_write(16*1024)
41647db96d56Sopenharmony_ci
41657db96d56Sopenharmony_ci    @unittest.skipIf(
41667db96d56Sopenharmony_ci        support.is_emscripten, "fstat() of a pipe fd is not supported"
41677db96d56Sopenharmony_ci    )
41687db96d56Sopenharmony_ci    def test_nonblock_pipe_write_smallbuf(self):
41697db96d56Sopenharmony_ci        self._test_nonblock_pipe_write(1024)
41707db96d56Sopenharmony_ci
41717db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'set_blocking'),
41727db96d56Sopenharmony_ci                         'os.set_blocking() required for this test')
41737db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
41747db96d56Sopenharmony_ci    def _test_nonblock_pipe_write(self, bufsize):
41757db96d56Sopenharmony_ci        sent = []
41767db96d56Sopenharmony_ci        received = []
41777db96d56Sopenharmony_ci        r, w = os.pipe()
41787db96d56Sopenharmony_ci        os.set_blocking(r, False)
41797db96d56Sopenharmony_ci        os.set_blocking(w, False)
41807db96d56Sopenharmony_ci
41817db96d56Sopenharmony_ci        # To exercise all code paths in the C implementation we need
41827db96d56Sopenharmony_ci        # to play with buffer sizes.  For instance, if we choose a
41837db96d56Sopenharmony_ci        # buffer size less than or equal to _PIPE_BUF (4096 on Linux)
41847db96d56Sopenharmony_ci        # then we will never get a partial write of the buffer.
41857db96d56Sopenharmony_ci        rf = self.open(r, mode='rb', closefd=True, buffering=bufsize)
41867db96d56Sopenharmony_ci        wf = self.open(w, mode='wb', closefd=True, buffering=bufsize)
41877db96d56Sopenharmony_ci
41887db96d56Sopenharmony_ci        with rf, wf:
41897db96d56Sopenharmony_ci            for N in 9999, 73, 7574:
41907db96d56Sopenharmony_ci                try:
41917db96d56Sopenharmony_ci                    i = 0
41927db96d56Sopenharmony_ci                    while True:
41937db96d56Sopenharmony_ci                        msg = bytes([i % 26 + 97]) * N
41947db96d56Sopenharmony_ci                        sent.append(msg)
41957db96d56Sopenharmony_ci                        wf.write(msg)
41967db96d56Sopenharmony_ci                        i += 1
41977db96d56Sopenharmony_ci
41987db96d56Sopenharmony_ci                except self.BlockingIOError as e:
41997db96d56Sopenharmony_ci                    self.assertEqual(e.args[0], errno.EAGAIN)
42007db96d56Sopenharmony_ci                    self.assertEqual(e.args[2], e.characters_written)
42017db96d56Sopenharmony_ci                    sent[-1] = sent[-1][:e.characters_written]
42027db96d56Sopenharmony_ci                    received.append(rf.read())
42037db96d56Sopenharmony_ci                    msg = b'BLOCKED'
42047db96d56Sopenharmony_ci                    wf.write(msg)
42057db96d56Sopenharmony_ci                    sent.append(msg)
42067db96d56Sopenharmony_ci
42077db96d56Sopenharmony_ci            while True:
42087db96d56Sopenharmony_ci                try:
42097db96d56Sopenharmony_ci                    wf.flush()
42107db96d56Sopenharmony_ci                    break
42117db96d56Sopenharmony_ci                except self.BlockingIOError as e:
42127db96d56Sopenharmony_ci                    self.assertEqual(e.args[0], errno.EAGAIN)
42137db96d56Sopenharmony_ci                    self.assertEqual(e.args[2], e.characters_written)
42147db96d56Sopenharmony_ci                    self.assertEqual(e.characters_written, 0)
42157db96d56Sopenharmony_ci                    received.append(rf.read())
42167db96d56Sopenharmony_ci
42177db96d56Sopenharmony_ci            received += iter(rf.read, None)
42187db96d56Sopenharmony_ci
42197db96d56Sopenharmony_ci        sent, received = b''.join(sent), b''.join(received)
42207db96d56Sopenharmony_ci        self.assertEqual(sent, received)
42217db96d56Sopenharmony_ci        self.assertTrue(wf.closed)
42227db96d56Sopenharmony_ci        self.assertTrue(rf.closed)
42237db96d56Sopenharmony_ci
42247db96d56Sopenharmony_ci    def test_create_fail(self):
42257db96d56Sopenharmony_ci        # 'x' mode fails if file is existing
42267db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, 'w', encoding="utf-8"):
42277db96d56Sopenharmony_ci            pass
42287db96d56Sopenharmony_ci        self.assertRaises(FileExistsError, self.open, os_helper.TESTFN, 'x', encoding="utf-8")
42297db96d56Sopenharmony_ci
42307db96d56Sopenharmony_ci    def test_create_writes(self):
42317db96d56Sopenharmony_ci        # 'x' mode opens for writing
42327db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, 'xb') as f:
42337db96d56Sopenharmony_ci            f.write(b"spam")
42347db96d56Sopenharmony_ci        with self.open(os_helper.TESTFN, 'rb') as f:
42357db96d56Sopenharmony_ci            self.assertEqual(b"spam", f.read())
42367db96d56Sopenharmony_ci
42377db96d56Sopenharmony_ci    def test_open_allargs(self):
42387db96d56Sopenharmony_ci        # there used to be a buffer overflow in the parser for rawmode
42397db96d56Sopenharmony_ci        self.assertRaises(ValueError, self.open, os_helper.TESTFN, 'rwax+', encoding="utf-8")
42407db96d56Sopenharmony_ci
42417db96d56Sopenharmony_ci    def test_check_encoding_errors(self):
42427db96d56Sopenharmony_ci        # bpo-37388: open() and TextIOWrapper must check encoding and errors
42437db96d56Sopenharmony_ci        # arguments in dev mode
42447db96d56Sopenharmony_ci        mod = self.io.__name__
42457db96d56Sopenharmony_ci        filename = __file__
42467db96d56Sopenharmony_ci        invalid = 'Boom, Shaka Laka, Boom!'
42477db96d56Sopenharmony_ci        code = textwrap.dedent(f'''
42487db96d56Sopenharmony_ci            import sys
42497db96d56Sopenharmony_ci            from {mod} import open, TextIOWrapper
42507db96d56Sopenharmony_ci
42517db96d56Sopenharmony_ci            try:
42527db96d56Sopenharmony_ci                open({filename!r}, encoding={invalid!r})
42537db96d56Sopenharmony_ci            except LookupError:
42547db96d56Sopenharmony_ci                pass
42557db96d56Sopenharmony_ci            else:
42567db96d56Sopenharmony_ci                sys.exit(21)
42577db96d56Sopenharmony_ci
42587db96d56Sopenharmony_ci            try:
42597db96d56Sopenharmony_ci                open({filename!r}, errors={invalid!r})
42607db96d56Sopenharmony_ci            except LookupError:
42617db96d56Sopenharmony_ci                pass
42627db96d56Sopenharmony_ci            else:
42637db96d56Sopenharmony_ci                sys.exit(22)
42647db96d56Sopenharmony_ci
42657db96d56Sopenharmony_ci            fp = open({filename!r}, "rb")
42667db96d56Sopenharmony_ci            with fp:
42677db96d56Sopenharmony_ci                try:
42687db96d56Sopenharmony_ci                    TextIOWrapper(fp, encoding={invalid!r})
42697db96d56Sopenharmony_ci                except LookupError:
42707db96d56Sopenharmony_ci                    pass
42717db96d56Sopenharmony_ci                else:
42727db96d56Sopenharmony_ci                    sys.exit(23)
42737db96d56Sopenharmony_ci
42747db96d56Sopenharmony_ci                try:
42757db96d56Sopenharmony_ci                    TextIOWrapper(fp, errors={invalid!r})
42767db96d56Sopenharmony_ci                except LookupError:
42777db96d56Sopenharmony_ci                    pass
42787db96d56Sopenharmony_ci                else:
42797db96d56Sopenharmony_ci                    sys.exit(24)
42807db96d56Sopenharmony_ci
42817db96d56Sopenharmony_ci            sys.exit(10)
42827db96d56Sopenharmony_ci        ''')
42837db96d56Sopenharmony_ci        proc = assert_python_failure('-X', 'dev', '-c', code)
42847db96d56Sopenharmony_ci        self.assertEqual(proc.rc, 10, proc)
42857db96d56Sopenharmony_ci
42867db96d56Sopenharmony_ci    def test_check_encoding_warning(self):
42877db96d56Sopenharmony_ci        # PEP 597: Raise warning when encoding is not specified
42887db96d56Sopenharmony_ci        # and sys.flags.warn_default_encoding is set.
42897db96d56Sopenharmony_ci        mod = self.io.__name__
42907db96d56Sopenharmony_ci        filename = __file__
42917db96d56Sopenharmony_ci        code = textwrap.dedent(f'''\
42927db96d56Sopenharmony_ci            import sys
42937db96d56Sopenharmony_ci            from {mod} import open, TextIOWrapper
42947db96d56Sopenharmony_ci            import pathlib
42957db96d56Sopenharmony_ci
42967db96d56Sopenharmony_ci            with open({filename!r}) as f:           # line 5
42977db96d56Sopenharmony_ci                pass
42987db96d56Sopenharmony_ci
42997db96d56Sopenharmony_ci            pathlib.Path({filename!r}).read_text()  # line 8
43007db96d56Sopenharmony_ci        ''')
43017db96d56Sopenharmony_ci        proc = assert_python_ok('-X', 'warn_default_encoding', '-c', code)
43027db96d56Sopenharmony_ci        warnings = proc.err.splitlines()
43037db96d56Sopenharmony_ci        self.assertEqual(len(warnings), 2)
43047db96d56Sopenharmony_ci        self.assertTrue(
43057db96d56Sopenharmony_ci            warnings[0].startswith(b"<string>:5: EncodingWarning: "))
43067db96d56Sopenharmony_ci        self.assertTrue(
43077db96d56Sopenharmony_ci            warnings[1].startswith(b"<string>:8: EncodingWarning: "))
43087db96d56Sopenharmony_ci
43097db96d56Sopenharmony_ci    def test_text_encoding(self):
43107db96d56Sopenharmony_ci        # PEP 597, bpo-47000. io.text_encoding() returns "locale" or "utf-8"
43117db96d56Sopenharmony_ci        # based on sys.flags.utf8_mode
43127db96d56Sopenharmony_ci        code = "import io; print(io.text_encoding(None))"
43137db96d56Sopenharmony_ci
43147db96d56Sopenharmony_ci        proc = assert_python_ok('-X', 'utf8=0', '-c', code)
43157db96d56Sopenharmony_ci        self.assertEqual(b"locale", proc.out.strip())
43167db96d56Sopenharmony_ci
43177db96d56Sopenharmony_ci        proc = assert_python_ok('-X', 'utf8=1', '-c', code)
43187db96d56Sopenharmony_ci        self.assertEqual(b"utf-8", proc.out.strip())
43197db96d56Sopenharmony_ci
43207db96d56Sopenharmony_ci    @support.cpython_only
43217db96d56Sopenharmony_ci    # Depending if OpenWrapper was already created or not, the warning is
43227db96d56Sopenharmony_ci    # emitted or not. For example, the attribute is already created when this
43237db96d56Sopenharmony_ci    # test is run multiple times.
43247db96d56Sopenharmony_ci    @warnings_helper.ignore_warnings(category=DeprecationWarning)
43257db96d56Sopenharmony_ci    def test_openwrapper(self):
43267db96d56Sopenharmony_ci        self.assertIs(self.io.OpenWrapper, self.io.open)
43277db96d56Sopenharmony_ci
43287db96d56Sopenharmony_ci
43297db96d56Sopenharmony_ciclass CMiscIOTest(MiscIOTest):
43307db96d56Sopenharmony_ci    io = io
43317db96d56Sopenharmony_ci
43327db96d56Sopenharmony_ci    def test_readinto_buffer_overflow(self):
43337db96d56Sopenharmony_ci        # Issue #18025
43347db96d56Sopenharmony_ci        class BadReader(self.io.BufferedIOBase):
43357db96d56Sopenharmony_ci            def read(self, n=-1):
43367db96d56Sopenharmony_ci                return b'x' * 10**6
43377db96d56Sopenharmony_ci        bufio = BadReader()
43387db96d56Sopenharmony_ci        b = bytearray(2)
43397db96d56Sopenharmony_ci        self.assertRaises(ValueError, bufio.readinto, b)
43407db96d56Sopenharmony_ci
43417db96d56Sopenharmony_ci    def check_daemon_threads_shutdown_deadlock(self, stream_name):
43427db96d56Sopenharmony_ci        # Issue #23309: deadlocks at shutdown should be avoided when a
43437db96d56Sopenharmony_ci        # daemon thread and the main thread both write to a file.
43447db96d56Sopenharmony_ci        code = """if 1:
43457db96d56Sopenharmony_ci            import sys
43467db96d56Sopenharmony_ci            import time
43477db96d56Sopenharmony_ci            import threading
43487db96d56Sopenharmony_ci            from test.support import SuppressCrashReport
43497db96d56Sopenharmony_ci
43507db96d56Sopenharmony_ci            file = sys.{stream_name}
43517db96d56Sopenharmony_ci
43527db96d56Sopenharmony_ci            def run():
43537db96d56Sopenharmony_ci                while True:
43547db96d56Sopenharmony_ci                    file.write('.')
43557db96d56Sopenharmony_ci                    file.flush()
43567db96d56Sopenharmony_ci
43577db96d56Sopenharmony_ci            crash = SuppressCrashReport()
43587db96d56Sopenharmony_ci            crash.__enter__()
43597db96d56Sopenharmony_ci            # don't call __exit__(): the crash occurs at Python shutdown
43607db96d56Sopenharmony_ci
43617db96d56Sopenharmony_ci            thread = threading.Thread(target=run)
43627db96d56Sopenharmony_ci            thread.daemon = True
43637db96d56Sopenharmony_ci            thread.start()
43647db96d56Sopenharmony_ci
43657db96d56Sopenharmony_ci            time.sleep(0.5)
43667db96d56Sopenharmony_ci            file.write('!')
43677db96d56Sopenharmony_ci            file.flush()
43687db96d56Sopenharmony_ci            """.format_map(locals())
43697db96d56Sopenharmony_ci        res, _ = run_python_until_end("-c", code)
43707db96d56Sopenharmony_ci        err = res.err.decode()
43717db96d56Sopenharmony_ci        if res.rc != 0:
43727db96d56Sopenharmony_ci            # Failure: should be a fatal error
43737db96d56Sopenharmony_ci            pattern = (r"Fatal Python error: _enter_buffered_busy: "
43747db96d56Sopenharmony_ci                       r"could not acquire lock "
43757db96d56Sopenharmony_ci                       r"for <(_io\.)?BufferedWriter name='<{stream_name}>'> "
43767db96d56Sopenharmony_ci                       r"at interpreter shutdown, possibly due to "
43777db96d56Sopenharmony_ci                       r"daemon threads".format_map(locals()))
43787db96d56Sopenharmony_ci            self.assertRegex(err, pattern)
43797db96d56Sopenharmony_ci        else:
43807db96d56Sopenharmony_ci            self.assertFalse(err.strip('.!'))
43817db96d56Sopenharmony_ci
43827db96d56Sopenharmony_ci    @threading_helper.requires_working_threading()
43837db96d56Sopenharmony_ci    def test_daemon_threads_shutdown_stdout_deadlock(self):
43847db96d56Sopenharmony_ci        self.check_daemon_threads_shutdown_deadlock('stdout')
43857db96d56Sopenharmony_ci
43867db96d56Sopenharmony_ci    @threading_helper.requires_working_threading()
43877db96d56Sopenharmony_ci    def test_daemon_threads_shutdown_stderr_deadlock(self):
43887db96d56Sopenharmony_ci        self.check_daemon_threads_shutdown_deadlock('stderr')
43897db96d56Sopenharmony_ci
43907db96d56Sopenharmony_ci
43917db96d56Sopenharmony_ciclass PyMiscIOTest(MiscIOTest):
43927db96d56Sopenharmony_ci    io = pyio
43937db96d56Sopenharmony_ci
43947db96d56Sopenharmony_ci
43957db96d56Sopenharmony_ci@unittest.skipIf(os.name == 'nt', 'POSIX signals required for this test.')
43967db96d56Sopenharmony_ciclass SignalsTest(unittest.TestCase):
43977db96d56Sopenharmony_ci
43987db96d56Sopenharmony_ci    def setUp(self):
43997db96d56Sopenharmony_ci        self.oldalrm = signal.signal(signal.SIGALRM, self.alarm_interrupt)
44007db96d56Sopenharmony_ci
44017db96d56Sopenharmony_ci    def tearDown(self):
44027db96d56Sopenharmony_ci        signal.signal(signal.SIGALRM, self.oldalrm)
44037db96d56Sopenharmony_ci
44047db96d56Sopenharmony_ci    def alarm_interrupt(self, sig, frame):
44057db96d56Sopenharmony_ci        1/0
44067db96d56Sopenharmony_ci
44077db96d56Sopenharmony_ci    def check_interrupted_write(self, item, bytes, **fdopen_kwargs):
44087db96d56Sopenharmony_ci        """Check that a partial write, when it gets interrupted, properly
44097db96d56Sopenharmony_ci        invokes the signal handler, and bubbles up the exception raised
44107db96d56Sopenharmony_ci        in the latter."""
44117db96d56Sopenharmony_ci
44127db96d56Sopenharmony_ci        # XXX This test has three flaws that appear when objects are
44137db96d56Sopenharmony_ci        # XXX not reference counted.
44147db96d56Sopenharmony_ci
44157db96d56Sopenharmony_ci        # - if wio.write() happens to trigger a garbage collection,
44167db96d56Sopenharmony_ci        #   the signal exception may be raised when some __del__
44177db96d56Sopenharmony_ci        #   method is running; it will not reach the assertRaises()
44187db96d56Sopenharmony_ci        #   call.
44197db96d56Sopenharmony_ci
44207db96d56Sopenharmony_ci        # - more subtle, if the wio object is not destroyed at once
44217db96d56Sopenharmony_ci        #   and survives this function, the next opened file is likely
44227db96d56Sopenharmony_ci        #   to have the same fileno (since the file descriptor was
44237db96d56Sopenharmony_ci        #   actively closed).  When wio.__del__ is finally called, it
44247db96d56Sopenharmony_ci        #   will close the other's test file...  To trigger this with
44257db96d56Sopenharmony_ci        #   CPython, try adding "global wio" in this function.
44267db96d56Sopenharmony_ci
44277db96d56Sopenharmony_ci        # - This happens only for streams created by the _pyio module,
44287db96d56Sopenharmony_ci        #   because a wio.close() that fails still consider that the
44297db96d56Sopenharmony_ci        #   file needs to be closed again.  You can try adding an
44307db96d56Sopenharmony_ci        #   "assert wio.closed" at the end of the function.
44317db96d56Sopenharmony_ci
44327db96d56Sopenharmony_ci        # Fortunately, a little gc.collect() seems to be enough to
44337db96d56Sopenharmony_ci        # work around all these issues.
44347db96d56Sopenharmony_ci        support.gc_collect()  # For PyPy or other GCs.
44357db96d56Sopenharmony_ci
44367db96d56Sopenharmony_ci        read_results = []
44377db96d56Sopenharmony_ci        def _read():
44387db96d56Sopenharmony_ci            s = os.read(r, 1)
44397db96d56Sopenharmony_ci            read_results.append(s)
44407db96d56Sopenharmony_ci
44417db96d56Sopenharmony_ci        t = threading.Thread(target=_read)
44427db96d56Sopenharmony_ci        t.daemon = True
44437db96d56Sopenharmony_ci        r, w = os.pipe()
44447db96d56Sopenharmony_ci        fdopen_kwargs["closefd"] = False
44457db96d56Sopenharmony_ci        large_data = item * (support.PIPE_MAX_SIZE // len(item) + 1)
44467db96d56Sopenharmony_ci        try:
44477db96d56Sopenharmony_ci            wio = self.io.open(w, **fdopen_kwargs)
44487db96d56Sopenharmony_ci            if hasattr(signal, 'pthread_sigmask'):
44497db96d56Sopenharmony_ci                # create the thread with SIGALRM signal blocked
44507db96d56Sopenharmony_ci                signal.pthread_sigmask(signal.SIG_BLOCK, [signal.SIGALRM])
44517db96d56Sopenharmony_ci                t.start()
44527db96d56Sopenharmony_ci                signal.pthread_sigmask(signal.SIG_UNBLOCK, [signal.SIGALRM])
44537db96d56Sopenharmony_ci            else:
44547db96d56Sopenharmony_ci                t.start()
44557db96d56Sopenharmony_ci
44567db96d56Sopenharmony_ci            # Fill the pipe enough that the write will be blocking.
44577db96d56Sopenharmony_ci            # It will be interrupted by the timer armed above.  Since the
44587db96d56Sopenharmony_ci            # other thread has read one byte, the low-level write will
44597db96d56Sopenharmony_ci            # return with a successful (partial) result rather than an EINTR.
44607db96d56Sopenharmony_ci            # The buffered IO layer must check for pending signal
44617db96d56Sopenharmony_ci            # handlers, which in this case will invoke alarm_interrupt().
44627db96d56Sopenharmony_ci            signal.alarm(1)
44637db96d56Sopenharmony_ci            try:
44647db96d56Sopenharmony_ci                self.assertRaises(ZeroDivisionError, wio.write, large_data)
44657db96d56Sopenharmony_ci            finally:
44667db96d56Sopenharmony_ci                signal.alarm(0)
44677db96d56Sopenharmony_ci                t.join()
44687db96d56Sopenharmony_ci            # We got one byte, get another one and check that it isn't a
44697db96d56Sopenharmony_ci            # repeat of the first one.
44707db96d56Sopenharmony_ci            read_results.append(os.read(r, 1))
44717db96d56Sopenharmony_ci            self.assertEqual(read_results, [bytes[0:1], bytes[1:2]])
44727db96d56Sopenharmony_ci        finally:
44737db96d56Sopenharmony_ci            os.close(w)
44747db96d56Sopenharmony_ci            os.close(r)
44757db96d56Sopenharmony_ci            # This is deliberate. If we didn't close the file descriptor
44767db96d56Sopenharmony_ci            # before closing wio, wio would try to flush its internal
44777db96d56Sopenharmony_ci            # buffer, and block again.
44787db96d56Sopenharmony_ci            try:
44797db96d56Sopenharmony_ci                wio.close()
44807db96d56Sopenharmony_ci            except OSError as e:
44817db96d56Sopenharmony_ci                if e.errno != errno.EBADF:
44827db96d56Sopenharmony_ci                    raise
44837db96d56Sopenharmony_ci
44847db96d56Sopenharmony_ci    @requires_alarm
44857db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
44867db96d56Sopenharmony_ci    def test_interrupted_write_unbuffered(self):
44877db96d56Sopenharmony_ci        self.check_interrupted_write(b"xy", b"xy", mode="wb", buffering=0)
44887db96d56Sopenharmony_ci
44897db96d56Sopenharmony_ci    @requires_alarm
44907db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
44917db96d56Sopenharmony_ci    def test_interrupted_write_buffered(self):
44927db96d56Sopenharmony_ci        self.check_interrupted_write(b"xy", b"xy", mode="wb")
44937db96d56Sopenharmony_ci
44947db96d56Sopenharmony_ci    @requires_alarm
44957db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
44967db96d56Sopenharmony_ci    def test_interrupted_write_text(self):
44977db96d56Sopenharmony_ci        self.check_interrupted_write("xy", b"xy", mode="w", encoding="ascii")
44987db96d56Sopenharmony_ci
44997db96d56Sopenharmony_ci    @support.no_tracing
45007db96d56Sopenharmony_ci    def check_reentrant_write(self, data, **fdopen_kwargs):
45017db96d56Sopenharmony_ci        def on_alarm(*args):
45027db96d56Sopenharmony_ci            # Will be called reentrantly from the same thread
45037db96d56Sopenharmony_ci            wio.write(data)
45047db96d56Sopenharmony_ci            1/0
45057db96d56Sopenharmony_ci        signal.signal(signal.SIGALRM, on_alarm)
45067db96d56Sopenharmony_ci        r, w = os.pipe()
45077db96d56Sopenharmony_ci        wio = self.io.open(w, **fdopen_kwargs)
45087db96d56Sopenharmony_ci        try:
45097db96d56Sopenharmony_ci            signal.alarm(1)
45107db96d56Sopenharmony_ci            # Either the reentrant call to wio.write() fails with RuntimeError,
45117db96d56Sopenharmony_ci            # or the signal handler raises ZeroDivisionError.
45127db96d56Sopenharmony_ci            with self.assertRaises((ZeroDivisionError, RuntimeError)) as cm:
45137db96d56Sopenharmony_ci                while 1:
45147db96d56Sopenharmony_ci                    for i in range(100):
45157db96d56Sopenharmony_ci                        wio.write(data)
45167db96d56Sopenharmony_ci                        wio.flush()
45177db96d56Sopenharmony_ci                    # Make sure the buffer doesn't fill up and block further writes
45187db96d56Sopenharmony_ci                    os.read(r, len(data) * 100)
45197db96d56Sopenharmony_ci            exc = cm.exception
45207db96d56Sopenharmony_ci            if isinstance(exc, RuntimeError):
45217db96d56Sopenharmony_ci                self.assertTrue(str(exc).startswith("reentrant call"), str(exc))
45227db96d56Sopenharmony_ci        finally:
45237db96d56Sopenharmony_ci            signal.alarm(0)
45247db96d56Sopenharmony_ci            wio.close()
45257db96d56Sopenharmony_ci            os.close(r)
45267db96d56Sopenharmony_ci
45277db96d56Sopenharmony_ci    @requires_alarm
45287db96d56Sopenharmony_ci    def test_reentrant_write_buffered(self):
45297db96d56Sopenharmony_ci        self.check_reentrant_write(b"xy", mode="wb")
45307db96d56Sopenharmony_ci
45317db96d56Sopenharmony_ci    @requires_alarm
45327db96d56Sopenharmony_ci    def test_reentrant_write_text(self):
45337db96d56Sopenharmony_ci        self.check_reentrant_write("xy", mode="w", encoding="ascii")
45347db96d56Sopenharmony_ci
45357db96d56Sopenharmony_ci    def check_interrupted_read_retry(self, decode, **fdopen_kwargs):
45367db96d56Sopenharmony_ci        """Check that a buffered read, when it gets interrupted (either
45377db96d56Sopenharmony_ci        returning a partial result or EINTR), properly invokes the signal
45387db96d56Sopenharmony_ci        handler and retries if the latter returned successfully."""
45397db96d56Sopenharmony_ci        r, w = os.pipe()
45407db96d56Sopenharmony_ci        fdopen_kwargs["closefd"] = False
45417db96d56Sopenharmony_ci        def alarm_handler(sig, frame):
45427db96d56Sopenharmony_ci            os.write(w, b"bar")
45437db96d56Sopenharmony_ci        signal.signal(signal.SIGALRM, alarm_handler)
45447db96d56Sopenharmony_ci        try:
45457db96d56Sopenharmony_ci            rio = self.io.open(r, **fdopen_kwargs)
45467db96d56Sopenharmony_ci            os.write(w, b"foo")
45477db96d56Sopenharmony_ci            signal.alarm(1)
45487db96d56Sopenharmony_ci            # Expected behaviour:
45497db96d56Sopenharmony_ci            # - first raw read() returns partial b"foo"
45507db96d56Sopenharmony_ci            # - second raw read() returns EINTR
45517db96d56Sopenharmony_ci            # - third raw read() returns b"bar"
45527db96d56Sopenharmony_ci            self.assertEqual(decode(rio.read(6)), "foobar")
45537db96d56Sopenharmony_ci        finally:
45547db96d56Sopenharmony_ci            signal.alarm(0)
45557db96d56Sopenharmony_ci            rio.close()
45567db96d56Sopenharmony_ci            os.close(w)
45577db96d56Sopenharmony_ci            os.close(r)
45587db96d56Sopenharmony_ci
45597db96d56Sopenharmony_ci    @requires_alarm
45607db96d56Sopenharmony_ci    def test_interrupted_read_retry_buffered(self):
45617db96d56Sopenharmony_ci        self.check_interrupted_read_retry(lambda x: x.decode('latin1'),
45627db96d56Sopenharmony_ci                                          mode="rb")
45637db96d56Sopenharmony_ci
45647db96d56Sopenharmony_ci    @requires_alarm
45657db96d56Sopenharmony_ci    def test_interrupted_read_retry_text(self):
45667db96d56Sopenharmony_ci        self.check_interrupted_read_retry(lambda x: x,
45677db96d56Sopenharmony_ci                                          mode="r", encoding="latin1")
45687db96d56Sopenharmony_ci
45697db96d56Sopenharmony_ci    def check_interrupted_write_retry(self, item, **fdopen_kwargs):
45707db96d56Sopenharmony_ci        """Check that a buffered write, when it gets interrupted (either
45717db96d56Sopenharmony_ci        returning a partial result or EINTR), properly invokes the signal
45727db96d56Sopenharmony_ci        handler and retries if the latter returned successfully."""
45737db96d56Sopenharmony_ci        select = import_helper.import_module("select")
45747db96d56Sopenharmony_ci
45757db96d56Sopenharmony_ci        # A quantity that exceeds the buffer size of an anonymous pipe's
45767db96d56Sopenharmony_ci        # write end.
45777db96d56Sopenharmony_ci        N = support.PIPE_MAX_SIZE
45787db96d56Sopenharmony_ci        r, w = os.pipe()
45797db96d56Sopenharmony_ci        fdopen_kwargs["closefd"] = False
45807db96d56Sopenharmony_ci
45817db96d56Sopenharmony_ci        # We need a separate thread to read from the pipe and allow the
45827db96d56Sopenharmony_ci        # write() to finish.  This thread is started after the SIGALRM is
45837db96d56Sopenharmony_ci        # received (forcing a first EINTR in write()).
45847db96d56Sopenharmony_ci        read_results = []
45857db96d56Sopenharmony_ci        write_finished = False
45867db96d56Sopenharmony_ci        error = None
45877db96d56Sopenharmony_ci        def _read():
45887db96d56Sopenharmony_ci            try:
45897db96d56Sopenharmony_ci                while not write_finished:
45907db96d56Sopenharmony_ci                    while r in select.select([r], [], [], 1.0)[0]:
45917db96d56Sopenharmony_ci                        s = os.read(r, 1024)
45927db96d56Sopenharmony_ci                        read_results.append(s)
45937db96d56Sopenharmony_ci            except BaseException as exc:
45947db96d56Sopenharmony_ci                nonlocal error
45957db96d56Sopenharmony_ci                error = exc
45967db96d56Sopenharmony_ci        t = threading.Thread(target=_read)
45977db96d56Sopenharmony_ci        t.daemon = True
45987db96d56Sopenharmony_ci        def alarm1(sig, frame):
45997db96d56Sopenharmony_ci            signal.signal(signal.SIGALRM, alarm2)
46007db96d56Sopenharmony_ci            signal.alarm(1)
46017db96d56Sopenharmony_ci        def alarm2(sig, frame):
46027db96d56Sopenharmony_ci            t.start()
46037db96d56Sopenharmony_ci
46047db96d56Sopenharmony_ci        large_data = item * N
46057db96d56Sopenharmony_ci        signal.signal(signal.SIGALRM, alarm1)
46067db96d56Sopenharmony_ci        try:
46077db96d56Sopenharmony_ci            wio = self.io.open(w, **fdopen_kwargs)
46087db96d56Sopenharmony_ci            signal.alarm(1)
46097db96d56Sopenharmony_ci            # Expected behaviour:
46107db96d56Sopenharmony_ci            # - first raw write() is partial (because of the limited pipe buffer
46117db96d56Sopenharmony_ci            #   and the first alarm)
46127db96d56Sopenharmony_ci            # - second raw write() returns EINTR (because of the second alarm)
46137db96d56Sopenharmony_ci            # - subsequent write()s are successful (either partial or complete)
46147db96d56Sopenharmony_ci            written = wio.write(large_data)
46157db96d56Sopenharmony_ci            self.assertEqual(N, written)
46167db96d56Sopenharmony_ci
46177db96d56Sopenharmony_ci            wio.flush()
46187db96d56Sopenharmony_ci            write_finished = True
46197db96d56Sopenharmony_ci            t.join()
46207db96d56Sopenharmony_ci
46217db96d56Sopenharmony_ci            self.assertIsNone(error)
46227db96d56Sopenharmony_ci            self.assertEqual(N, sum(len(x) for x in read_results))
46237db96d56Sopenharmony_ci        finally:
46247db96d56Sopenharmony_ci            signal.alarm(0)
46257db96d56Sopenharmony_ci            write_finished = True
46267db96d56Sopenharmony_ci            os.close(w)
46277db96d56Sopenharmony_ci            os.close(r)
46287db96d56Sopenharmony_ci            # This is deliberate. If we didn't close the file descriptor
46297db96d56Sopenharmony_ci            # before closing wio, wio would try to flush its internal
46307db96d56Sopenharmony_ci            # buffer, and could block (in case of failure).
46317db96d56Sopenharmony_ci            try:
46327db96d56Sopenharmony_ci                wio.close()
46337db96d56Sopenharmony_ci            except OSError as e:
46347db96d56Sopenharmony_ci                if e.errno != errno.EBADF:
46357db96d56Sopenharmony_ci                    raise
46367db96d56Sopenharmony_ci
46377db96d56Sopenharmony_ci    @requires_alarm
46387db96d56Sopenharmony_ci    def test_interrupted_write_retry_buffered(self):
46397db96d56Sopenharmony_ci        self.check_interrupted_write_retry(b"x", mode="wb")
46407db96d56Sopenharmony_ci
46417db96d56Sopenharmony_ci    @requires_alarm
46427db96d56Sopenharmony_ci    def test_interrupted_write_retry_text(self):
46437db96d56Sopenharmony_ci        self.check_interrupted_write_retry("x", mode="w", encoding="latin1")
46447db96d56Sopenharmony_ci
46457db96d56Sopenharmony_ci
46467db96d56Sopenharmony_ciclass CSignalsTest(SignalsTest):
46477db96d56Sopenharmony_ci    io = io
46487db96d56Sopenharmony_ci
46497db96d56Sopenharmony_ciclass PySignalsTest(SignalsTest):
46507db96d56Sopenharmony_ci    io = pyio
46517db96d56Sopenharmony_ci
46527db96d56Sopenharmony_ci    # Handling reentrancy issues would slow down _pyio even more, so the
46537db96d56Sopenharmony_ci    # tests are disabled.
46547db96d56Sopenharmony_ci    test_reentrant_write_buffered = None
46557db96d56Sopenharmony_ci    test_reentrant_write_text = None
46567db96d56Sopenharmony_ci
46577db96d56Sopenharmony_ci
46587db96d56Sopenharmony_cidef load_tests(loader, tests, pattern):
46597db96d56Sopenharmony_ci    tests = (CIOTest, PyIOTest, APIMismatchTest,
46607db96d56Sopenharmony_ci             CBufferedReaderTest, PyBufferedReaderTest,
46617db96d56Sopenharmony_ci             CBufferedWriterTest, PyBufferedWriterTest,
46627db96d56Sopenharmony_ci             CBufferedRWPairTest, PyBufferedRWPairTest,
46637db96d56Sopenharmony_ci             CBufferedRandomTest, PyBufferedRandomTest,
46647db96d56Sopenharmony_ci             StatefulIncrementalDecoderTest,
46657db96d56Sopenharmony_ci             CIncrementalNewlineDecoderTest, PyIncrementalNewlineDecoderTest,
46667db96d56Sopenharmony_ci             CTextIOWrapperTest, PyTextIOWrapperTest,
46677db96d56Sopenharmony_ci             CMiscIOTest, PyMiscIOTest,
46687db96d56Sopenharmony_ci             CSignalsTest, PySignalsTest,
46697db96d56Sopenharmony_ci             )
46707db96d56Sopenharmony_ci
46717db96d56Sopenharmony_ci    # Put the namespaces of the IO module we are testing and some useful mock
46727db96d56Sopenharmony_ci    # classes in the __dict__ of each test.
46737db96d56Sopenharmony_ci    mocks = (MockRawIO, MisbehavedRawIO, MockFileIO, CloseFailureIO,
46747db96d56Sopenharmony_ci             MockNonBlockWriterIO, MockUnseekableIO, MockRawIOWithoutRead,
46757db96d56Sopenharmony_ci             SlowFlushRawIO)
46767db96d56Sopenharmony_ci    all_members = io.__all__ + ["IncrementalNewlineDecoder"]
46777db96d56Sopenharmony_ci    c_io_ns = {name : getattr(io, name) for name in all_members}
46787db96d56Sopenharmony_ci    py_io_ns = {name : getattr(pyio, name) for name in all_members}
46797db96d56Sopenharmony_ci    globs = globals()
46807db96d56Sopenharmony_ci    c_io_ns.update((x.__name__, globs["C" + x.__name__]) for x in mocks)
46817db96d56Sopenharmony_ci    py_io_ns.update((x.__name__, globs["Py" + x.__name__]) for x in mocks)
46827db96d56Sopenharmony_ci    for test in tests:
46837db96d56Sopenharmony_ci        if test.__name__.startswith("C"):
46847db96d56Sopenharmony_ci            for name, obj in c_io_ns.items():
46857db96d56Sopenharmony_ci                setattr(test, name, obj)
46867db96d56Sopenharmony_ci        elif test.__name__.startswith("Py"):
46877db96d56Sopenharmony_ci            for name, obj in py_io_ns.items():
46887db96d56Sopenharmony_ci                setattr(test, name, obj)
46897db96d56Sopenharmony_ci
46907db96d56Sopenharmony_ci    suite = loader.suiteClass()
46917db96d56Sopenharmony_ci    for test in tests:
46927db96d56Sopenharmony_ci        suite.addTest(loader.loadTestsFromTestCase(test))
46937db96d56Sopenharmony_ci    return suite
46947db96d56Sopenharmony_ci
46957db96d56Sopenharmony_ciif __name__ == "__main__":
46967db96d56Sopenharmony_ci    unittest.main()
4697