/External.LCA_RESTRICTED/Languages/CPython/27/Lib/test/test_io.py

http://github.com/IronLanguages/main · Python · 2782 lines · 2269 code · 317 blank · 196 comment · 207 complexity · 8639be738ac6943e6cc6b971842110ff MD5 · raw file

Large files are truncated click here to view the full file

  1. """Unit tests for the io module."""
  2. # Tests of io are scattered over the test suite:
  3. # * test_bufio - tests file buffering
  4. # * test_memoryio - tests BytesIO and StringIO
  5. # * test_fileio - tests FileIO
  6. # * test_file - tests the file interface
  7. # * test_io - tests everything else in the io module
  8. # * test_univnewlines - tests universal newline support
  9. # * test_largefile - tests operations on a file greater than 2**32 bytes
  10. # (only enabled with -ulargefile)
  11. ################################################################################
  12. # ATTENTION TEST WRITERS!!!
  13. ################################################################################
  14. # When writing tests for io, it's important to test both the C and Python
  15. # implementations. This is usually done by writing a base test that refers to
  16. # the type it is testing as a attribute. Then it provides custom subclasses to
  17. # test both implementations. This file has lots of examples.
  18. ################################################################################
  19. from __future__ import print_function
  20. from __future__ import unicode_literals
  21. import os
  22. import sys
  23. import time
  24. import array
  25. import random
  26. import unittest
  27. import weakref
  28. import abc
  29. import signal
  30. import errno
  31. from itertools import cycle, count
  32. from collections import deque
  33. from test import test_support as support
  34. import codecs
  35. import io # C implementation of io
  36. import _pyio as pyio # Python implementation of io
  37. try:
  38. import threading
  39. except ImportError:
  40. threading = None
  41. __metaclass__ = type
  42. bytes = support.py3k_bytes
  43. def _default_chunk_size():
  44. """Get the default TextIOWrapper chunk size"""
  45. with io.open(__file__, "r", encoding="latin1") as f:
  46. return f._CHUNK_SIZE
  47. class MockRawIOWithoutRead:
  48. """A RawIO implementation without read(), so as to exercise the default
  49. RawIO.read() which calls readinto()."""
  50. def __init__(self, read_stack=()):
  51. self._read_stack = list(read_stack)
  52. self._write_stack = []
  53. self._reads = 0
  54. self._extraneous_reads = 0
  55. def write(self, b):
  56. self._write_stack.append(bytes(b))
  57. return len(b)
  58. def writable(self):
  59. return True
  60. def fileno(self):
  61. return 42
  62. def readable(self):
  63. return True
  64. def seekable(self):
  65. return True
  66. def seek(self, pos, whence):
  67. return 0 # wrong but we gotta return something
  68. def tell(self):
  69. return 0 # same comment as above
  70. def readinto(self, buf):
  71. self._reads += 1
  72. max_len = len(buf)
  73. try:
  74. data = self._read_stack[0]
  75. except IndexError:
  76. self._extraneous_reads += 1
  77. return 0
  78. if data is None:
  79. del self._read_stack[0]
  80. return None
  81. n = len(data)
  82. if len(data) <= max_len:
  83. del self._read_stack[0]
  84. buf[:n] = data
  85. return n
  86. else:
  87. buf[:] = data[:max_len]
  88. self._read_stack[0] = data[max_len:]
  89. return max_len
  90. def truncate(self, pos=None):
  91. return pos
  92. class CMockRawIOWithoutRead(MockRawIOWithoutRead, io.RawIOBase):
  93. pass
  94. class PyMockRawIOWithoutRead(MockRawIOWithoutRead, pyio.RawIOBase):
  95. pass
  96. class MockRawIO(MockRawIOWithoutRead):
  97. def read(self, n=None):
  98. self._reads += 1
  99. try:
  100. return self._read_stack.pop(0)
  101. except:
  102. self._extraneous_reads += 1
  103. return b""
  104. class CMockRawIO(MockRawIO, io.RawIOBase):
  105. pass
  106. class PyMockRawIO(MockRawIO, pyio.RawIOBase):
  107. pass
  108. class MisbehavedRawIO(MockRawIO):
  109. def write(self, b):
  110. return MockRawIO.write(self, b) * 2
  111. def read(self, n=None):
  112. return MockRawIO.read(self, n) * 2
  113. def seek(self, pos, whence):
  114. return -123
  115. def tell(self):
  116. return -456
  117. def readinto(self, buf):
  118. MockRawIO.readinto(self, buf)
  119. return len(buf) * 5
  120. class CMisbehavedRawIO(MisbehavedRawIO, io.RawIOBase):
  121. pass
  122. class PyMisbehavedRawIO(MisbehavedRawIO, pyio.RawIOBase):
  123. pass
  124. class CloseFailureIO(MockRawIO):
  125. closed = 0
  126. def close(self):
  127. if not self.closed:
  128. self.closed = 1
  129. raise IOError
  130. class CCloseFailureIO(CloseFailureIO, io.RawIOBase):
  131. pass
  132. class PyCloseFailureIO(CloseFailureIO, pyio.RawIOBase):
  133. pass
  134. class MockFileIO:
  135. def __init__(self, data):
  136. self.read_history = []
  137. super(MockFileIO, self).__init__(data)
  138. def read(self, n=None):
  139. res = super(MockFileIO, self).read(n)
  140. self.read_history.append(None if res is None else len(res))
  141. return res
  142. def readinto(self, b):
  143. res = super(MockFileIO, self).readinto(b)
  144. self.read_history.append(res)
  145. return res
  146. class CMockFileIO(MockFileIO, io.BytesIO):
  147. pass
  148. class PyMockFileIO(MockFileIO, pyio.BytesIO):
  149. pass
  150. class MockNonBlockWriterIO:
  151. def __init__(self):
  152. self._write_stack = []
  153. self._blocker_char = None
  154. def pop_written(self):
  155. s = b"".join(self._write_stack)
  156. self._write_stack[:] = []
  157. return s
  158. def block_on(self, char):
  159. """Block when a given char is encountered."""
  160. self._blocker_char = char
  161. def readable(self):
  162. return True
  163. def seekable(self):
  164. return True
  165. def writable(self):
  166. return True
  167. def write(self, b):
  168. b = bytes(b)
  169. n = -1
  170. if self._blocker_char:
  171. try:
  172. n = b.index(self._blocker_char)
  173. except ValueError:
  174. pass
  175. else:
  176. self._blocker_char = None
  177. self._write_stack.append(b[:n])
  178. raise self.BlockingIOError(0, "test blocking", n)
  179. self._write_stack.append(b)
  180. return len(b)
  181. class CMockNonBlockWriterIO(MockNonBlockWriterIO, io.RawIOBase):
  182. BlockingIOError = io.BlockingIOError
  183. class PyMockNonBlockWriterIO(MockNonBlockWriterIO, pyio.RawIOBase):
  184. BlockingIOError = pyio.BlockingIOError
  185. class IOTest(unittest.TestCase):
  186. def setUp(self):
  187. support.unlink(support.TESTFN)
  188. def tearDown(self):
  189. support.unlink(support.TESTFN)
  190. def write_ops(self, f):
  191. self.assertEqual(f.write(b"blah."), 5)
  192. f.truncate(0)
  193. self.assertEqual(f.tell(), 5)
  194. f.seek(0)
  195. self.assertEqual(f.write(b"blah."), 5)
  196. self.assertEqual(f.seek(0), 0)
  197. self.assertEqual(f.write(b"Hello."), 6)
  198. self.assertEqual(f.tell(), 6)
  199. self.assertEqual(f.seek(-1, 1), 5)
  200. self.assertEqual(f.tell(), 5)
  201. self.assertEqual(f.write(bytearray(b" world\n\n\n")), 9)
  202. self.assertEqual(f.seek(0), 0)
  203. self.assertEqual(f.write(b"h"), 1)
  204. self.assertEqual(f.seek(-1, 2), 13)
  205. self.assertEqual(f.tell(), 13)
  206. self.assertEqual(f.truncate(12), 12)
  207. self.assertEqual(f.tell(), 13)
  208. self.assertRaises(TypeError, f.seek, 0.0)
  209. def read_ops(self, f, buffered=False):
  210. data = f.read(5)
  211. self.assertEqual(data, b"hello")
  212. data = bytearray(data)
  213. self.assertEqual(f.readinto(data), 5)
  214. self.assertEqual(data, b" worl")
  215. self.assertEqual(f.readinto(data), 2)
  216. self.assertEqual(len(data), 5)
  217. self.assertEqual(data[:2], b"d\n")
  218. self.assertEqual(f.seek(0), 0)
  219. self.assertEqual(f.read(20), b"hello world\n")
  220. self.assertEqual(f.read(1), b"")
  221. self.assertEqual(f.readinto(bytearray(b"x")), 0)
  222. self.assertEqual(f.seek(-6, 2), 6)
  223. self.assertEqual(f.read(5), b"world")
  224. self.assertEqual(f.read(0), b"")
  225. self.assertEqual(f.readinto(bytearray()), 0)
  226. self.assertEqual(f.seek(-6, 1), 5)
  227. self.assertEqual(f.read(5), b" worl")
  228. self.assertEqual(f.tell(), 10)
  229. self.assertRaises(TypeError, f.seek, 0.0)
  230. if buffered:
  231. f.seek(0)
  232. self.assertEqual(f.read(), b"hello world\n")
  233. f.seek(6)
  234. self.assertEqual(f.read(), b"world\n")
  235. self.assertEqual(f.read(), b"")
  236. LARGE = 2**31
  237. def large_file_ops(self, f):
  238. assert f.readable()
  239. assert f.writable()
  240. self.assertEqual(f.seek(self.LARGE), self.LARGE)
  241. self.assertEqual(f.tell(), self.LARGE)
  242. self.assertEqual(f.write(b"xxx"), 3)
  243. self.assertEqual(f.tell(), self.LARGE + 3)
  244. self.assertEqual(f.seek(-1, 1), self.LARGE + 2)
  245. self.assertEqual(f.truncate(), self.LARGE + 2)
  246. self.assertEqual(f.tell(), self.LARGE + 2)
  247. self.assertEqual(f.seek(0, 2), self.LARGE + 2)
  248. self.assertEqual(f.truncate(self.LARGE + 1), self.LARGE + 1)
  249. self.assertEqual(f.tell(), self.LARGE + 2)
  250. self.assertEqual(f.seek(0, 2), self.LARGE + 1)
  251. self.assertEqual(f.seek(-1, 2), self.LARGE)
  252. self.assertEqual(f.read(2), b"x")
  253. def test_invalid_operations(self):
  254. # Try writing on a file opened in read mode and vice-versa.
  255. for mode in ("w", "wb"):
  256. with self.open(support.TESTFN, mode) as fp:
  257. self.assertRaises(IOError, fp.read)
  258. self.assertRaises(IOError, fp.readline)
  259. with self.open(support.TESTFN, "rb") as fp:
  260. self.assertRaises(IOError, fp.write, b"blah")
  261. self.assertRaises(IOError, fp.writelines, [b"blah\n"])
  262. with self.open(support.TESTFN, "r") as fp:
  263. self.assertRaises(IOError, fp.write, "blah")
  264. self.assertRaises(IOError, fp.writelines, ["blah\n"])
  265. def test_raw_file_io(self):
  266. with self.open(support.TESTFN, "wb", buffering=0) as f:
  267. self.assertEqual(f.readable(), False)
  268. self.assertEqual(f.writable(), True)
  269. self.assertEqual(f.seekable(), True)
  270. self.write_ops(f)
  271. with self.open(support.TESTFN, "rb", buffering=0) as f:
  272. self.assertEqual(f.readable(), True)
  273. self.assertEqual(f.writable(), False)
  274. self.assertEqual(f.seekable(), True)
  275. self.read_ops(f)
  276. def test_buffered_file_io(self):
  277. with self.open(support.TESTFN, "wb") as f:
  278. self.assertEqual(f.readable(), False)
  279. self.assertEqual(f.writable(), True)
  280. self.assertEqual(f.seekable(), True)
  281. self.write_ops(f)
  282. with self.open(support.TESTFN, "rb") as f:
  283. self.assertEqual(f.readable(), True)
  284. self.assertEqual(f.writable(), False)
  285. self.assertEqual(f.seekable(), True)
  286. self.read_ops(f, True)
  287. def test_readline(self):
  288. with self.open(support.TESTFN, "wb") as f:
  289. f.write(b"abc\ndef\nxyzzy\nfoo\x00bar\nanother line")
  290. with self.open(support.TESTFN, "rb") as f:
  291. self.assertEqual(f.readline(), b"abc\n")
  292. self.assertEqual(f.readline(10), b"def\n")
  293. self.assertEqual(f.readline(2), b"xy")
  294. self.assertEqual(f.readline(4), b"zzy\n")
  295. self.assertEqual(f.readline(), b"foo\x00bar\n")
  296. self.assertEqual(f.readline(None), b"another line")
  297. self.assertRaises(TypeError, f.readline, 5.3)
  298. with self.open(support.TESTFN, "r") as f:
  299. self.assertRaises(TypeError, f.readline, 5.3)
  300. def test_raw_bytes_io(self):
  301. f = self.BytesIO()
  302. self.write_ops(f)
  303. data = f.getvalue()
  304. self.assertEqual(data, b"hello world\n")
  305. f = self.BytesIO(data)
  306. self.read_ops(f, True)
  307. def test_large_file_ops(self):
  308. # On Windows and Mac OSX this test comsumes large resources; It takes
  309. # a long time to build the >2GB file and takes >2GB of disk space
  310. # therefore the resource must be enabled to run this test.
  311. if sys.platform[:3] == 'win' or sys.platform == 'darwin':
  312. if not support.is_resource_enabled("largefile"):
  313. print("\nTesting large file ops skipped on %s." % sys.platform,
  314. file=sys.stderr)
  315. print("It requires %d bytes and a long time." % self.LARGE,
  316. file=sys.stderr)
  317. print("Use 'regrtest.py -u largefile test_io' to run it.",
  318. file=sys.stderr)
  319. return
  320. with self.open(support.TESTFN, "w+b", 0) as f:
  321. self.large_file_ops(f)
  322. with self.open(support.TESTFN, "w+b") as f:
  323. self.large_file_ops(f)
  324. def test_with_open(self):
  325. for bufsize in (0, 1, 100):
  326. f = None
  327. with self.open(support.TESTFN, "wb", bufsize) as f:
  328. f.write(b"xxx")
  329. self.assertEqual(f.closed, True)
  330. f = None
  331. try:
  332. with self.open(support.TESTFN, "wb", bufsize) as f:
  333. 1 // 0
  334. except ZeroDivisionError:
  335. self.assertEqual(f.closed, True)
  336. else:
  337. self.fail("1 // 0 didn't raise an exception")
  338. # issue 5008
  339. def test_append_mode_tell(self):
  340. with self.open(support.TESTFN, "wb") as f:
  341. f.write(b"xxx")
  342. with self.open(support.TESTFN, "ab", buffering=0) as f:
  343. self.assertEqual(f.tell(), 3)
  344. with self.open(support.TESTFN, "ab") as f:
  345. self.assertEqual(f.tell(), 3)
  346. with self.open(support.TESTFN, "a") as f:
  347. self.assertTrue(f.tell() > 0)
  348. def test_destructor(self):
  349. record = []
  350. class MyFileIO(self.FileIO):
  351. def __del__(self):
  352. record.append(1)
  353. try:
  354. f = super(MyFileIO, self).__del__
  355. except AttributeError:
  356. pass
  357. else:
  358. f()
  359. def close(self):
  360. record.append(2)
  361. super(MyFileIO, self).close()
  362. def flush(self):
  363. record.append(3)
  364. super(MyFileIO, self).flush()
  365. f = MyFileIO(support.TESTFN, "wb")
  366. f.write(b"xxx")
  367. del f
  368. support.gc_collect()
  369. self.assertEqual(record, [1, 2, 3])
  370. with self.open(support.TESTFN, "rb") as f:
  371. self.assertEqual(f.read(), b"xxx")
  372. def _check_base_destructor(self, base):
  373. record = []
  374. class MyIO(base):
  375. def __init__(self):
  376. # This exercises the availability of attributes on object
  377. # destruction.
  378. # (in the C version, close() is called by the tp_dealloc
  379. # function, not by __del__)
  380. self.on_del = 1
  381. self.on_close = 2
  382. self.on_flush = 3
  383. def __del__(self):
  384. record.append(self.on_del)
  385. try:
  386. f = super(MyIO, self).__del__
  387. except AttributeError:
  388. pass
  389. else:
  390. f()
  391. def close(self):
  392. record.append(self.on_close)
  393. super(MyIO, self).close()
  394. def flush(self):
  395. record.append(self.on_flush)
  396. super(MyIO, self).flush()
  397. f = MyIO()
  398. del f
  399. support.gc_collect()
  400. self.assertEqual(record, [1, 2, 3])
  401. def test_IOBase_destructor(self):
  402. self._check_base_destructor(self.IOBase)
  403. def test_RawIOBase_destructor(self):
  404. self._check_base_destructor(self.RawIOBase)
  405. def test_BufferedIOBase_destructor(self):
  406. self._check_base_destructor(self.BufferedIOBase)
  407. def test_TextIOBase_destructor(self):
  408. self._check_base_destructor(self.TextIOBase)
  409. def test_close_flushes(self):
  410. with self.open(support.TESTFN, "wb") as f:
  411. f.write(b"xxx")
  412. with self.open(support.TESTFN, "rb") as f:
  413. self.assertEqual(f.read(), b"xxx")
  414. def test_array_writes(self):
  415. a = array.array(b'i', range(10))
  416. n = len(a.tostring())
  417. with self.open(support.TESTFN, "wb", 0) as f:
  418. self.assertEqual(f.write(a), n)
  419. with self.open(support.TESTFN, "wb") as f:
  420. self.assertEqual(f.write(a), n)
  421. def test_closefd(self):
  422. self.assertRaises(ValueError, self.open, support.TESTFN, 'w',
  423. closefd=False)
  424. def test_read_closed(self):
  425. with self.open(support.TESTFN, "w") as f:
  426. f.write("egg\n")
  427. with self.open(support.TESTFN, "r") as f:
  428. file = self.open(f.fileno(), "r", closefd=False)
  429. self.assertEqual(file.read(), "egg\n")
  430. file.seek(0)
  431. file.close()
  432. self.assertRaises(ValueError, file.read)
  433. def test_no_closefd_with_filename(self):
  434. # can't use closefd in combination with a file name
  435. self.assertRaises(ValueError, self.open, support.TESTFN, "r", closefd=False)
  436. def test_closefd_attr(self):
  437. with self.open(support.TESTFN, "wb") as f:
  438. f.write(b"egg\n")
  439. with self.open(support.TESTFN, "r") as f:
  440. self.assertEqual(f.buffer.raw.closefd, True)
  441. file = self.open(f.fileno(), "r", closefd=False)
  442. self.assertEqual(file.buffer.raw.closefd, False)
  443. def test_garbage_collection(self):
  444. # FileIO objects are collected, and collecting them flushes
  445. # all data to disk.
  446. f = self.FileIO(support.TESTFN, "wb")
  447. f.write(b"abcxxx")
  448. f.f = f
  449. wr = weakref.ref(f)
  450. del f
  451. support.gc_collect()
  452. self.assertTrue(wr() is None, wr)
  453. with self.open(support.TESTFN, "rb") as f:
  454. self.assertEqual(f.read(), b"abcxxx")
  455. def test_unbounded_file(self):
  456. # Issue #1174606: reading from an unbounded stream such as /dev/zero.
  457. zero = "/dev/zero"
  458. if not os.path.exists(zero):
  459. self.skipTest("{0} does not exist".format(zero))
  460. if sys.maxsize > 0x7FFFFFFF:
  461. self.skipTest("test can only run in a 32-bit address space")
  462. if support.real_max_memuse < support._2G:
  463. self.skipTest("test requires at least 2GB of memory")
  464. with self.open(zero, "rb", buffering=0) as f:
  465. self.assertRaises(OverflowError, f.read)
  466. with self.open(zero, "rb") as f:
  467. self.assertRaises(OverflowError, f.read)
  468. with self.open(zero, "r") as f:
  469. self.assertRaises(OverflowError, f.read)
  470. def test_flush_error_on_close(self):
  471. f = self.open(support.TESTFN, "wb", buffering=0)
  472. def bad_flush():
  473. raise IOError()
  474. f.flush = bad_flush
  475. self.assertRaises(IOError, f.close) # exception not swallowed
  476. def test_multi_close(self):
  477. f = self.open(support.TESTFN, "wb", buffering=0)
  478. f.close()
  479. f.close()
  480. f.close()
  481. self.assertRaises(ValueError, f.flush)
  482. def test_RawIOBase_read(self):
  483. # Exercise the default RawIOBase.read() implementation (which calls
  484. # readinto() internally).
  485. rawio = self.MockRawIOWithoutRead((b"abc", b"d", None, b"efg", None))
  486. self.assertEqual(rawio.read(2), b"ab")
  487. self.assertEqual(rawio.read(2), b"c")
  488. self.assertEqual(rawio.read(2), b"d")
  489. self.assertEqual(rawio.read(2), None)
  490. self.assertEqual(rawio.read(2), b"ef")
  491. self.assertEqual(rawio.read(2), b"g")
  492. self.assertEqual(rawio.read(2), None)
  493. self.assertEqual(rawio.read(2), b"")
  494. class CIOTest(IOTest):
  495. pass
  496. class PyIOTest(IOTest):
  497. test_array_writes = unittest.skip(
  498. "len(array.array) returns number of elements rather than bytelength"
  499. )(IOTest.test_array_writes)
  500. class CommonBufferedTests:
  501. # Tests common to BufferedReader, BufferedWriter and BufferedRandom
  502. def test_detach(self):
  503. raw = self.MockRawIO()
  504. buf = self.tp(raw)
  505. self.assertIs(buf.detach(), raw)
  506. self.assertRaises(ValueError, buf.detach)
  507. def test_fileno(self):
  508. rawio = self.MockRawIO()
  509. bufio = self.tp(rawio)
  510. self.assertEqual(42, bufio.fileno())
  511. def test_no_fileno(self):
  512. # XXX will we always have fileno() function? If so, kill
  513. # this test. Else, write it.
  514. pass
  515. def test_invalid_args(self):
  516. rawio = self.MockRawIO()
  517. bufio = self.tp(rawio)
  518. # Invalid whence
  519. self.assertRaises(ValueError, bufio.seek, 0, -1)
  520. self.assertRaises(ValueError, bufio.seek, 0, 3)
  521. def test_override_destructor(self):
  522. tp = self.tp
  523. record = []
  524. class MyBufferedIO(tp):
  525. def __del__(self):
  526. record.append(1)
  527. try:
  528. f = super(MyBufferedIO, self).__del__
  529. except AttributeError:
  530. pass
  531. else:
  532. f()
  533. def close(self):
  534. record.append(2)
  535. super(MyBufferedIO, self).close()
  536. def flush(self):
  537. record.append(3)
  538. super(MyBufferedIO, self).flush()
  539. rawio = self.MockRawIO()
  540. bufio = MyBufferedIO(rawio)
  541. writable = bufio.writable()
  542. del bufio
  543. support.gc_collect()
  544. if writable:
  545. self.assertEqual(record, [1, 2, 3])
  546. else:
  547. self.assertEqual(record, [1, 2])
  548. def test_context_manager(self):
  549. # Test usability as a context manager
  550. rawio = self.MockRawIO()
  551. bufio = self.tp(rawio)
  552. def _with():
  553. with bufio:
  554. pass
  555. _with()
  556. # bufio should now be closed, and using it a second time should raise
  557. # a ValueError.
  558. self.assertRaises(ValueError, _with)
  559. def test_error_through_destructor(self):
  560. # Test that the exception state is not modified by a destructor,
  561. # even if close() fails.
  562. rawio = self.CloseFailureIO()
  563. def f():
  564. self.tp(rawio).xyzzy
  565. with support.captured_output("stderr") as s:
  566. self.assertRaises(AttributeError, f)
  567. s = s.getvalue().strip()
  568. if s:
  569. # The destructor *may* have printed an unraisable error, check it
  570. self.assertEqual(len(s.splitlines()), 1)
  571. self.assertTrue(s.startswith("Exception IOError: "), s)
  572. self.assertTrue(s.endswith(" ignored"), s)
  573. def test_repr(self):
  574. raw = self.MockRawIO()
  575. b = self.tp(raw)
  576. clsname = "%s.%s" % (self.tp.__module__, self.tp.__name__)
  577. self.assertEqual(repr(b), "<%s>" % clsname)
  578. raw.name = "dummy"
  579. self.assertEqual(repr(b), "<%s name=u'dummy'>" % clsname)
  580. raw.name = b"dummy"
  581. self.assertEqual(repr(b), "<%s name='dummy'>" % clsname)
  582. def test_flush_error_on_close(self):
  583. raw = self.MockRawIO()
  584. def bad_flush():
  585. raise IOError()
  586. raw.flush = bad_flush
  587. b = self.tp(raw)
  588. self.assertRaises(IOError, b.close) # exception not swallowed
  589. def test_multi_close(self):
  590. raw = self.MockRawIO()
  591. b = self.tp(raw)
  592. b.close()
  593. b.close()
  594. b.close()
  595. self.assertRaises(ValueError, b.flush)
  596. def test_readonly_attributes(self):
  597. raw = self.MockRawIO()
  598. buf = self.tp(raw)
  599. x = self.MockRawIO()
  600. with self.assertRaises((AttributeError, TypeError)):
  601. buf.raw = x
  602. class BufferedReaderTest(unittest.TestCase, CommonBufferedTests):
  603. read_mode = "rb"
  604. def test_constructor(self):
  605. rawio = self.MockRawIO([b"abc"])
  606. bufio = self.tp(rawio)
  607. bufio.__init__(rawio)
  608. bufio.__init__(rawio, buffer_size=1024)
  609. bufio.__init__(rawio, buffer_size=16)
  610. self.assertEqual(b"abc", bufio.read())
  611. self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=0)
  612. self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-16)
  613. self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-1)
  614. rawio = self.MockRawIO([b"abc"])
  615. bufio.__init__(rawio)
  616. self.assertEqual(b"abc", bufio.read())
  617. def test_read(self):
  618. for arg in (None, 7):
  619. rawio = self.MockRawIO((b"abc", b"d", b"efg"))
  620. bufio = self.tp(rawio)
  621. self.assertEqual(b"abcdefg", bufio.read(arg))
  622. # Invalid args
  623. self.assertRaises(ValueError, bufio.read, -2)
  624. def test_read1(self):
  625. rawio = self.MockRawIO((b"abc", b"d", b"efg"))
  626. bufio = self.tp(rawio)
  627. self.assertEqual(b"a", bufio.read(1))
  628. self.assertEqual(b"b", bufio.read1(1))
  629. self.assertEqual(rawio._reads, 1)
  630. self.assertEqual(b"c", bufio.read1(100))
  631. self.assertEqual(rawio._reads, 1)
  632. self.assertEqual(b"d", bufio.read1(100))
  633. self.assertEqual(rawio._reads, 2)
  634. self.assertEqual(b"efg", bufio.read1(100))
  635. self.assertEqual(rawio._reads, 3)
  636. self.assertEqual(b"", bufio.read1(100))
  637. self.assertEqual(rawio._reads, 4)
  638. # Invalid args
  639. self.assertRaises(ValueError, bufio.read1, -1)
  640. def test_readinto(self):
  641. rawio = self.MockRawIO((b"abc", b"d", b"efg"))
  642. bufio = self.tp(rawio)
  643. b = bytearray(2)
  644. self.assertEqual(bufio.readinto(b), 2)
  645. self.assertEqual(b, b"ab")
  646. self.assertEqual(bufio.readinto(b), 2)
  647. self.assertEqual(b, b"cd")
  648. self.assertEqual(bufio.readinto(b), 2)
  649. self.assertEqual(b, b"ef")
  650. self.assertEqual(bufio.readinto(b), 1)
  651. self.assertEqual(b, b"gf")
  652. self.assertEqual(bufio.readinto(b), 0)
  653. self.assertEqual(b, b"gf")
  654. def test_readlines(self):
  655. def bufio():
  656. rawio = self.MockRawIO((b"abc\n", b"d\n", b"ef"))
  657. return self.tp(rawio)
  658. self.assertEqual(bufio().readlines(), [b"abc\n", b"d\n", b"ef"])
  659. self.assertEqual(bufio().readlines(5), [b"abc\n", b"d\n"])
  660. self.assertEqual(bufio().readlines(None), [b"abc\n", b"d\n", b"ef"])
  661. def test_buffering(self):
  662. data = b"abcdefghi"
  663. dlen = len(data)
  664. tests = [
  665. [ 100, [ 3, 1, 4, 8 ], [ dlen, 0 ] ],
  666. [ 100, [ 3, 3, 3], [ dlen ] ],
  667. [ 4, [ 1, 2, 4, 2 ], [ 4, 4, 1 ] ],
  668. ]
  669. for bufsize, buf_read_sizes, raw_read_sizes in tests:
  670. rawio = self.MockFileIO(data)
  671. bufio = self.tp(rawio, buffer_size=bufsize)
  672. pos = 0
  673. for nbytes in buf_read_sizes:
  674. self.assertEqual(bufio.read(nbytes), data[pos:pos+nbytes])
  675. pos += nbytes
  676. # this is mildly implementation-dependent
  677. self.assertEqual(rawio.read_history, raw_read_sizes)
  678. def test_read_non_blocking(self):
  679. # Inject some None's in there to simulate EWOULDBLOCK
  680. rawio = self.MockRawIO((b"abc", b"d", None, b"efg", None, None, None))
  681. bufio = self.tp(rawio)
  682. self.assertEqual(b"abcd", bufio.read(6))
  683. self.assertEqual(b"e", bufio.read(1))
  684. self.assertEqual(b"fg", bufio.read())
  685. self.assertEqual(b"", bufio.peek(1))
  686. self.assertIsNone(bufio.read())
  687. self.assertEqual(b"", bufio.read())
  688. rawio = self.MockRawIO((b"a", None, None))
  689. self.assertEqual(b"a", rawio.readall())
  690. self.assertIsNone(rawio.readall())
  691. def test_read_past_eof(self):
  692. rawio = self.MockRawIO((b"abc", b"d", b"efg"))
  693. bufio = self.tp(rawio)
  694. self.assertEqual(b"abcdefg", bufio.read(9000))
  695. def test_read_all(self):
  696. rawio = self.MockRawIO((b"abc", b"d", b"efg"))
  697. bufio = self.tp(rawio)
  698. self.assertEqual(b"abcdefg", bufio.read())
  699. @unittest.skipUnless(threading, 'Threading required for this test.')
  700. @support.requires_resource('cpu')
  701. def test_threads(self):
  702. try:
  703. # Write out many bytes with exactly the same number of 0's,
  704. # 1's... 255's. This will help us check that concurrent reading
  705. # doesn't duplicate or forget contents.
  706. N = 1000
  707. l = list(range(256)) * N
  708. random.shuffle(l)
  709. s = bytes(bytearray(l))
  710. with self.open(support.TESTFN, "wb") as f:
  711. f.write(s)
  712. with self.open(support.TESTFN, self.read_mode, buffering=0) as raw:
  713. bufio = self.tp(raw, 8)
  714. errors = []
  715. results = []
  716. def f():
  717. try:
  718. # Intra-buffer read then buffer-flushing read
  719. for n in cycle([1, 19]):
  720. s = bufio.read(n)
  721. if not s:
  722. break
  723. # list.append() is atomic
  724. results.append(s)
  725. except Exception as e:
  726. errors.append(e)
  727. raise
  728. threads = [threading.Thread(target=f) for x in range(20)]
  729. for t in threads:
  730. t.start()
  731. time.sleep(0.02) # yield
  732. for t in threads:
  733. t.join()
  734. self.assertFalse(errors,
  735. "the following exceptions were caught: %r" % errors)
  736. s = b''.join(results)
  737. for i in range(256):
  738. c = bytes(bytearray([i]))
  739. self.assertEqual(s.count(c), N)
  740. finally:
  741. support.unlink(support.TESTFN)
  742. def test_misbehaved_io(self):
  743. rawio = self.MisbehavedRawIO((b"abc", b"d", b"efg"))
  744. bufio = self.tp(rawio)
  745. self.assertRaises(IOError, bufio.seek, 0)
  746. self.assertRaises(IOError, bufio.tell)
  747. def test_no_extraneous_read(self):
  748. # Issue #9550; when the raw IO object has satisfied the read request,
  749. # we should not issue any additional reads, otherwise it may block
  750. # (e.g. socket).
  751. bufsize = 16
  752. for n in (2, bufsize - 1, bufsize, bufsize + 1, bufsize * 2):
  753. rawio = self.MockRawIO([b"x" * n])
  754. bufio = self.tp(rawio, bufsize)
  755. self.assertEqual(bufio.read(n), b"x" * n)
  756. # Simple case: one raw read is enough to satisfy the request.
  757. self.assertEqual(rawio._extraneous_reads, 0,
  758. "failed for {}: {} != 0".format(n, rawio._extraneous_reads))
  759. # A more complex case where two raw reads are needed to satisfy
  760. # the request.
  761. rawio = self.MockRawIO([b"x" * (n - 1), b"x"])
  762. bufio = self.tp(rawio, bufsize)
  763. self.assertEqual(bufio.read(n), b"x" * n)
  764. self.assertEqual(rawio._extraneous_reads, 0,
  765. "failed for {}: {} != 0".format(n, rawio._extraneous_reads))
  766. class CBufferedReaderTest(BufferedReaderTest):
  767. tp = io.BufferedReader
  768. def test_constructor(self):
  769. BufferedReaderTest.test_constructor(self)
  770. # The allocation can succeed on 32-bit builds, e.g. with more
  771. # than 2GB RAM and a 64-bit kernel.
  772. if sys.maxsize > 0x7FFFFFFF:
  773. rawio = self.MockRawIO()
  774. bufio = self.tp(rawio)
  775. self.assertRaises((OverflowError, MemoryError, ValueError),
  776. bufio.__init__, rawio, sys.maxsize)
  777. def test_initialization(self):
  778. rawio = self.MockRawIO([b"abc"])
  779. bufio = self.tp(rawio)
  780. self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=0)
  781. self.assertRaises(ValueError, bufio.read)
  782. self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-16)
  783. self.assertRaises(ValueError, bufio.read)
  784. self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-1)
  785. self.assertRaises(ValueError, bufio.read)
  786. def test_misbehaved_io_read(self):
  787. rawio = self.MisbehavedRawIO((b"abc", b"d", b"efg"))
  788. bufio = self.tp(rawio)
  789. # _pyio.BufferedReader seems to implement reading different, so that
  790. # checking this is not so easy.
  791. self.assertRaises(IOError, bufio.read, 10)
  792. def test_garbage_collection(self):
  793. # C BufferedReader objects are collected.
  794. # The Python version has __del__, so it ends into gc.garbage instead
  795. rawio = self.FileIO(support.TESTFN, "w+b")
  796. f = self.tp(rawio)
  797. f.f = f
  798. wr = weakref.ref(f)
  799. del f
  800. support.gc_collect()
  801. self.assertTrue(wr() is None, wr)
  802. class PyBufferedReaderTest(BufferedReaderTest):
  803. tp = pyio.BufferedReader
  804. class BufferedWriterTest(unittest.TestCase, CommonBufferedTests):
  805. write_mode = "wb"
  806. def test_constructor(self):
  807. rawio = self.MockRawIO()
  808. bufio = self.tp(rawio)
  809. bufio.__init__(rawio)
  810. bufio.__init__(rawio, buffer_size=1024)
  811. bufio.__init__(rawio, buffer_size=16)
  812. self.assertEqual(3, bufio.write(b"abc"))
  813. bufio.flush()
  814. self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=0)
  815. self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-16)
  816. self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-1)
  817. bufio.__init__(rawio)
  818. self.assertEqual(3, bufio.write(b"ghi"))
  819. bufio.flush()
  820. self.assertEqual(b"".join(rawio._write_stack), b"abcghi")
  821. def test_detach_flush(self):
  822. raw = self.MockRawIO()
  823. buf = self.tp(raw)
  824. buf.write(b"howdy!")
  825. self.assertFalse(raw._write_stack)
  826. buf.detach()
  827. self.assertEqual(raw._write_stack, [b"howdy!"])
  828. def test_write(self):
  829. # Write to the buffered IO but don't overflow the buffer.
  830. writer = self.MockRawIO()
  831. bufio = self.tp(writer, 8)
  832. bufio.write(b"abc")
  833. self.assertFalse(writer._write_stack)
  834. def test_write_overflow(self):
  835. writer = self.MockRawIO()
  836. bufio = self.tp(writer, 8)
  837. contents = b"abcdefghijklmnop"
  838. for n in range(0, len(contents), 3):
  839. bufio.write(contents[n:n+3])
  840. flushed = b"".join(writer._write_stack)
  841. # At least (total - 8) bytes were implicitly flushed, perhaps more
  842. # depending on the implementation.
  843. self.assertTrue(flushed.startswith(contents[:-8]), flushed)
  844. def check_writes(self, intermediate_func):
  845. # Lots of writes, test the flushed output is as expected.
  846. contents = bytes(range(256)) * 1000
  847. n = 0
  848. writer = self.MockRawIO()
  849. bufio = self.tp(writer, 13)
  850. # Generator of write sizes: repeat each N 15 times then proceed to N+1
  851. def gen_sizes():
  852. for size in count(1):
  853. for i in range(15):
  854. yield size
  855. sizes = gen_sizes()
  856. while n < len(contents):
  857. size = min(next(sizes), len(contents) - n)
  858. self.assertEqual(bufio.write(contents[n:n+size]), size)
  859. intermediate_func(bufio)
  860. n += size
  861. bufio.flush()
  862. self.assertEqual(contents,
  863. b"".join(writer._write_stack))
  864. def test_writes(self):
  865. self.check_writes(lambda bufio: None)
  866. def test_writes_and_flushes(self):
  867. self.check_writes(lambda bufio: bufio.flush())
  868. def test_writes_and_seeks(self):
  869. def _seekabs(bufio):
  870. pos = bufio.tell()
  871. bufio.seek(pos + 1, 0)
  872. bufio.seek(pos - 1, 0)
  873. bufio.seek(pos, 0)
  874. self.check_writes(_seekabs)
  875. def _seekrel(bufio):
  876. pos = bufio.seek(0, 1)
  877. bufio.seek(+1, 1)
  878. bufio.seek(-1, 1)
  879. bufio.seek(pos, 0)
  880. self.check_writes(_seekrel)
  881. def test_writes_and_truncates(self):
  882. self.check_writes(lambda bufio: bufio.truncate(bufio.tell()))
  883. def test_write_non_blocking(self):
  884. raw = self.MockNonBlockWriterIO()
  885. bufio = self.tp(raw, 8)
  886. self.assertEqual(bufio.write(b"abcd"), 4)
  887. self.assertEqual(bufio.write(b"efghi"), 5)
  888. # 1 byte will be written, the rest will be buffered
  889. raw.block_on(b"k")
  890. self.assertEqual(bufio.write(b"jklmn"), 5)
  891. # 8 bytes will be written, 8 will be buffered and the rest will be lost
  892. raw.block_on(b"0")
  893. try:
  894. bufio.write(b"opqrwxyz0123456789")
  895. except self.BlockingIOError as e:
  896. written = e.characters_written
  897. else:
  898. self.fail("BlockingIOError should have been raised")
  899. self.assertEqual(written, 16)
  900. self.assertEqual(raw.pop_written(),
  901. b"abcdefghijklmnopqrwxyz")
  902. self.assertEqual(bufio.write(b"ABCDEFGHI"), 9)
  903. s = raw.pop_written()
  904. # Previously buffered bytes were flushed
  905. self.assertTrue(s.startswith(b"01234567A"), s)
  906. def test_write_and_rewind(self):
  907. raw = io.BytesIO()
  908. bufio = self.tp(raw, 4)
  909. self.assertEqual(bufio.write(b"abcdef"), 6)
  910. self.assertEqual(bufio.tell(), 6)
  911. bufio.seek(0, 0)
  912. self.assertEqual(bufio.write(b"XY"), 2)
  913. bufio.seek(6, 0)
  914. self.assertEqual(raw.getvalue(), b"XYcdef")
  915. self.assertEqual(bufio.write(b"123456"), 6)
  916. bufio.flush()
  917. self.assertEqual(raw.getvalue(), b"XYcdef123456")
  918. def test_flush(self):
  919. writer = self.MockRawIO()
  920. bufio = self.tp(writer, 8)
  921. bufio.write(b"abc")
  922. bufio.flush()
  923. self.assertEqual(b"abc", writer._write_stack[0])
  924. def test_destructor(self):
  925. writer = self.MockRawIO()
  926. bufio = self.tp(writer, 8)
  927. bufio.write(b"abc")
  928. del bufio
  929. support.gc_collect()
  930. self.assertEqual(b"abc", writer._write_stack[0])
  931. def test_truncate(self):
  932. # Truncate implicitly flushes the buffer.
  933. with self.open(support.TESTFN, self.write_mode, buffering=0) as raw:
  934. bufio = self.tp(raw, 8)
  935. bufio.write(b"abcdef")
  936. self.assertEqual(bufio.truncate(3), 3)
  937. self.assertEqual(bufio.tell(), 6)
  938. with self.open(support.TESTFN, "rb", buffering=0) as f:
  939. self.assertEqual(f.read(), b"abc")
  940. @unittest.skipUnless(threading, 'Threading required for this test.')
  941. @support.requires_resource('cpu')
  942. def test_threads(self):
  943. try:
  944. # Write out many bytes from many threads and test they were
  945. # all flushed.
  946. N = 1000
  947. contents = bytes(range(256)) * N
  948. sizes = cycle([1, 19])
  949. n = 0
  950. queue = deque()
  951. while n < len(contents):
  952. size = next(sizes)
  953. queue.append(contents[n:n+size])
  954. n += size
  955. del contents
  956. # We use a real file object because it allows us to
  957. # exercise situations where the GIL is released before
  958. # writing the buffer to the raw streams. This is in addition
  959. # to concurrency issues due to switching threads in the middle
  960. # of Python code.
  961. with self.open(support.TESTFN, self.write_mode, buffering=0) as raw:
  962. bufio = self.tp(raw, 8)
  963. errors = []
  964. def f():
  965. try:
  966. while True:
  967. try:
  968. s = queue.popleft()
  969. except IndexError:
  970. return
  971. bufio.write(s)
  972. except Exception as e:
  973. errors.append(e)
  974. raise
  975. threads = [threading.Thread(target=f) for x in range(20)]
  976. for t in threads:
  977. t.start()
  978. time.sleep(0.02) # yield
  979. for t in threads:
  980. t.join()
  981. self.assertFalse(errors,
  982. "the following exceptions were caught: %r" % errors)
  983. bufio.close()
  984. with self.open(support.TESTFN, "rb") as f:
  985. s = f.read()
  986. for i in range(256):
  987. self.assertEqual(s.count(bytes([i])), N)
  988. finally:
  989. support.unlink(support.TESTFN)
  990. def test_misbehaved_io(self):
  991. rawio = self.MisbehavedRawIO()
  992. bufio = self.tp(rawio, 5)
  993. self.assertRaises(IOError, bufio.seek, 0)
  994. self.assertRaises(IOError, bufio.tell)
  995. self.assertRaises(IOError, bufio.write, b"abcdef")
  996. def test_max_buffer_size_deprecation(self):
  997. with support.check_warnings(("max_buffer_size is deprecated",
  998. DeprecationWarning)):
  999. self.tp(self.MockRawIO(), 8, 12)
  1000. class CBufferedWriterTest(BufferedWriterTest):
  1001. tp = io.BufferedWriter
  1002. def test_constructor(self):
  1003. BufferedWriterTest.test_constructor(self)
  1004. # The allocation can succeed on 32-bit builds, e.g. with more
  1005. # than 2GB RAM and a 64-bit kernel.
  1006. if sys.maxsize > 0x7FFFFFFF:
  1007. rawio = self.MockRawIO()
  1008. bufio = self.tp(rawio)
  1009. self.assertRaises((OverflowError, MemoryError, ValueError),
  1010. bufio.__init__, rawio, sys.maxsize)
  1011. def test_initialization(self):
  1012. rawio = self.MockRawIO()
  1013. bufio = self.tp(rawio)
  1014. self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=0)
  1015. self.assertRaises(ValueError, bufio.write, b"def")
  1016. self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-16)
  1017. self.assertRaises(ValueError, bufio.write, b"def")
  1018. self.assertRaises(ValueError, bufio.__init__, rawio, buffer_size=-1)
  1019. self.assertRaises(ValueError, bufio.write, b"def")
  1020. def test_garbage_collection(self):
  1021. # C BufferedWriter objects are collected, and collecting them flushes
  1022. # all data to disk.
  1023. # The Python version has __del__, so it ends into gc.garbage instead
  1024. rawio = self.FileIO(support.TESTFN, "w+b")
  1025. f = self.tp(rawio)
  1026. f.write(b"123xxx")
  1027. f.x = f
  1028. wr = weakref.ref(f)
  1029. del f
  1030. support.gc_collect()
  1031. self.assertTrue(wr() is None, wr)
  1032. with self.open(support.TESTFN, "rb") as f:
  1033. self.assertEqual(f.read(), b"123xxx")
  1034. class PyBufferedWriterTest(BufferedWriterTest):
  1035. tp = pyio.BufferedWriter
  1036. class BufferedRWPairTest(unittest.TestCase):
  1037. def test_constructor(self):
  1038. pair = self.tp(self.MockRawIO(), self.MockRawIO())
  1039. self.assertFalse(pair.closed)
  1040. def test_detach(self):
  1041. pair = self.tp(self.MockRawIO(), self.MockRawIO())
  1042. self.assertRaises(self.UnsupportedOperation, pair.detach)
  1043. def test_constructor_max_buffer_size_deprecation(self):
  1044. with support.check_warnings(("max_buffer_size is deprecated",
  1045. DeprecationWarning)):
  1046. self.tp(self.MockRawIO(), self.MockRawIO(), 8, 12)
  1047. def test_constructor_with_not_readable(self):
  1048. class NotReadable(MockRawIO):
  1049. def readable(self):
  1050. return False
  1051. self.assertRaises(IOError, self.tp, NotReadable(), self.MockRawIO())
  1052. def test_constructor_with_not_writeable(self):
  1053. class NotWriteable(MockRawIO):
  1054. def writable(self):
  1055. return False
  1056. self.assertRaises(IOError, self.tp, self.MockRawIO(), NotWriteable())
  1057. def test_read(self):
  1058. pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO())
  1059. self.assertEqual(pair.read(3), b"abc")
  1060. self.assertEqual(pair.read(1), b"d")
  1061. self.assertEqual(pair.read(), b"ef")
  1062. pair = self.tp(self.BytesIO(b"abc"), self.MockRawIO())
  1063. self.assertEqual(pair.read(None), b"abc")
  1064. def test_readlines(self):
  1065. pair = lambda: self.tp(self.BytesIO(b"abc\ndef\nh"), self.MockRawIO())
  1066. self.assertEqual(pair().readlines(), [b"abc\n", b"def\n", b"h"])
  1067. self.assertEqual(pair().readlines(), [b"abc\n", b"def\n", b"h"])
  1068. self.assertEqual(pair().readlines(5), [b"abc\n", b"def\n"])
  1069. def test_read1(self):
  1070. # .read1() is delegated to the underlying reader object, so this test
  1071. # can be shallow.
  1072. pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO())
  1073. self.assertEqual(pair.read1(3), b"abc")
  1074. def test_readinto(self):
  1075. pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO())
  1076. data = bytearray(5)
  1077. self.assertEqual(pair.readinto(data), 5)
  1078. self.assertEqual(data, b"abcde")
  1079. def test_write(self):
  1080. w = self.MockRawIO()
  1081. pair = self.tp(self.MockRawIO(), w)
  1082. pair.write(b"abc")
  1083. pair.flush()
  1084. pair.write(b"def")
  1085. pair.flush()
  1086. self.assertEqual(w._write_stack, [b"abc", b"def"])
  1087. def test_peek(self):
  1088. pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO())
  1089. self.assertTrue(pair.peek(3).startswith(b"abc"))
  1090. self.assertEqual(pair.read(3), b"abc")
  1091. def test_readable(self):
  1092. pair = self.tp(self.MockRawIO(), self.MockRawIO())
  1093. self.assertTrue(pair.readable())
  1094. def test_writeable(self):
  1095. pair = self.tp(self.MockRawIO(), self.MockRawIO())
  1096. self.assertTrue(pair.writable())
  1097. def test_seekable(self):
  1098. # BufferedRWPairs are never seekable, even if their readers and writers
  1099. # are.
  1100. pair = self.tp(self.MockRawIO(), self.MockRawIO())
  1101. self.assertFalse(pair.seekable())
  1102. # .flush() is delegated to the underlying writer object and has been
  1103. # tested in the test_write method.
  1104. def test_close_and_closed(self):
  1105. pair = self.tp(self.MockRawIO(), self.MockRawIO())
  1106. self.assertFalse(pair.closed)
  1107. pair.close()
  1108. self.assertTrue(pair.closed)
  1109. def test_isatty(self):
  1110. class SelectableIsAtty(MockRawIO):
  1111. def __init__(self, isatty):
  1112. MockRawIO.__init__(self)
  1113. self._isatty = isatty
  1114. def isatty(self):
  1115. return self._isatty
  1116. pair = self.tp(SelectableIsAtty(False), SelectableIsAtty(False))
  1117. self.assertFalse(pair.isatty())
  1118. pair = self.tp(SelectableIsAtty(True), SelectableIsAtty(False))
  1119. self.assertTrue(pair.isatty())
  1120. pair = self.tp(SelectableIsAtty(False), SelectableIsAtty(True))
  1121. self.assertTrue(pair.isatty())
  1122. pair = self.tp(SelectableIsAtty(True), SelectableIsAtty(True))
  1123. self.assertTrue(pair.isatty())
  1124. class CBufferedRWPairTest(BufferedRWPairTest):
  1125. tp = io.BufferedRWPair
  1126. class PyBufferedRWPairTest(BufferedRWPairTest):
  1127. tp = pyio.BufferedRWPair
  1128. class BufferedRandomTest(BufferedReaderTest, BufferedWriterTest):
  1129. read_mode = "rb+"
  1130. write_mode = "wb+"
  1131. def test_constructor(self):
  1132. BufferedReaderTest.test_constructor(self)
  1133. BufferedWriterTest.test_constructor(self)
  1134. def test_read_and_write(self):
  1135. raw = self.MockRawIO((b"asdf", b"ghjk"))
  1136. rw = self.tp(raw, 8)
  1137. self.assertEqual(b"as", rw.read(2))
  1138. rw.write(b"ddd")
  1139. rw.write(b"eee")
  1140. self.assertFalse(raw._write_stack) # Buffer writes
  1141. self.assertEqual(b"ghjk", rw.read())
  1142. self.assertEqual(b"dddeee", raw._write_stack[0])
  1143. def test_seek_and_tell(self):
  1144. raw = self.BytesIO(b"asdfghjkl")
  1145. rw = self.tp(raw)
  1146. self.assertEqual(b"as", rw.read(2))
  1147. self.assertEqual(2, rw.tell())
  1148. rw.seek(0, 0)
  1149. self.assertEqual(b"asdf", rw.read(4))
  1150. rw.write(b"asdf")
  1151. rw.seek(0, 0)
  1152. self.assertEqual(b"asdfasdfl", rw.read())
  1153. self.assertEqual(9, rw.tell())
  1154. rw.seek(-4, 2)
  1155. self.assertEqual(5, rw.tell())
  1156. rw.seek(2, 1)
  1157. self.assertEqual(7, rw.tell())
  1158. self.assertEqual(b"fl", rw.read(11))
  1159. self.assertRaises(TypeError, rw.seek, 0.0)
  1160. def check_flush_and_read(self, read_func):
  1161. raw = self.BytesIO(b"abcdefghi")
  1162. bufio = self.tp(raw)
  1163. self.assertEqual(b"ab", read_func(bufio, 2))
  1164. bufio.write(b"12")
  1165. self.assertEqual(b"ef", read_func(bufio, 2))
  1166. self.assertEqual(6, bufio.tell())
  1167. bufio.flush()
  1168. self.assertEqual(6, bufio.tell())
  1169. self.assertEqual(b"ghi", read_func(bufio))
  1170. raw.seek(0, 0)
  1171. raw.write(b"XYZ")
  1172. # flush() resets the read buffer
  1173. bufio.flush()
  1174. bufio.seek(0, 0)
  1175. self.assertEqual(b"XYZ", read_func(bufio, 3))
  1176. def test_flush_and_read(self):
  1177. self.check_flush_and_read(lambda bufio, *args: bufio.read(*args))
  1178. def test_flush_and_readinto(self):
  1179. def _readinto(bufio, n=-1):
  1180. b = bytearray(n if n >= 0 else 9999)
  1181. n = bufio.readinto(b)
  1182. return bytes(b[:n])
  1183. self.check_flush_and_read(_readinto)
  1184. def test_flush_and_peek(self):
  1185. def _peek(bufio, n=-1):
  1186. # This relies on the fact that the buffer can contain the whole
  1187. # raw stream, otherwise peek() can return less.
  1188. b = bufio.peek(n)
  1189. if n != -1:
  1190. b = b[:n]
  1191. bufio.seek(len(b), 1)
  1192. return b
  1193. self.check_flush_and_read(_peek)
  1194. def test_flush_and_write(self):
  1195. raw = self.BytesIO(b"abcdefghi")
  1196. bufio = self.tp(raw)
  1197. bufio.write(b"123")
  1198. bufio.flush()
  1199. bufio.write(b"45")
  1200. bufio.flush()
  1201. bufio.seek(0, 0)
  1202. self.assertEqual(b"12345fghi", raw.getvalue())
  1203. self.assertEqual(b"12345fghi", bufio.read())
  1204. def test_threads(self):
  1205. BufferedReaderTest.test_threads(self)
  1206. BufferedWriterTest.test_threads(self)
  1207. def test_writes_and_peek(self):
  1208. def _peek(bufio):
  1209. bufio.peek(1)
  1210. self.check_writes(_peek)
  1211. def _peek(bufio):
  1212. pos = bufio.tell()
  1213. bufio.seek(-1, 1)
  1214. bufio.peek(1)
  1215. bufio.seek(pos, 0)
  1216. self.check_writes(_peek)
  1217. def test_writes_and_reads(self):
  1218. def _read(bufio):
  1219. bufio.seek(-1, 1)
  1220. bufio.read(1)
  1221. self