Python's StringIO doesn't do well with `with` statements
Asked Answered
A

2

19

I need to stub tempfile and StringIO seemed perfect. Only that all this fails in an omission:

In [1]: from StringIO import StringIO
In [2]: with StringIO("foo") as f: f.read()

--> AttributeError: StringIO instance has no attribute '__exit__'

What's the usual way to provide canned info instead of reading files with nondeterministic content?

Afloat answered 19/8, 2012 at 17:50 Comment(0)
S
35

The StringIO module predates the with statement. Since StringIO has been removed in Python 3 anyways, you can just use its replacement, io.BytesIO:

>>> import io
>>> with io.BytesIO(b"foo") as f: f.read()
b'foo'
Segmental answered 19/8, 2012 at 17:58 Comment(2)
Note that the io module is pure-python in Python 2.6, while Python 2.7 uses Python 3.1's fast C implementation. So for Python 2.6 only, using io.BytesIO will result in a performance penalty.Grahamgrahame
not removed, from What’s New In Python 3.0: The StringIO and cStringIO modules are gone. Instead, import the io module and use io.StringIO or io.BytesIO for text and data respectively.Ambrogino
A
3

this monkeypatch works for me in python2. call monkeypatch in your initialization routine.

import logging
from StringIO import StringIO
logging.basicConfig(level=logging.DEBUG if __debug__ else logging.INFO)

def debug(*args):
    logging.debug('args: %s', args)
    return args[0]

def monkeypatch():
    '''
    allow StringIO to use `with` statement
    '''
    StringIO.__exit__ = debug
    StringIO.__enter__ = debug

if __name__ == '__main__':
    monkeypatch()
    with StringIO("this is a test") as infile:
        print infile.read()

test run:

jcomeau@aspire:~/stackoverflow/12028637$ python test.py 
DEBUG:root:args: (<StringIO.StringIO instance at 0xf73e76ec>,)
this is a test
DEBUG:root:args: (<StringIO.StringIO instance at 0xf73e76ec>, None, None, None)
jcomeau@aspire:~/stackoverflow/12028637$
Abhenry answered 5/9, 2016 at 20:38 Comment(1)
Note that this only works for the pure python version, not the cStringIO version, so it's no help for getting fast StringIO to play nice with with in 2.7Sissified

© 2022 - 2024 — McMap. All rights reserved.