Author: Amaury Forgeot d'Arc <[email protected]>
Branch: py3.5
Changeset: r91087:0f983f4075de
Date: 2017-04-18 19:03 +0200
http://bitbucket.org/pypy/pypy/changeset/0f983f4075de/
Log: Chain exceptions when close() contains multiple operations that can
fail.
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
@@ -1030,7 +1030,12 @@
raise oefmt(space.w_ValueError,
"I/O operation on uninitialized object")
w_meth = space.getattr(self.w_reader, space.newtext("close"))
- space.call_args(w_meth, __args__)
+ try:
+ space.call_args(w_meth, __args__)
+ except OperationError as e2:
+ if e:
+ e2.chain_exceptions(space, e)
+ e = e2
if e:
raise e
diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py
--- a/pypy/module/_io/interp_textio.py
+++ b/pypy/module/_io/interp_textio.py
@@ -528,13 +528,20 @@
def close_w(self, space):
self._check_attached(space)
- if not space.is_true(space.getattr(self.w_buffer,
- space.newtext("closed"))):
+ if space.is_true(space.getattr(self.w_buffer,
+ space.newtext("closed"))):
+ return
+ try:
+ space.call_method(self, "flush")
+ except OperationError as e:
try:
- space.call_method(self, "flush")
- finally:
ret = space.call_method(self.w_buffer, "close")
- return ret
+ except OperationError as e2:
+ e2.chain_exceptions(space, e)
+ raise
+ else:
+ ret = space.call_method(self.w_buffer, "close")
+ return ret
def _dealloc_warn_w(self, space, w_source):
space.call_method(self.w_buffer, "_dealloc_warn", w_source)
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
@@ -707,6 +707,7 @@
pair = _io.BufferedRWPair(reader, writer)
err = raises(NameError, pair.close)
assert 'reader_non_existing' in str(err.value)
+ assert 'writer_non_existing' in str(err.value.__context__)
assert not pair.closed
assert not reader.closed
assert not writer.closed
diff --git a/pypy/module/_io/test/test_textio.py
b/pypy/module/_io/test/test_textio.py
--- a/pypy/module/_io/test/test_textio.py
+++ b/pypy/module/_io/test/test_textio.py
@@ -365,6 +365,22 @@
raises(IOError, txt.close) # exception not swallowed
assert txt.closed
+ def test_close_error_on_close(self):
+ import _io as io
+ buffer = io.BytesIO(b'testdata')
+ def bad_flush():
+ raise OSError('flush')
+ def bad_close():
+ raise OSError('close')
+ buffer.close = bad_close
+ txt = io.TextIOWrapper(buffer, encoding="ascii")
+ txt.flush = bad_flush
+ err = raises(OSError, txt.close)
+ assert err.value.args == ('close',)
+ assert isinstance(err.value.__context__, OSError)
+ assert err.value.__context__.args == ('flush',)
+ assert not txt.closed
+
def test_illegal_decoder(self):
import _io
raises(LookupError, _io.TextIOWrapper, _io.BytesIO(),
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit