classification
Title: StringIO and seek()
Type: behavior Stage: resolved
Components: Documentation, IO, Library (Lib) Versions: Python 3.2, Python 3.3, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: docs@python, martin.panter, pitrou, python-dev, quentel, terry.reedy
Priority: normal Keywords:

Created on 2011-09-06 20:48 by terry.reedy, last changed 2015-09-20 06:17 by martin.panter. This issue is now closed.

Messages (4)
msg143649 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2011-09-06 20:48
First, there is a minor documentation issue.
15.2.3.1. I/O Base Classes
class io.IOBase
seek(offset, whence=SEEK_SET) 
Change the stream position to the given byte offset

Since StringIO seeks by code units that should perhaps say 'byte or code unit offset' or a separate note should be added to the doc entry for StringIO.

>>> txt = StringIO('ab\U00010030')
>>> txt.seek(3)
3
>>> txt.write('x')
1
>>> txt.getvalue()
'ab\ud800x'

The behavior problem is that seeking for StringIO does not work relative to the current position or end.

IOError: Can't do nonzero cur-relative seeks
# Note: this message is wrong for end-relative seeks.

I presume this is inherited from an undocumented restriction on seeking with text streams, because chars *might* be variably sized. However, I do not think it should be. StringIO does not inherit the same reason for the restriction (certainly not on wide builds, and on narrow builds, seeking from the beginning is just as problematical). For StringIO, there is no option of 'opening in binary (byte) mode instead' as there is for disk files. Since a StringIO object is a wrapped array of fixed-size units, seeking from any position is as trivial as it is from the beginning. And again, the current docs imply that it should work.

Note that seeking from the beginning is not limited to the existing content. Instead, skipped areas are filled with nulls.

from io import StringIO
txt = StringIO('0123456789')
txt.seek(15,0) # no problem with absolute seek
txt.write('xxx')
s  = txt.getvalue()
print(ord(s[12]))
# 0

So that is not a reason to limit seeking from other positions either.
msg150078 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011-12-22 07:50
I would rather document it in TextIOBase:
http://docs.python.org/dev/library/io.html#io.TextIOBase

With text I/O streams, tell() returns an arbitrary "position cookie", meaning you can't meaningfully do arithmetic on it: this is why cur-relative seeking and end-relative seeking isn't supported.

Of course, on StringIO the "arbitrary position cookie" is a perfectly well-defined character offset, so we *could* specifically enhance StringIO.tell. Whether it's a good idea to do it (while arbitrary text files would still have the limitation) is left to debate.
msg151741 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2012-01-21 19:30
New changeset 03e61104f7a2 by Antoine Pitrou in branch '3.2':
Issue #12922: fix the TextIOBase documentation to include a description of seek() and tell() methods.
http://hg.python.org/cpython/rev/03e61104f7a2

New changeset f7e5abfb31ea by Antoine Pitrou in branch 'default':
Issue #12922: fix the TextIOBase documentation to include a description of seek() and tell() methods.
http://hg.python.org/cpython/rev/f7e5abfb31ea

New changeset fcf4d547bed8 by Antoine Pitrou in branch '2.7':
Issue #12922: fix the TextIOBase documentation to include a description of seek() and tell() methods.
http://hg.python.org/cpython/rev/fcf4d547bed8
msg251150 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2015-09-20 06:17
Opened Issue 25190 about the enhancing StringIO side of this.
History
Date User Action Args
2015-09-20 06:17:30martin.pantersetmessages: + msg251150
2012-01-21 19:30:32pitrousetstatus: open -> closed
resolution: fixed
stage: needs patch -> resolved
2012-01-21 19:30:15python-devsetnosy: + python-dev
messages: + msg151741
2011-12-22 07:50:23pitrousetassignee: docs@python
type: enhancement -> behavior
components: + Documentation
versions: + Python 2.7
nosy: + docs@python, pitrou

messages: + msg150078
2011-12-22 06:23:22martin.pantersetnosy: + martin.panter
2011-09-07 14:46:49pitrousettype: behavior -> enhancement
components: + IO
stage: test needed -> needs patch
2011-09-07 14:01:16quentelsetnosy: + quentel
2011-09-06 20:48:49terry.reedycreate