In Python 3.6.1, I've tried wrapping a tempfile.SpooledTemporaryFile in an io.TextIOWrapper:
with tempfile.SpooledTemporaryFile() as tfh:
do_some_download(tfh)
tfh.seek(0)
wrapper = io.TextIOWrapper(tfh, encoding='utf-8')
yield from do_some_text_formatting(wrapper)
The line wrapper = io.TextIOWrapper(tfh, encoding='utf-8')
gives me an error:
AttributeError: 'SpooledTemporaryFile' object has no attribute 'readable'
If I create a simple class like this, I can bypass the error (I get similar errors for writable
and seekable
):
class MySpooledTempfile(tempfile.SpooledTemporaryFile):
@property
def readable(self):
return self._file.readable
@property
def writable(self):
return self._file.writable
@property
def seekable(self):
return self._file.seekable
Is there a good reason why tempfile.SpooledTemporaryFile doesn't already have these attributes?
SpooledTemporaryFile
actually uses 2 different _file
implementations under the hood - initially an io
Buffer (StringIO
or BytesIO
), until it rolls over and creates a "file-like object" via tempfile.TemporaryFile()
(for example, when max_size
is exceeded).
io.TextIOWrapper
requires a BufferedIOBase
base class/interface, which is provided by io.StringIO
and io.BytesIO
, but not necessarily by the object returned by TemporaryFile()
(though in my testing on OSX, TemporaryFile()
returned an _io.BufferedRandom
object, which had the desired interface, my theory is this may depend on platform).
So, I would expect your MySpooledTempfile
wrapper to possibly fail on some platforms after rollover.
This is fixed in python 3.11. Changelog for reference
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With