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.