(root)/
Python-3.11.7/
Lib/
test/
test_memoryio.py
       1  """Unit tests for memory-based file-like objects.
       2  StringIO -- for unicode strings
       3  BytesIO -- for bytes
       4  """
       5  
       6  import unittest
       7  from test import support
       8  
       9  import io
      10  import _pyio as pyio
      11  import pickle
      12  import sys
      13  
      14  class ESC[4;38;5;81mIntLike:
      15      def __init__(self, num):
      16          self._num = num
      17      def __index__(self):
      18          return self._num
      19      __int__ = __index__
      20  
      21  class ESC[4;38;5;81mMemorySeekTestMixin:
      22  
      23      def testInit(self):
      24          buf = self.buftype("1234567890")
      25          bytesIo = self.ioclass(buf)
      26  
      27      def testRead(self):
      28          buf = self.buftype("1234567890")
      29          bytesIo = self.ioclass(buf)
      30  
      31          self.assertEqual(buf[:1], bytesIo.read(1))
      32          self.assertEqual(buf[1:5], bytesIo.read(4))
      33          self.assertEqual(buf[5:], bytesIo.read(900))
      34          self.assertEqual(self.EOF, bytesIo.read())
      35  
      36      def testReadNoArgs(self):
      37          buf = self.buftype("1234567890")
      38          bytesIo = self.ioclass(buf)
      39  
      40          self.assertEqual(buf, bytesIo.read())
      41          self.assertEqual(self.EOF, bytesIo.read())
      42  
      43      def testSeek(self):
      44          buf = self.buftype("1234567890")
      45          bytesIo = self.ioclass(buf)
      46  
      47          bytesIo.read(5)
      48          bytesIo.seek(0)
      49          self.assertEqual(buf, bytesIo.read())
      50  
      51          bytesIo.seek(3)
      52          self.assertEqual(buf[3:], bytesIo.read())
      53          self.assertRaises(TypeError, bytesIo.seek, 0.0)
      54  
      55      def testTell(self):
      56          buf = self.buftype("1234567890")
      57          bytesIo = self.ioclass(buf)
      58  
      59          self.assertEqual(0, bytesIo.tell())
      60          bytesIo.seek(5)
      61          self.assertEqual(5, bytesIo.tell())
      62          bytesIo.seek(10000)
      63          self.assertEqual(10000, bytesIo.tell())
      64  
      65  
      66  class ESC[4;38;5;81mMemoryTestMixin:
      67  
      68      def test_detach(self):
      69          buf = self.ioclass()
      70          self.assertRaises(self.UnsupportedOperation, buf.detach)
      71  
      72      def write_ops(self, f, t):
      73          self.assertEqual(f.write(t("blah.")), 5)
      74          self.assertEqual(f.seek(0), 0)
      75          self.assertEqual(f.write(t("Hello.")), 6)
      76          self.assertEqual(f.tell(), 6)
      77          self.assertEqual(f.seek(5), 5)
      78          self.assertEqual(f.tell(), 5)
      79          self.assertEqual(f.write(t(" world\n\n\n")), 9)
      80          self.assertEqual(f.seek(0), 0)
      81          self.assertEqual(f.write(t("h")), 1)
      82          self.assertEqual(f.truncate(12), 12)
      83          self.assertEqual(f.tell(), 1)
      84  
      85      def test_write(self):
      86          buf = self.buftype("hello world\n")
      87          memio = self.ioclass(buf)
      88  
      89          self.write_ops(memio, self.buftype)
      90          self.assertEqual(memio.getvalue(), buf)
      91          memio = self.ioclass()
      92          self.write_ops(memio, self.buftype)
      93          self.assertEqual(memio.getvalue(), buf)
      94          self.assertRaises(TypeError, memio.write, None)
      95          memio.close()
      96          self.assertRaises(ValueError, memio.write, self.buftype(""))
      97  
      98      def test_writelines(self):
      99          buf = self.buftype("1234567890")
     100          memio = self.ioclass()
     101  
     102          self.assertEqual(memio.writelines([buf] * 100), None)
     103          self.assertEqual(memio.getvalue(), buf * 100)
     104          memio.writelines([])
     105          self.assertEqual(memio.getvalue(), buf * 100)
     106          memio = self.ioclass()
     107          self.assertRaises(TypeError, memio.writelines, [buf] + [1])
     108          self.assertEqual(memio.getvalue(), buf)
     109          self.assertRaises(TypeError, memio.writelines, None)
     110          memio.close()
     111          self.assertRaises(ValueError, memio.writelines, [])
     112  
     113      def test_writelines_error(self):
     114          memio = self.ioclass()
     115          def error_gen():
     116              yield self.buftype('spam')
     117              raise KeyboardInterrupt
     118  
     119          self.assertRaises(KeyboardInterrupt, memio.writelines, error_gen())
     120  
     121      def test_truncate(self):
     122          buf = self.buftype("1234567890")
     123          memio = self.ioclass(buf)
     124  
     125          self.assertRaises(ValueError, memio.truncate, -1)
     126          self.assertRaises(ValueError, memio.truncate, IntLike(-1))
     127          memio.seek(6)
     128          self.assertEqual(memio.truncate(IntLike(8)), 8)
     129          self.assertEqual(memio.getvalue(), buf[:8])
     130          self.assertEqual(memio.truncate(), 6)
     131          self.assertEqual(memio.getvalue(), buf[:6])
     132          self.assertEqual(memio.truncate(4), 4)
     133          self.assertEqual(memio.getvalue(), buf[:4])
     134          self.assertEqual(memio.tell(), 6)
     135          memio.seek(0, 2)
     136          memio.write(buf)
     137          self.assertEqual(memio.getvalue(), buf[:4] + buf)
     138          pos = memio.tell()
     139          self.assertEqual(memio.truncate(None), pos)
     140          self.assertEqual(memio.tell(), pos)
     141          self.assertRaises(TypeError, memio.truncate, '0')
     142          memio.close()
     143          self.assertRaises(ValueError, memio.truncate, 0)
     144          self.assertRaises(ValueError, memio.truncate, IntLike(0))
     145  
     146      def test_init(self):
     147          buf = self.buftype("1234567890")
     148          memio = self.ioclass(buf)
     149          self.assertEqual(memio.getvalue(), buf)
     150          memio = self.ioclass(None)
     151          self.assertEqual(memio.getvalue(), self.EOF)
     152          memio.__init__(buf * 2)
     153          self.assertEqual(memio.getvalue(), buf * 2)
     154          memio.__init__(buf)
     155          self.assertEqual(memio.getvalue(), buf)
     156          self.assertRaises(TypeError, memio.__init__, [])
     157  
     158      def test_read(self):
     159          buf = self.buftype("1234567890")
     160          memio = self.ioclass(buf)
     161  
     162          self.assertEqual(memio.read(0), self.EOF)
     163          self.assertEqual(memio.read(1), buf[:1])
     164          self.assertEqual(memio.read(4), buf[1:5])
     165          self.assertEqual(memio.read(900), buf[5:])
     166          self.assertEqual(memio.read(), self.EOF)
     167          memio.seek(0)
     168          self.assertEqual(memio.read(IntLike(0)), self.EOF)
     169          self.assertEqual(memio.read(IntLike(1)), buf[:1])
     170          self.assertEqual(memio.read(IntLike(4)), buf[1:5])
     171          self.assertEqual(memio.read(IntLike(900)), buf[5:])
     172          memio.seek(0)
     173          self.assertEqual(memio.read(), buf)
     174          self.assertEqual(memio.read(), self.EOF)
     175          self.assertEqual(memio.tell(), 10)
     176          memio.seek(0)
     177          self.assertEqual(memio.read(-1), buf)
     178          memio.seek(0)
     179          self.assertEqual(memio.read(IntLike(-1)), buf)
     180          memio.seek(0)
     181          self.assertEqual(type(memio.read()), type(buf))
     182          memio.seek(100)
     183          self.assertEqual(type(memio.read()), type(buf))
     184          memio.seek(0)
     185          self.assertEqual(memio.read(None), buf)
     186          self.assertRaises(TypeError, memio.read, '')
     187          memio.seek(len(buf) + 1)
     188          self.assertEqual(memio.read(1), self.EOF)
     189          memio.seek(len(buf) + 1)
     190          self.assertEqual(memio.read(IntLike(1)), self.EOF)
     191          memio.seek(len(buf) + 1)
     192          self.assertEqual(memio.read(), self.EOF)
     193          memio.close()
     194          self.assertRaises(ValueError, memio.read)
     195  
     196      def test_readline(self):
     197          buf = self.buftype("1234567890\n")
     198          memio = self.ioclass(buf * 2)
     199  
     200          self.assertEqual(memio.readline(0), self.EOF)
     201          self.assertEqual(memio.readline(IntLike(0)), self.EOF)
     202          self.assertEqual(memio.readline(), buf)
     203          self.assertEqual(memio.readline(), buf)
     204          self.assertEqual(memio.readline(), self.EOF)
     205          memio.seek(0)
     206          self.assertEqual(memio.readline(5), buf[:5])
     207          self.assertEqual(memio.readline(5), buf[5:10])
     208          self.assertEqual(memio.readline(5), buf[10:15])
     209          memio.seek(0)
     210          self.assertEqual(memio.readline(IntLike(5)), buf[:5])
     211          self.assertEqual(memio.readline(IntLike(5)), buf[5:10])
     212          self.assertEqual(memio.readline(IntLike(5)), buf[10:15])
     213          memio.seek(0)
     214          self.assertEqual(memio.readline(-1), buf)
     215          memio.seek(0)
     216          self.assertEqual(memio.readline(IntLike(-1)), buf)
     217          memio.seek(0)
     218          self.assertEqual(memio.readline(0), self.EOF)
     219          self.assertEqual(memio.readline(IntLike(0)), self.EOF)
     220          # Issue #24989: Buffer overread
     221          memio.seek(len(buf) * 2 + 1)
     222          self.assertEqual(memio.readline(), self.EOF)
     223  
     224          buf = self.buftype("1234567890\n")
     225          memio = self.ioclass((buf * 3)[:-1])
     226          self.assertEqual(memio.readline(), buf)
     227          self.assertEqual(memio.readline(), buf)
     228          self.assertEqual(memio.readline(), buf[:-1])
     229          self.assertEqual(memio.readline(), self.EOF)
     230          memio.seek(0)
     231          self.assertEqual(type(memio.readline()), type(buf))
     232          self.assertEqual(memio.readline(), buf)
     233          self.assertRaises(TypeError, memio.readline, '')
     234          memio.close()
     235          self.assertRaises(ValueError,  memio.readline)
     236  
     237      def test_readlines(self):
     238          buf = self.buftype("1234567890\n")
     239          memio = self.ioclass(buf * 10)
     240  
     241          self.assertEqual(memio.readlines(), [buf] * 10)
     242          memio.seek(5)
     243          self.assertEqual(memio.readlines(), [buf[5:]] + [buf] * 9)
     244          memio.seek(0)
     245          self.assertEqual(memio.readlines(15), [buf] * 2)
     246          memio.seek(0)
     247          self.assertEqual(memio.readlines(-1), [buf] * 10)
     248          memio.seek(0)
     249          self.assertEqual(memio.readlines(0), [buf] * 10)
     250          memio.seek(0)
     251          self.assertEqual(type(memio.readlines()[0]), type(buf))
     252          memio.seek(0)
     253          self.assertEqual(memio.readlines(None), [buf] * 10)
     254          self.assertRaises(TypeError, memio.readlines, '')
     255          # Issue #24989: Buffer overread
     256          memio.seek(len(buf) * 10 + 1)
     257          self.assertEqual(memio.readlines(), [])
     258          memio.close()
     259          self.assertRaises(ValueError, memio.readlines)
     260  
     261      def test_iterator(self):
     262          buf = self.buftype("1234567890\n")
     263          memio = self.ioclass(buf * 10)
     264  
     265          self.assertEqual(iter(memio), memio)
     266          self.assertTrue(hasattr(memio, '__iter__'))
     267          self.assertTrue(hasattr(memio, '__next__'))
     268          i = 0
     269          for line in memio:
     270              self.assertEqual(line, buf)
     271              i += 1
     272          self.assertEqual(i, 10)
     273          memio.seek(0)
     274          i = 0
     275          for line in memio:
     276              self.assertEqual(line, buf)
     277              i += 1
     278          self.assertEqual(i, 10)
     279          # Issue #24989: Buffer overread
     280          memio.seek(len(buf) * 10 + 1)
     281          self.assertEqual(list(memio), [])
     282          memio = self.ioclass(buf * 2)
     283          memio.close()
     284          self.assertRaises(ValueError, memio.__next__)
     285  
     286      def test_getvalue(self):
     287          buf = self.buftype("1234567890")
     288          memio = self.ioclass(buf)
     289  
     290          self.assertEqual(memio.getvalue(), buf)
     291          memio.read()
     292          self.assertEqual(memio.getvalue(), buf)
     293          self.assertEqual(type(memio.getvalue()), type(buf))
     294          memio = self.ioclass(buf * 1000)
     295          self.assertEqual(memio.getvalue()[-3:], self.buftype("890"))
     296          memio = self.ioclass(buf)
     297          memio.close()
     298          self.assertRaises(ValueError, memio.getvalue)
     299  
     300      def test_seek(self):
     301          buf = self.buftype("1234567890")
     302          memio = self.ioclass(buf)
     303  
     304          memio.read(5)
     305          self.assertRaises(ValueError, memio.seek, -1)
     306          self.assertRaises(ValueError, memio.seek, 1, -1)
     307          self.assertRaises(ValueError, memio.seek, 1, 3)
     308          self.assertEqual(memio.seek(0), 0)
     309          self.assertEqual(memio.seek(0, 0), 0)
     310          self.assertEqual(memio.read(), buf)
     311          self.assertEqual(memio.seek(3), 3)
     312          self.assertEqual(memio.seek(0, 1), 3)
     313          self.assertEqual(memio.read(), buf[3:])
     314          self.assertEqual(memio.seek(len(buf)), len(buf))
     315          self.assertEqual(memio.read(), self.EOF)
     316          memio.seek(len(buf) + 1)
     317          self.assertEqual(memio.read(), self.EOF)
     318          self.assertEqual(memio.seek(0, 2), len(buf))
     319          self.assertEqual(memio.read(), self.EOF)
     320          memio.close()
     321          self.assertRaises(ValueError, memio.seek, 0)
     322  
     323      def test_overseek(self):
     324          buf = self.buftype("1234567890")
     325          memio = self.ioclass(buf)
     326  
     327          self.assertEqual(memio.seek(len(buf) + 1), 11)
     328          self.assertEqual(memio.read(), self.EOF)
     329          self.assertEqual(memio.tell(), 11)
     330          self.assertEqual(memio.getvalue(), buf)
     331          memio.write(self.EOF)
     332          self.assertEqual(memio.getvalue(), buf)
     333          memio.write(buf)
     334          self.assertEqual(memio.getvalue(), buf + self.buftype('\0') + buf)
     335  
     336      def test_tell(self):
     337          buf = self.buftype("1234567890")
     338          memio = self.ioclass(buf)
     339  
     340          self.assertEqual(memio.tell(), 0)
     341          memio.seek(5)
     342          self.assertEqual(memio.tell(), 5)
     343          memio.seek(10000)
     344          self.assertEqual(memio.tell(), 10000)
     345          memio.close()
     346          self.assertRaises(ValueError, memio.tell)
     347  
     348      def test_flush(self):
     349          buf = self.buftype("1234567890")
     350          memio = self.ioclass(buf)
     351  
     352          self.assertEqual(memio.flush(), None)
     353  
     354      def test_flags(self):
     355          memio = self.ioclass()
     356  
     357          self.assertEqual(memio.writable(), True)
     358          self.assertEqual(memio.readable(), True)
     359          self.assertEqual(memio.seekable(), True)
     360          self.assertEqual(memio.isatty(), False)
     361          self.assertEqual(memio.closed, False)
     362          memio.close()
     363          self.assertRaises(ValueError, memio.writable)
     364          self.assertRaises(ValueError, memio.readable)
     365          self.assertRaises(ValueError, memio.seekable)
     366          self.assertRaises(ValueError, memio.isatty)
     367          self.assertEqual(memio.closed, True)
     368  
     369      def test_subclassing(self):
     370          buf = self.buftype("1234567890")
     371          def test1():
     372              class ESC[4;38;5;81mMemIO(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149mioclass):
     373                  pass
     374              m = MemIO(buf)
     375              return m.getvalue()
     376          def test2():
     377              class ESC[4;38;5;81mMemIO(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149mioclass):
     378                  def __init__(me, a, b):
     379                      self.ioclass.__init__(me, a)
     380              m = MemIO(buf, None)
     381              return m.getvalue()
     382          self.assertEqual(test1(), buf)
     383          self.assertEqual(test2(), buf)
     384  
     385      def test_instance_dict_leak(self):
     386          # Test case for issue #6242.
     387          # This will be caught by regrtest.py -R if this leak.
     388          for _ in range(100):
     389              memio = self.ioclass()
     390              memio.foo = 1
     391  
     392      def test_pickling(self):
     393          buf = self.buftype("1234567890")
     394          memio = self.ioclass(buf)
     395          memio.foo = 42
     396          memio.seek(2)
     397  
     398          class ESC[4;38;5;81mPickleTestMemIO(ESC[4;38;5;149mselfESC[4;38;5;149m.ESC[4;38;5;149mioclass):
     399              def __init__(me, initvalue, foo):
     400                  self.ioclass.__init__(me, initvalue)
     401                  me.foo = foo
     402              # __getnewargs__ is undefined on purpose. This checks that PEP 307
     403              # is used to provide pickling support.
     404  
     405          # Pickle expects the class to be on the module level. Here we use a
     406          # little hack to allow the PickleTestMemIO class to derive from
     407          # self.ioclass without having to define all combinations explicitly on
     408          # the module-level.
     409          import __main__
     410          PickleTestMemIO.__module__ = '__main__'
     411          PickleTestMemIO.__qualname__ = PickleTestMemIO.__name__
     412          __main__.PickleTestMemIO = PickleTestMemIO
     413          submemio = PickleTestMemIO(buf, 80)
     414          submemio.seek(2)
     415  
     416          # We only support pickle protocol 2 and onward since we use extended
     417          # __reduce__ API of PEP 307 to provide pickling support.
     418          for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
     419              for obj in (memio, submemio):
     420                  obj2 = pickle.loads(pickle.dumps(obj, protocol=proto))
     421                  self.assertEqual(obj.getvalue(), obj2.getvalue())
     422                  self.assertEqual(obj.__class__, obj2.__class__)
     423                  self.assertEqual(obj.foo, obj2.foo)
     424                  self.assertEqual(obj.tell(), obj2.tell())
     425                  obj2.close()
     426                  self.assertRaises(ValueError, pickle.dumps, obj2, proto)
     427          del __main__.PickleTestMemIO
     428  
     429  
     430  class ESC[4;38;5;81mPyBytesIOTest(ESC[4;38;5;149mMemoryTestMixin, ESC[4;38;5;149mMemorySeekTestMixin, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     431      # Test _pyio.BytesIO; class also inherited for testing C implementation
     432  
     433      UnsupportedOperation = pyio.UnsupportedOperation
     434  
     435      @staticmethod
     436      def buftype(s):
     437          return s.encode("ascii")
     438      ioclass = pyio.BytesIO
     439      EOF = b""
     440  
     441      def test_getbuffer(self):
     442          memio = self.ioclass(b"1234567890")
     443          buf = memio.getbuffer()
     444          self.assertEqual(bytes(buf), b"1234567890")
     445          memio.seek(5)
     446          buf = memio.getbuffer()
     447          self.assertEqual(bytes(buf), b"1234567890")
     448          # Trying to change the size of the BytesIO while a buffer is exported
     449          # raises a BufferError.
     450          self.assertRaises(BufferError, memio.write, b'x' * 100)
     451          self.assertRaises(BufferError, memio.truncate)
     452          self.assertRaises(BufferError, memio.close)
     453          self.assertFalse(memio.closed)
     454          # Mutating the buffer updates the BytesIO
     455          buf[3:6] = b"abc"
     456          self.assertEqual(bytes(buf), b"123abc7890")
     457          self.assertEqual(memio.getvalue(), b"123abc7890")
     458          # After the buffer gets released, we can resize and close the BytesIO
     459          # again
     460          del buf
     461          support.gc_collect()
     462          memio.truncate()
     463          memio.close()
     464          self.assertRaises(ValueError, memio.getbuffer)
     465  
     466      def test_getbuffer_empty(self):
     467          memio = self.ioclass()
     468          buf = memio.getbuffer()
     469          self.assertEqual(bytes(buf), b"")
     470          # Trying to change the size of the BytesIO while a buffer is exported
     471          # raises a BufferError.
     472          self.assertRaises(BufferError, memio.write, b'x')
     473          buf2 = memio.getbuffer()
     474          self.assertRaises(BufferError, memio.write, b'x')
     475          buf.release()
     476          self.assertRaises(BufferError, memio.write, b'x')
     477          buf2.release()
     478          memio.write(b'x')
     479  
     480      def test_read1(self):
     481          buf = self.buftype("1234567890")
     482          self.assertEqual(self.ioclass(buf).read1(), buf)
     483          self.assertEqual(self.ioclass(buf).read1(-1), buf)
     484  
     485      def test_readinto(self):
     486          buf = self.buftype("1234567890")
     487          memio = self.ioclass(buf)
     488  
     489          b = bytearray(b"hello")
     490          self.assertEqual(memio.readinto(b), 5)
     491          self.assertEqual(b, b"12345")
     492          self.assertEqual(memio.readinto(b), 5)
     493          self.assertEqual(b, b"67890")
     494          self.assertEqual(memio.readinto(b), 0)
     495          self.assertEqual(b, b"67890")
     496          b = bytearray(b"hello world")
     497          memio.seek(0)
     498          self.assertEqual(memio.readinto(b), 10)
     499          self.assertEqual(b, b"1234567890d")
     500          b = bytearray(b"")
     501          memio.seek(0)
     502          self.assertEqual(memio.readinto(b), 0)
     503          self.assertEqual(b, b"")
     504          self.assertRaises(TypeError, memio.readinto, '')
     505          import array
     506          a = array.array('b', b"hello world")
     507          memio = self.ioclass(buf)
     508          memio.readinto(a)
     509          self.assertEqual(a.tobytes(), b"1234567890d")
     510          memio.close()
     511          self.assertRaises(ValueError, memio.readinto, b)
     512          memio = self.ioclass(b"123")
     513          b = bytearray()
     514          memio.seek(42)
     515          memio.readinto(b)
     516          self.assertEqual(b, b"")
     517  
     518      def test_relative_seek(self):
     519          buf = self.buftype("1234567890")
     520          memio = self.ioclass(buf)
     521  
     522          self.assertEqual(memio.seek(-1, 1), 0)
     523          self.assertEqual(memio.seek(3, 1), 3)
     524          self.assertEqual(memio.seek(-4, 1), 0)
     525          self.assertEqual(memio.seek(-1, 2), 9)
     526          self.assertEqual(memio.seek(1, 1), 10)
     527          self.assertEqual(memio.seek(1, 2), 11)
     528          memio.seek(-3, 2)
     529          self.assertEqual(memio.read(), buf[-3:])
     530          memio.seek(0)
     531          memio.seek(1, 1)
     532          self.assertEqual(memio.read(), buf[1:])
     533  
     534      def test_unicode(self):
     535          memio = self.ioclass()
     536  
     537          self.assertRaises(TypeError, self.ioclass, "1234567890")
     538          self.assertRaises(TypeError, memio.write, "1234567890")
     539          self.assertRaises(TypeError, memio.writelines, ["1234567890"])
     540  
     541      def test_bytes_array(self):
     542          buf = b"1234567890"
     543          import array
     544          a = array.array('b', list(buf))
     545          memio = self.ioclass(a)
     546          self.assertEqual(memio.getvalue(), buf)
     547          self.assertEqual(memio.write(a), 10)
     548          self.assertEqual(memio.getvalue(), buf)
     549  
     550      def test_issue5449(self):
     551          buf = self.buftype("1234567890")
     552          self.ioclass(initial_bytes=buf)
     553          self.assertRaises(TypeError, self.ioclass, buf, foo=None)
     554  
     555  
     556  class ESC[4;38;5;81mTextIOTestMixin:
     557  
     558      def test_newlines_property(self):
     559          memio = self.ioclass(newline=None)
     560          # The C StringIO decodes newlines in write() calls, but the Python
     561          # implementation only does when reading.  This function forces them to
     562          # be decoded for testing.
     563          def force_decode():
     564              memio.seek(0)
     565              memio.read()
     566          self.assertEqual(memio.newlines, None)
     567          memio.write("a\n")
     568          force_decode()
     569          self.assertEqual(memio.newlines, "\n")
     570          memio.write("b\r\n")
     571          force_decode()
     572          self.assertEqual(memio.newlines, ("\n", "\r\n"))
     573          memio.write("c\rd")
     574          force_decode()
     575          self.assertEqual(memio.newlines, ("\r", "\n", "\r\n"))
     576  
     577      def test_relative_seek(self):
     578          memio = self.ioclass()
     579  
     580          self.assertRaises(OSError, memio.seek, -1, 1)
     581          self.assertRaises(OSError, memio.seek, 3, 1)
     582          self.assertRaises(OSError, memio.seek, -3, 1)
     583          self.assertRaises(OSError, memio.seek, -1, 2)
     584          self.assertRaises(OSError, memio.seek, 1, 1)
     585          self.assertRaises(OSError, memio.seek, 1, 2)
     586  
     587      def test_textio_properties(self):
     588          memio = self.ioclass()
     589  
     590          # These are just dummy values but we nevertheless check them for fear
     591          # of unexpected breakage.
     592          self.assertIsNone(memio.encoding)
     593          self.assertIsNone(memio.errors)
     594          self.assertFalse(memio.line_buffering)
     595  
     596      def test_newline_default(self):
     597          memio = self.ioclass("a\nb\r\nc\rd")
     598          self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
     599          self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
     600  
     601          memio = self.ioclass()
     602          self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
     603          memio.seek(0)
     604          self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
     605          self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
     606  
     607      def test_newline_none(self):
     608          # newline=None
     609          memio = self.ioclass("a\nb\r\nc\rd", newline=None)
     610          self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"])
     611          memio.seek(0)
     612          self.assertEqual(memio.read(1), "a")
     613          self.assertEqual(memio.read(2), "\nb")
     614          self.assertEqual(memio.read(2), "\nc")
     615          self.assertEqual(memio.read(1), "\n")
     616          self.assertEqual(memio.getvalue(), "a\nb\nc\nd")
     617  
     618          memio = self.ioclass(newline=None)
     619          self.assertEqual(2, memio.write("a\n"))
     620          self.assertEqual(3, memio.write("b\r\n"))
     621          self.assertEqual(3, memio.write("c\rd"))
     622          memio.seek(0)
     623          self.assertEqual(memio.read(), "a\nb\nc\nd")
     624          self.assertEqual(memio.getvalue(), "a\nb\nc\nd")
     625  
     626          memio = self.ioclass("a\r\nb", newline=None)
     627          self.assertEqual(memio.read(3), "a\nb")
     628  
     629      def test_newline_empty(self):
     630          # newline=""
     631          memio = self.ioclass("a\nb\r\nc\rd", newline="")
     632          self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
     633          memio.seek(0)
     634          self.assertEqual(memio.read(4), "a\nb\r")
     635          self.assertEqual(memio.read(2), "\nc")
     636          self.assertEqual(memio.read(1), "\r")
     637          self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
     638  
     639          memio = self.ioclass(newline="")
     640          self.assertEqual(2, memio.write("a\n"))
     641          self.assertEqual(2, memio.write("b\r"))
     642          self.assertEqual(2, memio.write("\nc"))
     643          self.assertEqual(2, memio.write("\rd"))
     644          memio.seek(0)
     645          self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"])
     646          self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
     647  
     648      def test_newline_lf(self):
     649          # newline="\n"
     650          memio = self.ioclass("a\nb\r\nc\rd", newline="\n")
     651          self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
     652          self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
     653  
     654          memio = self.ioclass(newline="\n")
     655          self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
     656          memio.seek(0)
     657          self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"])
     658          self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd")
     659  
     660      def test_newline_cr(self):
     661          # newline="\r"
     662          memio = self.ioclass("a\nb\r\nc\rd", newline="\r")
     663          self.assertEqual(memio.read(), "a\rb\r\rc\rd")
     664          memio.seek(0)
     665          self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
     666          self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd")
     667  
     668          memio = self.ioclass(newline="\r")
     669          self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
     670          memio.seek(0)
     671          self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"])
     672          memio.seek(0)
     673          self.assertEqual(memio.readlines(), ["a\r", "b\r", "\r", "c\r", "d"])
     674          self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd")
     675  
     676      def test_newline_crlf(self):
     677          # newline="\r\n"
     678          memio = self.ioclass("a\nb\r\nc\rd", newline="\r\n")
     679          self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd")
     680          memio.seek(0)
     681          self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
     682          memio.seek(0)
     683          self.assertEqual(memio.readlines(), ["a\r\n", "b\r\r\n", "c\rd"])
     684          self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd")
     685  
     686          memio = self.ioclass(newline="\r\n")
     687          self.assertEqual(memio.write("a\nb\r\nc\rd"), 8)
     688          memio.seek(0)
     689          self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"])
     690          self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd")
     691  
     692      def test_issue5265(self):
     693          # StringIO can duplicate newlines in universal newlines mode
     694          memio = self.ioclass("a\r\nb\r\n", newline=None)
     695          self.assertEqual(memio.read(5), "a\nb\n")
     696          self.assertEqual(memio.getvalue(), "a\nb\n")
     697  
     698      def test_newline_argument(self):
     699          self.assertRaises(TypeError, self.ioclass, newline=b"\n")
     700          self.assertRaises(ValueError, self.ioclass, newline="error")
     701          # These should not raise an error
     702          for newline in (None, "", "\n", "\r", "\r\n"):
     703              self.ioclass(newline=newline)
     704  
     705  
     706  class ESC[4;38;5;81mPyStringIOTest(ESC[4;38;5;149mMemoryTestMixin, ESC[4;38;5;149mMemorySeekTestMixin,
     707                       ESC[4;38;5;149mTextIOTestMixin, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     708      buftype = str
     709      ioclass = pyio.StringIO
     710      UnsupportedOperation = pyio.UnsupportedOperation
     711      EOF = ""
     712  
     713      def test_lone_surrogates(self):
     714          # Issue #20424
     715          memio = self.ioclass('\ud800')
     716          self.assertEqual(memio.read(), '\ud800')
     717  
     718          memio = self.ioclass()
     719          memio.write('\ud800')
     720          self.assertEqual(memio.getvalue(), '\ud800')
     721  
     722  
     723  class ESC[4;38;5;81mPyStringIOPickleTest(ESC[4;38;5;149mTextIOTestMixin, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     724      """Test if pickle restores properly the internal state of StringIO.
     725      """
     726      buftype = str
     727      UnsupportedOperation = pyio.UnsupportedOperation
     728      EOF = ""
     729  
     730      class ESC[4;38;5;81mioclass(ESC[4;38;5;149mpyioESC[4;38;5;149m.ESC[4;38;5;149mStringIO):
     731          def __new__(cls, *args, **kwargs):
     732              return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs)))
     733          def __init__(self, *args, **kwargs):
     734              pass
     735  
     736  
     737  class ESC[4;38;5;81mCBytesIOTest(ESC[4;38;5;149mPyBytesIOTest):
     738      ioclass = io.BytesIO
     739      UnsupportedOperation = io.UnsupportedOperation
     740  
     741      def test_getstate(self):
     742          memio = self.ioclass()
     743          state = memio.__getstate__()
     744          self.assertEqual(len(state), 3)
     745          bytearray(state[0]) # Check if state[0] supports the buffer interface.
     746          self.assertIsInstance(state[1], int)
     747          if state[2] is not None:
     748              self.assertIsInstance(state[2], dict)
     749          memio.close()
     750          self.assertRaises(ValueError, memio.__getstate__)
     751  
     752      def test_setstate(self):
     753          # This checks whether __setstate__ does proper input validation.
     754          memio = self.ioclass()
     755          memio.__setstate__((b"no error", 0, None))
     756          memio.__setstate__((bytearray(b"no error"), 0, None))
     757          memio.__setstate__((b"no error", 0, {'spam': 3}))
     758          self.assertRaises(ValueError, memio.__setstate__, (b"", -1, None))
     759          self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None))
     760          self.assertRaises(TypeError, memio.__setstate__, (b"", 0.0, None))
     761          self.assertRaises(TypeError, memio.__setstate__, (b"", 0, 0))
     762          self.assertRaises(TypeError, memio.__setstate__, (b"len-test", 0))
     763          self.assertRaises(TypeError, memio.__setstate__)
     764          self.assertRaises(TypeError, memio.__setstate__, 0)
     765          memio.close()
     766          self.assertRaises(ValueError, memio.__setstate__, (b"closed", 0, None))
     767  
     768      check_sizeof = support.check_sizeof
     769  
     770      @support.cpython_only
     771      def test_sizeof(self):
     772          basesize = support.calcobjsize('P2n2Pn')
     773          check = self.check_sizeof
     774          self.assertEqual(object.__sizeof__(io.BytesIO()), basesize)
     775          check(io.BytesIO(), basesize )
     776          n = 1000  # use a variable to prevent constant folding
     777          check(io.BytesIO(b'a' * n), basesize + sys.getsizeof(b'a' * n))
     778  
     779      # Various tests of copy-on-write behaviour for BytesIO.
     780  
     781      def _test_cow_mutation(self, mutation):
     782          # Common code for all BytesIO copy-on-write mutation tests.
     783          imm = b' ' * 1024
     784          old_rc = sys.getrefcount(imm)
     785          memio = self.ioclass(imm)
     786          self.assertEqual(sys.getrefcount(imm), old_rc + 1)
     787          mutation(memio)
     788          self.assertEqual(sys.getrefcount(imm), old_rc)
     789  
     790      @support.cpython_only
     791      def test_cow_truncate(self):
     792          # Ensure truncate causes a copy.
     793          def mutation(memio):
     794              memio.truncate(1)
     795          self._test_cow_mutation(mutation)
     796  
     797      @support.cpython_only
     798      def test_cow_write(self):
     799          # Ensure write that would not cause a resize still results in a copy.
     800          def mutation(memio):
     801              memio.seek(0)
     802              memio.write(b'foo')
     803          self._test_cow_mutation(mutation)
     804  
     805      @support.cpython_only
     806      def test_cow_setstate(self):
     807          # __setstate__ should cause buffer to be released.
     808          memio = self.ioclass(b'foooooo')
     809          state = memio.__getstate__()
     810          def mutation(memio):
     811              memio.__setstate__(state)
     812          self._test_cow_mutation(mutation)
     813  
     814      @support.cpython_only
     815      def test_cow_mutable(self):
     816          # BytesIO should accept only Bytes for copy-on-write sharing, since
     817          # arbitrary buffer-exporting objects like bytearray() aren't guaranteed
     818          # to be immutable.
     819          ba = bytearray(1024)
     820          old_rc = sys.getrefcount(ba)
     821          memio = self.ioclass(ba)
     822          self.assertEqual(sys.getrefcount(ba), old_rc)
     823  
     824  class ESC[4;38;5;81mCStringIOTest(ESC[4;38;5;149mPyStringIOTest):
     825      ioclass = io.StringIO
     826      UnsupportedOperation = io.UnsupportedOperation
     827  
     828      # XXX: For the Python version of io.StringIO, this is highly
     829      # dependent on the encoding used for the underlying buffer.
     830      def test_widechar(self):
     831          buf = self.buftype("\U0002030a\U00020347")
     832          memio = self.ioclass(buf)
     833  
     834          self.assertEqual(memio.getvalue(), buf)
     835          self.assertEqual(memio.write(buf), len(buf))
     836          self.assertEqual(memio.tell(), len(buf))
     837          self.assertEqual(memio.getvalue(), buf)
     838          self.assertEqual(memio.write(buf), len(buf))
     839          self.assertEqual(memio.tell(), len(buf) * 2)
     840          self.assertEqual(memio.getvalue(), buf + buf)
     841  
     842      def test_getstate(self):
     843          memio = self.ioclass()
     844          state = memio.__getstate__()
     845          self.assertEqual(len(state), 4)
     846          self.assertIsInstance(state[0], str)
     847          self.assertIsInstance(state[1], str)
     848          self.assertIsInstance(state[2], int)
     849          if state[3] is not None:
     850              self.assertIsInstance(state[3], dict)
     851          memio.close()
     852          self.assertRaises(ValueError, memio.__getstate__)
     853  
     854      def test_setstate(self):
     855          # This checks whether __setstate__ does proper input validation.
     856          memio = self.ioclass()
     857          memio.__setstate__(("no error", "\n", 0, None))
     858          memio.__setstate__(("no error", "", 0, {'spam': 3}))
     859          self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None))
     860          self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None))
     861          self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None))
     862          self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None))
     863          self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None))
     864          self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0))
     865          self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0))
     866          self.assertRaises(TypeError, memio.__setstate__)
     867          self.assertRaises(TypeError, memio.__setstate__, 0)
     868          memio.close()
     869          self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None))
     870  
     871  
     872  class ESC[4;38;5;81mCStringIOPickleTest(ESC[4;38;5;149mPyStringIOPickleTest):
     873      UnsupportedOperation = io.UnsupportedOperation
     874  
     875      class ESC[4;38;5;81mioclass(ESC[4;38;5;149mioESC[4;38;5;149m.ESC[4;38;5;149mStringIO):
     876          def __new__(cls, *args, **kwargs):
     877              return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs)))
     878          def __init__(self, *args, **kwargs):
     879              pass
     880  
     881  
     882  if __name__ == '__main__':
     883      unittest.main()