summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-06-12 22:23:49 (GMT)
committerGitHub <noreply@github.com>2019-06-12 22:23:49 (GMT)
commitc15a682603a47f5aef5025f6a2e3babb699273d6 (patch)
tree52b09a312a7aef518512575f2d05bdd2ef022a3f
parent3955dfff600dc8568e71ca19a48c72555043081f (diff)
downloadcpython-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.py10
-rw-r--r--Lib/test/test_io.py15
-rw-r--r--Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst2
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.