0

I'm trying to migrate a python 2 project to be python 3 compatible, and got hung up when it was harder than expected to replace a StringIO.StringIO with io.BytesIO. After a lot of debugging I think the problem comes down to this difference in behaviors:

Using StringIO.StringIO:

>>> sys.executable
'/Users/michael/.pyenv/versions/2.7.17/bin/python'
>>> s = StringIO.StringIO()
>>> s.truncate(0)
>>> s.write('a')
>>> s.flush()
>>> s.seek(0)
>>> s.read()
'a'
>>> s.truncate(0)
>>> s.write('a')
>>> s.flush()
>>> s.seek(0)
>>> s.read()
'a'

Using io.BytesIO:

>>> sys.executable
'/Users/michael/.pyenv/versions/2.7.17/bin/python'
>>> b = io.BytesIO()
>>> b.truncate(0)
0L
>>> b.write('a')
1L
>>> b.flush()
>>> b.seek(0)
0L
>>> b.read()
'a'
>>> b.truncate(0)
0L
>>> b.write('a')
1L
>>> b.flush()
>>> b.seek(0)
0L
>>> b.read()
'\x00a'

So you can see the second time through, truncating and flushing the buffer the io.BytesIO object gets a null byte at the beginning, but the StringIO.StringIO one does not.

In Python 3.5.8 I can't use StringIO.StringIO, but in io.BytesIO the behavior is the same (noting I explicitly write b'a').

What causes this null byte to be prepended when I try to continually overwrite an io.BytesIO instance, but not when I use StringIO.StringIO?

kojiro
  • 74,557
  • 19
  • 143
  • 201
  • 1
    Does this answer your question? [Why does truncating a BytesIO mess it up?](https://stackoverflow.com/questions/39109068/why-does-truncating-a-bytesio-mess-it-up) – metatoaster Nov 18 '19 at 05:47
  • I think it does, thanks. It’s interesting that truncate does implicitly seek in the old StringIO, but not in the new one. I’ll explore a bit more. – kojiro Nov 18 '19 at 05:53

0 Answers0