Search code examples
pythonstreamstringio

Python StringIO.write doesn't like integer zero?


Why can stream.write output pretty much anything other than zero?

from StringIO import StringIO
v0 = 0
v1 = 1
a = [1, 0, v1, v0, "string", 0.0, 2.0]
stream = StringIO()
for v in a:
    stream.write(v)
    stream.write('\n')
print stream.getvalue()

With Python 2.7.6, running this code produces:

1

1

string

2.0

Solution

  • The interface for fileobj.write() requires that you write a string, always:

    file.write(str)
    Write a string to the file.

    Emphasis mine.

    It is an implementation detail that for StringIO() non-strings just happen to work. The code optimises the 'empty string' case by using:

    if not s: return
    

    to avoid doing unnecessary string concatenation. This means that if you pass in any falsey value, such as numeric 0 or None or an empty container, writing doesn't take place.

    Convert your objects to a string before writing:

    for v in a:
        stream.write(str(v))
        stream.write('\n')
    

    If you used the C-optimised version here you'd have had an error:

    >>> from cStringIO import StringIO
    >>> f = StringIO()
    >>> f.write(0)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: must be string or buffer, not int