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 anio
Buffer (StringIO
orBytesIO
), until it rolls over and creates a "file-like object" viatempfile.TemporaryFile()
(for example, whenmax_size
is exceeded).io.TextIOWrapper
requires aBufferedIOBase
base class/interface, which is provided byio.StringIO
andio.BytesIO
, but not necessarily by the object returned byTemporaryFile()
(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.