Author: Amaury Forgeot d'Arc <amaur...@gmail.com> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit