Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it only possible to `seek` from the beginning of a text file?

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 with seek(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.

like image 854
zvone Avatar asked Oct 28 '25 19:10

zvone


1 Answers

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.

like image 91
chepner Avatar answered Oct 31 '25 09:10

chepner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!