gh-138720: Make Buffered closed check match flush (GH-138724)
In `_io__Buffered_flush_impl` the macro `CHECK_CLOSED` is used to check the `buffered*` is in a good state to be flushed. That differs slightly from `buffered_closed`. In some cases, that difference would result in `close()` thinking the file needed to be flushed and closed while `flush()` thought the file was already closed. This could happen during GC and would result in an unraisable exception.
This commit is contained in:
@@ -1980,6 +1980,10 @@ class BufferedRWPairTest:
|
|||||||
self.assertEqual(getattr(pair, method)(data), 5)
|
self.assertEqual(getattr(pair, method)(data), 5)
|
||||||
self.assertEqual(bytes(data), b"abcde")
|
self.assertEqual(bytes(data), b"abcde")
|
||||||
|
|
||||||
|
# gh-138720: C BufferedRWPair would destruct in a bad order resulting in
|
||||||
|
# an unraisable exception.
|
||||||
|
support.gc_collect()
|
||||||
|
|
||||||
def test_write(self):
|
def test_write(self):
|
||||||
w = self.MockRawIO()
|
w = self.MockRawIO()
|
||||||
pair = self.tp(self.MockRawIO(), w)
|
pair = self.tp(self.MockRawIO(), w)
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Fix an issue where :class:`io.BufferedWriter` and :class:`io.BufferedRandom`
|
||||||
|
had different definitions of "closed" for :meth:`~io.IOBase.close` and
|
||||||
|
:meth:`~io.IOBase.flush` which resulted in an exception when close called
|
||||||
|
flush but flush thought the file was already closed.
|
||||||
@@ -553,8 +553,8 @@ _io__Buffered_close_impl(buffered *self)
|
|||||||
if (!ENTER_BUFFERED(self)) {
|
if (!ENTER_BUFFERED(self)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
/* gh-138720: Use IS_CLOSED to match flush CHECK_CLOSED. */
|
||||||
r = buffered_closed(self);
|
r = IS_CLOSED(self);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto end;
|
goto end;
|
||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user