Author: Amaury Forgeot d'Arc <[email protected]>
Branch:
Changeset: r78090:0117c2d4c183
Date: 2015-06-14 16:38 +0200
http://bitbucket.org/pypy/pypy/changeset/0117c2d4c183/
Log: CPython Issue #21802: The reader in BufferedRWPair now is closed
even when closing writer failed in BufferedRWPair.close()
diff --git a/pypy/module/_io/interp_bufferedio.py
b/pypy/module/_io/interp_bufferedio.py
--- a/pypy/module/_io/interp_bufferedio.py
+++ b/pypy/module/_io/interp_bufferedio.py
@@ -972,9 +972,26 @@
method, writer=True)
# forward to both
- for method in ['close']:
- locals()[method + '_w'] = make_forwarding_method(
- method, writer=True, reader=True)
+ def close_w(self, space, __args__):
+ if self.w_writer is None:
+ raise oefmt(space.w_ValueError,
+ "I/O operation on uninitialized object")
+ w_meth = space.getattr(self.w_writer, space.wrap("close"))
+ try:
+ space.call_args(w_meth, __args__)
+ except OperationError as e:
+ pass
+ else:
+ e = None
+
+ if self.w_reader is None:
+ raise oefmt(space.w_ValueError,
+ "I/O operation on uninitialized object")
+ w_meth = space.getattr(self.w_reader, space.wrap("close"))
+ space.call_args(w_meth, __args__)
+
+ if e:
+ raise e
def isatty_w(self, space):
if space.is_true(space.call_method(self.w_writer, "isatty")):
diff --git a/pypy/module/_io/test/test_bufferedio.py
b/pypy/module/_io/test/test_bufferedio.py
--- a/pypy/module/_io/test/test_bufferedio.py
+++ b/pypy/module/_io/test/test_bufferedio.py
@@ -592,6 +592,47 @@
raises(IOError, _io.BufferedRWPair, _io.BytesIO(), NotWritable())
+ def test_writer_close_error_on_close(self):
+ import _io
+ class MockRawIO(_io._IOBase):
+ def readable(self):
+ return True
+ def writable(self):
+ return True
+ def writer_close():
+ writer_non_existing
+ reader = MockRawIO()
+ writer = MockRawIO()
+ writer.close = writer_close
+ pair = _io.BufferedRWPair(reader, writer)
+ err = raises(NameError, pair.close)
+ assert 'writer_non_existing' in str(err.value)
+ assert not pair.closed
+ assert reader.closed
+ assert not writer.closed
+
+ def test_reader_writer_close_error_on_close(self):
+ import _io
+ class MockRawIO(_io._IOBase):
+ def readable(self):
+ return True
+ def writable(self):
+ return True
+ def reader_close():
+ reader_non_existing
+ def writer_close():
+ writer_non_existing
+ reader = MockRawIO()
+ reader.close = reader_close
+ writer = MockRawIO()
+ writer.close = writer_close
+ pair = _io.BufferedRWPair(reader, writer)
+ err = raises(NameError, pair.close)
+ assert 'reader_non_existing' in str(err.value)
+ assert not pair.closed
+ assert not reader.closed
+ assert not writer.closed
+
class AppTestBufferedRandom:
spaceconfig = dict(usemodules=['_io'])
diff --git a/pypy/module/_io/test/test_fileio.py
b/pypy/module/_io/test/test_fileio.py
--- a/pypy/module/_io/test/test_fileio.py
+++ b/pypy/module/_io/test/test_fileio.py
@@ -197,17 +197,13 @@
def test_mode_strings(self):
import _io
import os
- try:
- for modes in [('w', 'wb'), ('wb', 'wb'), ('wb+', 'rb+'),
- ('w+b', 'rb+'), ('a', 'ab'), ('ab', 'ab'),
- ('ab+', 'ab+'), ('a+b', 'ab+'), ('r', 'rb'),
- ('rb', 'rb'), ('rb+', 'rb+'), ('r+b', 'rb+')]:
- # read modes are last so that TESTFN will exist first
- with _io.FileIO(self.tmpfile, modes[0]) as f:
- assert f.mode == modes[1]
- finally:
- if os.path.exists(self.tmpfile):
- os.unlink(self.tmpfile)
+ for modes in [('w', 'wb'), ('wb', 'wb'), ('wb+', 'rb+'),
+ ('w+b', 'rb+'), ('a', 'ab'), ('ab', 'ab'),
+ ('ab+', 'ab+'), ('a+b', 'ab+'), ('r', 'rb'),
+ ('rb', 'rb'), ('rb+', 'rb+'), ('r+b', 'rb+')]:
+ # read modes are last so that TESTFN will exist first
+ with _io.FileIO(self.tmpfile, modes[0]) as f:
+ assert f.mode == modes[1]
def test_flush_error_on_close(self):
# Test that the file is closed despite failed flush
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit