diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-06-12 22:23:49 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-12 22:23:49 (GMT) |
commit | c15a682603a47f5aef5025f6a2e3babb699273d6 (patch) | |
tree | 52b09a312a7aef518512575f2d05bdd2ef022a3f | |
parent | 3955dfff600dc8568e71ca19a48c72555043081f (diff) | |
download | cpython-c15a682603a47f5aef5025f6a2e3babb699273d6.zip cpython-c15a682603a47f5aef5025f6a2e3babb699273d6.tar.gz cpython-c15a682603a47f5aef5025f6a2e3babb699273d6.tar.bz2 |
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 4f6f7c5a611905fb6b81671547f268c226bc646a)
* bpo-37223: test_io: silence destructor errors (GH-13954)
Implement also MockNonBlockWriterIO.seek() method.
(cherry picked from commit b589cef9c4dada2fb84ce0fae5040ecf16d9d5ef)
* 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 913fa1c8245d1cde6edb4254f4fb965cc91786ef)
-rw-r--r-- | Lib/_pyio.py | 10 | ||||
-rw-r--r-- | Lib/test/test_io.py | 15 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst | 2 |
3 files changed, 27 insertions, 0 deletions
diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 43c2434..0b6493b 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -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: diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 3a1f5ba..55686d7 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -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(): diff --git a/Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst b/Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst new file mode 100644 index 0000000..295ddeb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst @@ -0,0 +1,2 @@ +:class:`_pyio.IOBase` destructor now does nothing if getting the ``closed`` +attribute fails to better mimick :class:`_io.IOBase` finalizer. |