bpo-37223: test_io: silence destructor errors (GH-14031)

* bpo-18748: Fix _pyio.IOBase destructor (closed case) (GH-13952)

_pyio.IOBase destructor now does nothing if getting the closed
attribute fails to better mimick _io.IOBase finalizer.

(cherry picked from commit 4f6f7c5a61)

* bpo-37223: test_io: silence destructor errors (GH-13954)

Implement also MockNonBlockWriterIO.seek() method.

(cherry picked from commit b589cef9c4)

* bpo-37223, test_io: silence last 'Exception ignored in:' (GH-14029)

Use catch_unraisable_exception() to ignore 'Exception ignored in:'
error when the internal BufferedWriter of the BufferedRWPair is
destroyed. The C implementation doesn't give access to the
internal BufferedWriter, so just ignore the warning instead.

(cherry picked from commit 913fa1c824)
This commit is contained in:
Victor Stinner 2019-06-13 00:23:49 +02:00 committed by GitHub
parent 3955dfff60
commit c15a682603
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 0 deletions

View File

@ -405,6 +405,16 @@ class IOBase(metaclass=abc.ABCMeta):
def __del__(self):
"""Destructor. Calls close()."""
try:
closed = self.closed
except Exception:
# If getting closed fails, then the object is probably
# in an unusable state, so ignore.
return
if closed:
return
if _IOBASE_EMITS_UNRAISABLE:
self.close()
else:

View File

@ -277,6 +277,10 @@ class MockNonBlockWriterIO:
def seekable(self):
return True
def seek(self, pos, whence=0):
# naive implementation, enough for tests
return 0
def writable(self):
return True
@ -1486,6 +1490,9 @@ class BufferedReaderTest(unittest.TestCase, CommonBufferedTests):
self.assertRaises(OSError, bufio.seek, 0)
self.assertRaises(OSError, bufio.tell)
# Silence destructor error
bufio.close = lambda: None
def test_no_extraneous_read(self):
# Issue #9550; when the raw IO object has satisfied the read request,
# we should not issue any additional reads, otherwise it may block
@ -1834,6 +1841,9 @@ class BufferedWriterTest(unittest.TestCase, CommonBufferedTests):
self.assertRaises(OSError, bufio.tell)
self.assertRaises(OSError, bufio.write, b"abcdef")
# Silence destructor error
bufio.close = lambda: None
def test_max_buffer_size_removal(self):
with self.assertRaises(TypeError):
self.tp(self.MockRawIO(), 8, 12)
@ -2060,6 +2070,11 @@ class BufferedRWPairTest(unittest.TestCase):
# Silence destructor error
writer.close = lambda: None
writer = None
with support.catch_unraisable_exception():
pair = None
support.gc_collect()
def test_reader_writer_close_error_on_close(self):
def reader_close():

View File

@ -0,0 +1,2 @@
:class:`_pyio.IOBase` destructor now does nothing if getting the ``closed``
attribute fails to better mimick :class:`_io.IOBase` finalizer.