Reputation: 19352
Python documentation says:
In text files (those opened without a
b
in the mode string), only seeks relative to the beginning of the file are allowed (the exception being seeking to the very file end withseek(0, 2)
).
And indeed, this fails:
with open(filename, 'rt') as f:
f.seek(2, os.SEEK_SET)
f.seek(2, os.SEEK_CUR)
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
io.UnsupportedOperation: can't do nonzero cur-relative seeks
The Question
I can easily replace every f.seek(offset, os.SEEK_CUR)
with f.seek(f.tell() + offset, os.SEEK_SET)
, so, why doesn't Python do it itself?
This works:
with open(filename, 'rt') as f:
f.seek(2, os.SEEK_SET)
f.seek(f.tell() + 2, os.SEEK_SET)
Am I missing something? Will this fail sometimes? What should I be careful about?
I can imagine problems with seeking into the middle of a multi-byte UTF-8 sequence, but I don't see how it makes a difference whether I seek from SEEK_SET
or SEEK_CUR
.
Upvotes: 4
Views: 818
Reputation: 531075
I suspect f.seek(f.tell() + 2, os.SEEK_SET)
is only allowed because the implementation cannot distinguish this from f.seek(f.tell(), os.SEEK_SET)
. From the documentation for seek
:
SEEK_SET or 0: seek from the start of the stream (the default); offset must either be a number returned by TextIOBase.tell(), or zero. Any other offset value produces undefined behaviour.
Since f.tell() + 2
isn't a value returned by f.tell()
, that's undefined behavior, because you aren't supposed to know what the return value of f.tell()
represents, and so adding 2 to it isn't meaningful.
The idea is that the only seeks allowed are to absolute positions you saved from previous calls to f.tell()
, not arbitrarily calculated positions.
Upvotes: 3