Repository navigation
Docs and docstrings for io.*.seek are inconsistent #107801
Copy link
Copy link
Closed
Labels
3.11only security fixesonly security fixes3.12only security fixesonly security fixes3.13only security fixesonly security fixesdocsDocumentation in the Doc dirDocumentation in the Doc dirtopic-IOtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Documentation
The documentation on text handles is misleading, in particular for the seek method.
Steps to reproduce
handle = open('/tmp/lines.txt')
help(handle.seek)
This produces the following documentation:
Help on built-in function seek:
seek(cookie, whence=0, /) method of _io.TextIOWrapper instance
Change stream position.
Change the stream position to the given byte offset. The offset is
interpreted relative to the position indicated by whence. Values
for whence are:
* 0 -- start of stream (the default); offset should be zero or positive
* 1 -- current stream position; offset may be negative
* 2 -- end of stream; offset is usually negative
Return the new absolute position.
Issues
- The documentation talks about a byte offset, but the interface mentions a cookie.
- The constants defined in
osmodule, likeos.SEEK_ENDare not mentioned. - whence=2 with negative offset fails.
Generally, the behaviour is very inconsistent, seek relative to the end fail, seek relative to the start works, but might yield a situation when read fails.
Full investigation of the issue
Linked PRs
- gh-107801: Improve io.*.seek docs and docstrings #107899
- gh-107801: Improve the accuracy of io.TextIOWrapper.seek docs #107933
- gh-107801: Improve the accuracy of os.lseek docs #107935
- gh-107801: Document SEEK_HOLE and SEEK_DATA #107936
- [3.12] gh-107801: Document SEEK_HOLE and SEEK_DATA (GH-107936) #108086
- [3.11] gh-107801: Document SEEK_HOLE and SEEK_DATA (GH-107936) #108087
- gh-107801: Improve the docs of the SEEK_* constants #108099
- [3.11] gh-107801: Improve the docs of the SEEK_* constants (GH-108099) #108100
- [3.12] gh-107801: Improve the docs of the SEEK_* constants (#108099) #108108
- [3.12] gh-107801: Improve the accuracy of os.lseek docs (#107935) #108136
- [3.11] gh-107801: Improve the accuracy of os.lseek docs (#107935) #108137
- [3.12] gh-107801: Improve the accuracy of io.TextIOWrapper.seek docs (#107933) #108262
- [3.11] gh-107801: Improve the accuracy of io.TextIOWrapper.seek docs (#107933) #108264
- gh-107801: Document io.TextIOWrapper.tell #108265
- gh-107801: Improve the accuracy of io.IOBase.seek docs #108268
- [3.12] gh-107801: Document io.TextIOWrapper.tell (#108265) #108547
- [3.11] gh-107801: Document io.TextIOWrapper.tell (#108265) #108548
- [3.12] gh-107801: Improve the accuracy of io.IOBase.seek docs (#108268) #108655
- [3.11] gh-107801: Improve the accuracy of io.IOBase.seek docs (#108268) #108656
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
3.11only security fixesonly security fixes3.12only security fixesonly security fixes3.13only security fixesonly security fixesdocsDocumentation in the Doc dirDocumentation in the Doc dirtopic-IOtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Activity
sunmy2019 commentedon Aug 10, 2023
Note: If anything is changed here, the relevant doc should also be changed.
https://docs.python.org/3/library/io.html#io.IOBase.seek
AA-Turner commentedon Aug 12, 2023
@MatthiasWiesmann would you have time to write a PR with suggestied revisions of the help text?
To note, Python 3.12 will include the constants in
os(see #104418), though there is quite a bit of inconsistency between the variousseek()methods' docstrings:cpython/Modules/_io/iobase.c
Lines 82 to 99 in 2e27da1
cpython/Modules/_io/bufferedio.c
Lines 1285 to 1290 in 2e27da1
cpython/Modules/_io/bytesio.c
Lines 637 to 650 in 2e27da1
cpython/Modules/_io/fileio.c
Lines 954 to 969 in 2e27da1
cpython/Modules/_io/stringio.c
Lines 464 to 477 in 2e27da1
cpython/Modules/_io/textio.c
Lines 2428 to 2433 in 2e27da1
cc @erlend-aasland as the author of #104418 if you have any thoughts.
A
pythongh-107801: Improve io.*.seek docs and docstrings
erlend-aasland commentedon Aug 13, 2023
I agree that it is confusing that the parameter names for the low-level API
seek()aren't used consistently throughout the docs/docstrings. Luckily, these are all positional-only, so we can easily normalise them without backwards compatibility concerns.Suggested improvements:
seek()paramsio.SEEK_*constants instead ofos.SEEK_*io.SEEK_constantsserhiy-storchaka commentedon Aug 14, 2023
TextIOWrapper.seek()has no docstring, so pydoc shows a docstring from a parent class, which is inadequate due to significant difference in semantic.TextIOWrapper.seek()is not a byte offset, and not an offset at all. It is a "cookie", i.e. zero or an opaque number returned bytell(). Passing anything other than zero and the value returned bytell()whenwhence=SEEK_SEThas undefined behavior.Neither forward seeking nor backward seeking are supported. The only supported are rewinding to the start and restoring the previous position saved by
tell(). Confusion could be avoided ifTextIOWrapper.tell()returned a special type instead of integer, but for now it would be a large breaking change (because the cookie can be saved in a file as an integer and used in other process).erlend-aasland commentedon Aug 14, 2023
As a data point: on macOS, Linux, and FreeBSD, the
lseekandfseekmanpages uses offset and whence as parameter names.serhiy-storchaka commentedon Aug 14, 2023
Because they only work with binary files. They do not work with TextIOWrapper which support multibyte stateful codecs.
erlend-aasland commentedon Aug 14, 2023
There are a lot of tasks here. Suggesting to proceed in this order:
os.lseek. Rationale: theSEEK_*constants are also used for this function. If theSEEK_*constants are to talk about the whence parameter, we should use it foros.lseekas well.os.SEEK_SET,os.SEEK_CURandos.SEEK_END; explain that they are used for the whence parameter ofos.lseekand of theseek()method of file objects; add a very short description to each constant.os.SEEK_HOLEandos.SEEK_DATA(exposed inosthoughposix)_io.*.seek()params where it makes sense.seek()methods (Doc/library/io.rst)seek()methods35 remaining items
[3.11] pythongh-107801: Document io.TextIOWrapper.tell (python#108265)
[3.11] gh-107801: Document io.TextIOWrapper.tell (#108265) (#108548)
[3.12] gh-107801: Document io.TextIOWrapper.tell (#108265) (#108547)
gh-107801: Improve the accuracy of io.IOBase.seek docs (#108268)
[3.12] pythongh-107801: Improve the accuracy of io.IOBase.seek docs (p…
[3.11] pythongh-107801: Improve the accuracy of io.IOBase.seek docs (p…
[3.11] gh-107801: Improve the accuracy of io.IOBase.seek docs (#108268)…
[3.12] gh-107801: Improve the accuracy of io.IOBase.seek docs (#108268)…
Merge branch 'main' into icompexc
hugovk commentedon Nov 9, 2023
Lots of merged PRs here. 🚀
Anything still to do, or can the issue be closed?
vadmium commentedon Jul 26, 2024
Issue #82969 is open about IOBase.seek/tell vs TextIOWrapper and the offset/cookie parameter
Issue #122299 is about the byte vs character seek offsets
picnixz commentedon Dec 2, 2024
I'll close this issue as
completedsince #82969 was closed and #122299 is likely to be closed as well IMO. We can always add more docs if needed and use that issue as a tracker.