mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Handle reentrant detach in TextIOWrapper.close() (#7277)
When a custom `closed` property on the underlying buffer calls `detach()` during the `file_closed()` check in `close()`, the wrapper's internal buffer becomes None. Subsequent flush/close operations then fail with AttributeError on NoneType. Add a guard after the `file_closed()` check to detect if the buffer was detached reentrantly, and return early in that case (detach has already flushed the stream). This mirrors the fix applied in CPython (https://github.com/python/cpython/issues/142594\).
This commit is contained in:
1 parent
bef46f17d5
commit
be39a67f27
2 files changed
+7
-1
No files matched your search
Vendored
-1
@@ -4211,7 +4211,6 @@ class CTextIOWrapperTest(TextIOWrapperTest):
|
||||
self.assertEqual([b"abcdef", b"middle", b"g"*chunk_size],
|
||||
buf._write_stack)
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: 'NoneType' object has no attribute 'closed'
|
||||
def test_issue142594(self):
|
||||
wrapper = None
|
||||
detached = False
|
||||
|
||||
@@ -3793,6 +3793,13 @@ mod _io {
|
||||
if file_closed(&buffer, vm)? {
|
||||
return Ok(());
|
||||
}
|
||||
// https://github.com/python/cpython/issues/142594
|
||||
// The file_closed() check above may have triggered a reentrant
|
||||
// call to detach() via a custom `closed` property.
|
||||
// If so, the buffer is now detached and we should return early.
|
||||
if vm.is_none(&zelf.lock(vm)?.buffer) {
|
||||
return Ok(());
|
||||
}
|
||||
if zelf.finalizing.load(Ordering::Relaxed) {
|
||||
// _dealloc_warn: delegate to buffer._dealloc_warn(source)
|
||||
let _ = vm.call_method(&buffer, "_dealloc_warn", (zelf.as_object().to_owned(),));
|
||||
|
||||
Reference in new issue
Block a user