Skip to content

Commit a356841

Browse files
authored
bpo-37054, _pyio: Fix BytesIO and TextIOWrapper __del__() (GH-13601)
Fix destructor _pyio.BytesIO and _pyio.TextIOWrapper: initialize their _buffer attribute as soon as possible (in the class body), because it's used by __del__() which calls close().
1 parent df9b032 commit a356841

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

Lib/_pyio.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,10 @@ class BytesIO(BufferedIOBase):
873873

874874
"""Buffered I/O implementation using an in-memory bytes buffer."""
875875

876+
# Initialize _buffer as soon as possible since it's used by __del__()
877+
# which calls close()
878+
_buffer = None
879+
876880
def __init__(self, initial_bytes=None):
877881
buf = bytearray()
878882
if initial_bytes is not None:
@@ -900,7 +904,8 @@ def getbuffer(self):
900904
return memoryview(self._buffer)
901905

902906
def close(self):
903-
self._buffer.clear()
907+
if self._buffer is not None:
908+
self._buffer.clear()
904909
super().close()
905910

906911
def read(self, size=-1):
@@ -1970,6 +1975,10 @@ class TextIOWrapper(TextIOBase):
19701975

19711976
_CHUNK_SIZE = 2048
19721977

1978+
# Initialize _buffer as soon as possible since it's used by __del__()
1979+
# which calls close()
1980+
_buffer = None
1981+
19731982
# The write_through argument has no effect here since this
19741983
# implementation always writes through. The argument is present only
19751984
# so that the signature can match the signature of the C version.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix destructor :class:`_pyio.BytesIO` and :class:`_pyio.TextIOWrapper`:
2+
initialize their ``_buffer`` attribute as soon as possible (in the class
3+
body), because it's used by ``__del__()`` which calls ``close()``.

0 commit comments

Comments
 (0)