PageRenderTime 48ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/module/_io/test/test_fileio.py

https://bitbucket.org/pypy/pypy/
Python | 264 lines | 261 code | 3 blank | 0 comment | 2 complexity | e2b4e8e62c3319dba6377f2a0b1cf377 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from rpython.tool.udir import udir
  2. import os
  3. class AppTestFileIO:
  4. spaceconfig = dict(usemodules=['_io'] + (['fcntl'] if os.name != 'nt' else []))
  5. def setup_class(cls):
  6. tmpfile = udir.join('tmpfile')
  7. tmpfile.write("a\nb\nc", mode='wb')
  8. cls.w_tmpfile = cls.space.wrap(str(tmpfile))
  9. cls.w_tmpdir = cls.space.wrap(str(udir))
  10. cls.w_posix = cls.space.appexec([], """():
  11. import %s as m;
  12. return m""" % os.name)
  13. def test_constructor(self):
  14. import _io
  15. f = _io.FileIO(self.tmpfile, 'a')
  16. assert f.name.endswith('tmpfile')
  17. assert f.mode == 'ab'
  18. assert f.closefd is True
  19. f.close()
  20. def test_invalid_fd(self):
  21. import _io
  22. raises(ValueError, _io.FileIO, -10)
  23. raises(TypeError, _io.FileIO, 2 ** 31)
  24. raises(TypeError, _io.FileIO, -2 ** 31 - 1)
  25. def test_weakrefable(self):
  26. import _io
  27. from weakref import proxy
  28. f = _io.FileIO(self.tmpfile)
  29. p = proxy(f)
  30. assert p.mode == 'rb'
  31. f.close()
  32. def test_open_fd(self):
  33. import _io
  34. os = self.posix
  35. fd = os.open(self.tmpfile, os.O_RDONLY, 0666)
  36. f = _io.FileIO(fd, "rb", closefd=False)
  37. assert f.fileno() == fd
  38. assert f.closefd is False
  39. f.close()
  40. os.close(fd)
  41. def test_open_directory(self):
  42. import _io
  43. import os
  44. raises(IOError, _io.FileIO, self.tmpdir, "rb")
  45. if os.name != 'nt':
  46. fd = os.open(self.tmpdir, os.O_RDONLY)
  47. raises(IOError, _io.FileIO, fd, "rb")
  48. os.close(fd)
  49. def test_readline(self):
  50. import _io
  51. f = _io.FileIO(self.tmpfile, 'rb')
  52. assert f.readline() == 'a\n'
  53. assert f.readline() == 'b\n'
  54. assert f.readline() == 'c'
  55. assert f.readline() == ''
  56. f.close()
  57. def test_readlines(self):
  58. import _io
  59. f = _io.FileIO(self.tmpfile, 'rb')
  60. assert f.readlines() == ["a\n", "b\n", "c"]
  61. f.seek(0)
  62. assert f.readlines(3) == ["a\n", "b\n"]
  63. f.close()
  64. def test_readall(self):
  65. import _io
  66. f = _io.FileIO(self.tmpfile, 'rb')
  67. assert f.readall() == "a\nb\nc"
  68. f.close()
  69. def test_write(self):
  70. import _io
  71. filename = self.tmpfile + '_w'
  72. f = _io.FileIO(filename, 'wb')
  73. f.write("te")
  74. f.write(u"st")
  75. # try without flushing
  76. f2 = _io.FileIO(filename, 'rb')
  77. assert f2.read() == "test"
  78. f.close()
  79. f2.close()
  80. def test_writelines(self):
  81. import _io
  82. filename = self.tmpfile + '_w'
  83. f = _io.FileIO(filename, 'wb')
  84. f.writelines(["line1\n", "line2", "line3"])
  85. f2 = _io.FileIO(filename, 'rb')
  86. assert f2.read() == "line1\nline2line3"
  87. f.close()
  88. f2.close()
  89. def test_seek(self):
  90. import _io
  91. f = _io.FileIO(self.tmpfile, 'rb')
  92. f.seek(0)
  93. self.posix.close(f.fileno())
  94. raises(IOError, f.seek, 0)
  95. def test_tell(self):
  96. import _io
  97. f = _io.FileIO(self.tmpfile, 'rb')
  98. f.seek(3)
  99. assert f.tell() == 3
  100. f.close()
  101. def test_truncate(self):
  102. import _io
  103. f = _io.FileIO(self.tmpfile, 'r+b')
  104. assert f.truncate(100) == 100 # grow the file
  105. f.close()
  106. f = _io.FileIO(self.tmpfile)
  107. assert len(f.read()) == 100
  108. f.close()
  109. #
  110. f = _io.FileIO(self.tmpfile, 'r+b')
  111. f.seek(50)
  112. assert f.truncate() == 50
  113. f.close()
  114. f = _io.FileIO(self.tmpfile)
  115. assert len(f.read()) == 50
  116. f.close()
  117. def test_readinto(self):
  118. import _io
  119. a = bytearray('x' * 10)
  120. f = _io.FileIO(self.tmpfile, 'r+')
  121. assert f.readinto(a) == 10
  122. exc = raises(TypeError, f.readinto, u"hello")
  123. assert str(exc.value) == "cannot use unicode as modifiable buffer"
  124. exc = raises(TypeError, f.readinto, buffer(b"hello"))
  125. assert str(exc.value) == "must be read-write buffer, not buffer"
  126. exc = raises(TypeError, f.readinto, buffer(bytearray("hello")))
  127. assert str(exc.value) == "must be read-write buffer, not buffer"
  128. exc = raises(TypeError, f.readinto, memoryview(b"hello"))
  129. assert str(exc.value) == "must be read-write buffer, not memoryview"
  130. f.close()
  131. assert a == 'a\nb\nc\0\0\0\0\0'
  132. #
  133. a = bytearray('x' * 10)
  134. f = _io.FileIO(self.tmpfile, 'r+')
  135. f.truncate(3)
  136. assert f.readinto(a) == 3
  137. f.close()
  138. assert a == 'a\nbxxxxxxx'
  139. def test_nonblocking_read(self):
  140. try:
  141. import os, fcntl
  142. except ImportError:
  143. skip("need fcntl to set nonblocking mode")
  144. r_fd, w_fd = os.pipe()
  145. # set nonblocking
  146. fcntl.fcntl(r_fd, fcntl.F_SETFL, os.O_NONBLOCK)
  147. import _io
  148. f = _io.FileIO(r_fd, 'r')
  149. # Read from stream sould return None
  150. assert f.read() is None
  151. assert f.read(10) is None
  152. a = bytearray('x' * 10)
  153. assert f.readinto(a) is None
  154. def test_repr(self):
  155. import _io
  156. f = _io.FileIO(self.tmpfile, 'r')
  157. assert repr(f) == ("<_io.FileIO name=%r mode='%s'>"
  158. % (f.name, f.mode))
  159. del f.name
  160. assert repr(f) == ("<_io.FileIO fd=%r mode='%s'>"
  161. % (f.fileno(), f.mode))
  162. f.close()
  163. assert repr(f) == "<_io.FileIO [closed]>"
  164. def test_unclosed_fd_on_exception(self):
  165. import _io
  166. import os
  167. class MyException(Exception): pass
  168. class MyFileIO(_io.FileIO):
  169. def __setattr__(self, name, value):
  170. if name == "name":
  171. raise MyException("blocked setting name")
  172. return super(MyFileIO, self).__setattr__(name, value)
  173. fd = os.open(self.tmpfile, os.O_RDONLY)
  174. raises(MyException, MyFileIO, fd)
  175. os.close(fd) # should not raise OSError(EBADF)
  176. def test_mode_strings(self):
  177. import _io
  178. import os
  179. for modes in [('w', 'wb'), ('wb', 'wb'), ('wb+', 'rb+'),
  180. ('w+b', 'rb+'), ('a', 'ab'), ('ab', 'ab'),
  181. ('ab+', 'ab+'), ('a+b', 'ab+'), ('r', 'rb'),
  182. ('rb', 'rb'), ('rb+', 'rb+'), ('r+b', 'rb+')]:
  183. # read modes are last so that TESTFN will exist first
  184. with _io.FileIO(self.tmpfile, modes[0]) as f:
  185. assert f.mode == modes[1]
  186. def test_flush_error_on_close(self):
  187. # Test that the file is closed despite failed flush
  188. # and that flush() is called before file closed.
  189. import _io, os
  190. fd = os.open(self.tmpfile, os.O_RDONLY, 0666)
  191. f = _io.FileIO(fd, 'r', closefd=False)
  192. closed = []
  193. def bad_flush():
  194. closed[:] = [f.closed]
  195. raise IOError()
  196. f.flush = bad_flush
  197. raises(IOError, f.close) # exception not swallowed
  198. assert f.closed
  199. assert closed # flush() called
  200. assert not closed[0] # flush() called before file closed
  201. os.close(fd)
  202. def test_flush_at_exit():
  203. from pypy import conftest
  204. from pypy.tool.option import make_config, make_objspace
  205. from rpython.tool.udir import udir
  206. tmpfile = udir.join('test_flush_at_exit')
  207. config = make_config(conftest.option)
  208. space = make_objspace(config)
  209. space.appexec([space.wrap(str(tmpfile))], """(tmpfile):
  210. import io
  211. f = io.open(tmpfile, 'w', encoding='ascii')
  212. f.write(u'42')
  213. # no flush() and no close()
  214. import sys; sys._keepalivesomewhereobscure = f
  215. """)
  216. space.finish()
  217. assert tmpfile.read() == '42'
  218. def test_flush_at_exit_IOError_and_ValueError():
  219. from pypy import conftest
  220. from pypy.tool.option import make_config, make_objspace
  221. config = make_config(conftest.option)
  222. space = make_objspace(config)
  223. space.appexec([], """():
  224. import io
  225. class MyStream(io.IOBase):
  226. def flush(self):
  227. raise IOError
  228. class MyStream2(io.IOBase):
  229. def flush(self):
  230. raise ValueError
  231. s = MyStream()
  232. s2 = MyStream2()
  233. import sys; sys._keepalivesomewhereobscure = s
  234. """)
  235. space.finish() # the IOError has been ignored