test_StringIO.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. # Tests StringIO and cStringIO
  2. import unittest
  3. import StringIO
  4. import cStringIO
  5. import types
  6. import array
  7. import sys
  8. from test import test_support
  9. class TestGenericStringIO(unittest.TestCase):
  10. # use a class variable MODULE to define which module is being tested
  11. # Line of data to test as string
  12. _line = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!'
  13. # Constructor to use for the test data (._line is passed to this
  14. # constructor)
  15. constructor = str
  16. def setUp(self):
  17. self._lines = self.constructor((self._line + '\n') * 5)
  18. self._fp = self.MODULE.StringIO(self._lines)
  19. def test_reads(self):
  20. eq = self.assertEqual
  21. self.assertRaises(TypeError, self._fp.seek)
  22. eq(self._fp.read(10), self._line[:10])
  23. eq(self._fp.read(0), '')
  24. eq(self._fp.readline(0), '')
  25. eq(self._fp.readline(), self._line[10:] + '\n')
  26. eq(len(self._fp.readlines(60)), 2)
  27. self._fp.seek(0)
  28. eq(self._fp.readline(-1), self._line + '\n')
  29. def test_writes(self):
  30. f = self.MODULE.StringIO()
  31. self.assertRaises(TypeError, f.seek)
  32. f.write(self._line[:6])
  33. f.seek(3)
  34. f.write(self._line[20:26])
  35. f.write(self._line[52])
  36. self.assertEqual(f.getvalue(), 'abcuvwxyz!')
  37. def test_writelines(self):
  38. f = self.MODULE.StringIO()
  39. f.writelines([self._line[0], self._line[1], self._line[2]])
  40. f.seek(0)
  41. self.assertEqual(f.getvalue(), 'abc')
  42. def test_writelines_error(self):
  43. def errorGen():
  44. yield 'a'
  45. raise KeyboardInterrupt()
  46. f = self.MODULE.StringIO()
  47. self.assertRaises(KeyboardInterrupt, f.writelines, errorGen())
  48. def test_truncate(self):
  49. eq = self.assertEqual
  50. f = self.MODULE.StringIO()
  51. f.write(self._lines)
  52. f.seek(10)
  53. f.truncate()
  54. eq(f.getvalue(), 'abcdefghij')
  55. f.truncate(5)
  56. eq(f.getvalue(), 'abcde')
  57. f.write('xyz')
  58. eq(f.getvalue(), 'abcdexyz')
  59. self.assertRaises(IOError, f.truncate, -1)
  60. f.close()
  61. self.assertRaises(ValueError, f.write, 'frobnitz')
  62. def test_closed_flag(self):
  63. f = self.MODULE.StringIO()
  64. self.assertEqual(f.closed, False)
  65. f.close()
  66. self.assertEqual(f.closed, True)
  67. f = self.MODULE.StringIO("abc")
  68. self.assertEqual(f.closed, False)
  69. f.close()
  70. self.assertEqual(f.closed, True)
  71. def test_isatty(self):
  72. f = self.MODULE.StringIO()
  73. self.assertRaises(TypeError, f.isatty, None)
  74. self.assertEqual(f.isatty(), False)
  75. f.close()
  76. self.assertRaises(ValueError, f.isatty)
  77. def test_iterator(self):
  78. eq = self.assertEqual
  79. unless = self.assertTrue
  80. eq(iter(self._fp), self._fp)
  81. # Does this object support the iteration protocol?
  82. unless(hasattr(self._fp, '__iter__'))
  83. unless(hasattr(self._fp, 'next'))
  84. i = 0
  85. for line in self._fp:
  86. eq(line, self._line + '\n')
  87. i += 1
  88. eq(i, 5)
  89. self._fp.close()
  90. self.assertRaises(ValueError, self._fp.next)
  91. def test_getvalue(self):
  92. self._fp.close()
  93. self.assertRaises(ValueError, self._fp.getvalue)
  94. @test_support.bigmemtest(test_support._2G + 2**26, memuse=2.001)
  95. def test_reads_from_large_stream(self, size):
  96. linesize = 2**26 # 64 MiB
  97. lines = ['x' * (linesize - 1) + '\n'] * (size // linesize) + \
  98. ['y' * (size % linesize)]
  99. f = self.MODULE.StringIO(''.join(lines))
  100. for i, expected in enumerate(lines):
  101. line = f.read(len(expected))
  102. self.assertEqual(len(line), len(expected))
  103. self.assertEqual(line, expected)
  104. self.assertEqual(f.read(), '')
  105. f.seek(0)
  106. for i, expected in enumerate(lines):
  107. line = f.readline()
  108. self.assertEqual(len(line), len(expected))
  109. self.assertEqual(line, expected)
  110. self.assertEqual(f.readline(), '')
  111. f.seek(0)
  112. self.assertEqual(f.readlines(), lines)
  113. self.assertEqual(f.readlines(), [])
  114. f.seek(0)
  115. self.assertEqual(f.readlines(size), lines)
  116. self.assertEqual(f.readlines(), [])
  117. # In worst case cStringIO requires 2 + 1 + 1/2 + 1/2**2 + ... = 4
  118. # bytes per input character.
  119. @test_support.bigmemtest(test_support._2G, memuse=4)
  120. def test_writes_to_large_stream(self, size):
  121. s = 'x' * 2**26 # 64 MiB
  122. f = self.MODULE.StringIO()
  123. n = size
  124. while n > len(s):
  125. f.write(s)
  126. n -= len(s)
  127. s = None
  128. f.write('x' * n)
  129. self.assertEqual(len(f.getvalue()), size)
  130. class TestStringIO(TestGenericStringIO):
  131. MODULE = StringIO
  132. def test_unicode(self):
  133. if not test_support.have_unicode: return
  134. # The StringIO module also supports concatenating Unicode
  135. # snippets to larger Unicode strings. This is tested by this
  136. # method. Note that cStringIO does not support this extension.
  137. f = self.MODULE.StringIO()
  138. f.write(self._line[:6])
  139. f.seek(3)
  140. f.write(unicode(self._line[20:26]))
  141. f.write(unicode(self._line[52]))
  142. s = f.getvalue()
  143. self.assertEqual(s, unicode('abcuvwxyz!'))
  144. self.assertEqual(type(s), types.UnicodeType)
  145. class TestcStringIO(TestGenericStringIO):
  146. MODULE = cStringIO
  147. def test_array_support(self):
  148. # Issue #1730114: cStringIO should accept array objects
  149. a = array.array('B', [0,1,2])
  150. f = self.MODULE.StringIO(a)
  151. self.assertEqual(f.getvalue(), '\x00\x01\x02')
  152. def test_unicode(self):
  153. if not test_support.have_unicode: return
  154. # The cStringIO module converts Unicode strings to character
  155. # strings when writing them to cStringIO objects.
  156. # Check that this works.
  157. f = self.MODULE.StringIO()
  158. f.write(u'abcde')
  159. s = f.getvalue()
  160. self.assertEqual(s, 'abcde')
  161. self.assertEqual(type(s), str)
  162. f = self.MODULE.StringIO(u'abcde')
  163. s = f.getvalue()
  164. self.assertEqual(s, 'abcde')
  165. self.assertEqual(type(s), str)
  166. self.assertRaises(UnicodeEncodeError, self.MODULE.StringIO, u'\xf4')
  167. import sys
  168. if sys.platform.startswith('java'):
  169. # Jython doesn't have a buffer object, so we just do a useless
  170. # fake of the buffer tests.
  171. buffer = str
  172. class TestBufferStringIO(TestStringIO):
  173. constructor = buffer
  174. class TestBuffercStringIO(TestcStringIO):
  175. constructor = buffer
  176. class TestMemoryviewcStringIO(TestcStringIO):
  177. constructor = memoryview
  178. def test_main():
  179. test_support.run_unittest(TestStringIO, TestcStringIO)
  180. with test_support.check_py3k_warnings(("buffer.. not supported",
  181. DeprecationWarning)):
  182. test_support.run_unittest(TestBufferStringIO, TestBuffercStringIO)
  183. test_support.run_unittest(TestMemoryviewcStringIO)
  184. if __name__ == '__main__':
  185. test_main()