implement a detach() method for BufferedIOBase and TextIOBase #5883
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index e580366..e3e7c3d 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -642,6 +642,15 @@
"""
self._unsupported("write")
+ def detach(self) -> None:
+ """
+ Separate the underlying raw stream from the buffer and return it.
+
+ After the raw stream has been detached, the buffer is in an unusable
+ state.
+ """
+ self._unsupported("detach")
+
io.BufferedIOBase.register(BufferedIOBase)
@@ -689,13 +698,21 @@
self.raw.flush()
def close(self):
- if not self.closed:
+ if not self.closed and self.raw is not None:
try:
self.flush()
except IOError:
pass # If flush() fails, just give up
self.raw.close()
+ def detach(self):
+ if self.raw is None:
+ raise ValueError("raw stream already detached")
+ self.flush()
+ raw = self.raw
+ self.raw = None
+ return raw
+
### Inquiries ###
def seekable(self):
@@ -1236,6 +1253,15 @@
"""
self._unsupported("readline")
+ def detach(self) -> None:
+ """
+ Separate the underlying buffer from the TextIOBase and return it.
+
+ After the underlying buffer has been detached, the TextIO is in an
+ unusable state.
+ """
+ self._unsupported("detach")
+
@property
def encoding(self):
"""Subclasses should override."""
@@ -1448,11 +1474,12 @@
self._telling = self._seekable
def close(self):
- try:
- self.flush()
- except IOError:
- pass # If flush() fails, just give up
- self.buffer.close()
+ if self.buffer is not None:
+ try:
+ self.flush()
+ except IOError:
+ pass # If flush() fails, just give up
+ self.buffer.close()
@property
def closed(self):
@@ -1647,6 +1674,14 @@
self.seek(pos)
return self.buffer.truncate()
+ def detach(self):
+ if self.buffer is None:
+ raise ValueError("buffer is already detached")
+ self.flush()
+ buffer = self.buffer
+ self.buffer = None
+ return buffer
+
def seek(self, cookie, whence=0):
if self.closed:
raise ValueError("tell on closed file")
@@ -1865,3 +1900,7 @@
@property
def encoding(self):
return None
+
+ def detach(self):
+ # This doesn't make sense on StringIO.
+ self._unsupported("detach")