Mailing List Archive

[issue37635] Using constant for whence arg in seek()
New submission from Kyle Stanley <aeros167@gmail.com>:

In Python 3.1, three constants were added to the IO module to be used for the whence argument of seek():

SEEK_SET or 0 – start of the stream
SEEK_CUR or 1 – current stream position
SEEK_END or 2 – end of the stream

However, there are at least 102 occurrences across CPython where the integer values are used instead. This only includes instances when a value for the whence arg is explicitly specified. All of the occurrences can be easily found with the usage of git grep:

git grep -E "seek\(-?[0-9]+, [0-2]\)"

This doesn't affect functionality in any way, but it would result in significant readability improvement if these were all replaced with constants. The only requirement would be importing IO or manually specifying the value of constants.

For simplicity, I would probably start with anything that directly involves IO. The largest number of occurrences are in Lib/test/test_io, so that probably would be the best place to begin. Also, this module already imports io anyways, so it would be a straightforward find and replace.

It would also be quite useful to make this change in the documentation, in Doc/tutorial/inputoutput there are 4 occurrences. If anything, anyone less familiar with the IO module in general would be the most likely to benefit from this change so modifying the tutorial would likely be the most useful change for the majority of users.

As a single example of what I'm talking about, here's line 334 of Lib/test/test_io:

self.assertEqual(f.seek(-1, 1), 5)

I would propose changing it to:

self.assertEqual(f.seek(-1, io.SEEK_CUR), 5)

----------
components: IO
messages: 348207
nosy: aeros167, benjamin.peterson, stutzbach
priority: normal
severity: normal
status: open
title: Using constant for whence arg in seek()
type: enhancement
versions: Python 3.9

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37635>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37635] Using constant for whence arg in seek() [ In reply to ]
Change by Kyle Stanley <aeros167@gmail.com>:


----------
assignee: -> docs@python
components: +Documentation, Tests
nosy: +docs@python

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37635>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37635] Using constant for whence arg in seek() [ In reply to ]
Raymond Hettinger <raymond.hettinger@gmail.com> added the comment:

I think it's okay to leave these as 0, 1, 2 because they have a long and well known tradition across multiple languages. The named versions are just alternatives available for end-users. The numbered forms also let us avoid a bunch of otherwise unnecessary imports (which affect start-up time and occasionally create load order bootstrapping issues).

Antoine, what do you think?

----------
nosy: +pitrou, rhettinger

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37635>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37635] Using constant for whence arg in seek() [ In reply to ]
Kyle Stanley <aeros167@gmail.com> added the comment:

>The named versions are just alternatives available for end-users

While it is true that the usage of 0,1,2 is more commonly used across the repository, the constants are used several times across Lib/_compression.py and Lib/_pyio.py. From my perspective, it looks like the locations which already used the integer values were just not updated rather than it being an intentional design decision.

However, if it is primarily targeted at the end-users, I would still recommend at least updating the tutorial and perhaps other IO documentation to use the constants. To any user unfamiliar with the integers, the constants convey their purpose far more explicitly, and I don't think anyone familiar with the integers would be confused by the constants.

>The numbered forms also let us avoid a bunch of otherwise unnecessary imports (which affect >start-up time and occasionally create load order bootstrapping issues).

I can definitely understand this argument for anything that doesn't already import IO. It probably wouldn't be worthwhile to increase start times and introduce load order bugs.

But for anything that already imports IO anyways, this seems like it would only serve to be a readability improvement without causing any change in functionality. This might not make a difference at all to developers who are used to using 0,1,2, but their purpose is not inherently obvious to anyone that isn't.

This change would be in alignment with "Explicit is better than implicit". The purpose of the integers is defined only by implication based on tradition, whereas the constants explicitly define the purpose of the argument.

A major advantage of Python over many existing languages is the emphasis on providing maximum readability. Sometimes functionality should be prioritized, such as in places where IO is not already imported. But in cases where there is no functionality cost, readability should be the priority. Even for non-public sections such as the tests, improved readability leads to easier maintenance and incorporation of new Python developers.

----------

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37635>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37635] Using constant for whence arg in seek() [ In reply to ]
Raymond Hettinger <raymond.hettinger@gmail.com> added the comment:

This is Antoine's call. I believe he made the original decision not to sweep through the standard library, changing it everywhere it occurred. Perhaps this was performance reasons, perhaps the existing code was already clear enough, perhaps the value-add was too low. For me personally, it is easier to remember 0 than the name of the constant.

----------
assignee: docs@python -> pitrou

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37635>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37635] Using constant for whence arg in seek() [ In reply to ]
Antoine Pitrou <pitrou@free.fr> added the comment:

I would agree with changing the tutorial. The rest doesn't need to be changed.

----------

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37635>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37635] Using constant for whence arg in seek() [ In reply to ]
Serhiy Storchaka <storchaka+cpython@gmail.com> added the comment:

AFAIK there is an open PR which sweeps through the standard library, changing seek() everywhere to use named constants.

----------
nosy: +serhiy.storchaka

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37635>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37635] Using constant for whence arg in seek() [ In reply to ]
Kyle Stanley <aeros167@gmail.com> added the comment:

> I would agree with changing the tutorial. The rest doesn't need to be changed.

Fair enough, that's understandable. I'll look into creating a PR for the tutorial to attach to this issue. Thanks for the feedback Antoine and Raymond.

>AFAIK there is an open PR which sweeps through the standard library, changing seek() >everywhere to use named constants.

Even I would disagree with doing it through all of stdlib, especially with the current feedback. I was primarily advocating for using the constants in places where the io module was already being imported, since in that case, it wouldn't result in any additional overhead. Replacing it everywhere would require a significant number of additional io imports.

----------

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37635>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37635] Using constant for whence arg in seek() [ In reply to ]
Kyle Stanley <aeros167@gmail.com> added the comment:

Upon further consideration, I think that it would be best to leave the code examples as is in the "inputoutput" tutorial, but it still be worth mentioning that the constants exist as alternatives. This is due to adding the additional step of "import io" in order to be able to access the constants. The tutorial code examples should probably aim to not add additional extra lines that are not needed.

While I was working on a PR for updating the tutorial, I noticed that the second argument's name for seek() was *from_what* instead of *whence*. Was this an older name for the argument that is now outdated or am I missing something?

Doc/tutorial: https://github.com/python/cpython/blob/master/Doc/tutorial/inputoutput.rst#methods-of-file-objects

Doc/library: https://docs.python.org/3/library/io.html#io.IOBase.seek

----------

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37635>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37635] Using constant for whence arg in seek() [ In reply to ]
Antoine Pitrou <pitrou@free.fr> added the comment:

I don't know. "whence" is the official name of the argument in the POSIX API:
https://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html

Perhaps "from_what" is assumed to be more understandable by the average reader?

Also, os.lseek() uses "how":
https://docs.python.org/3/library/os.html#os.lseek

----------

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37635>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37635] Using constant for whence arg in seek() [ In reply to ]
Kyle Stanley <aeros167@gmail.com> added the comment:

> I don't know. "whence" is the official name of the argument in the POSIX API

> Perhaps "from_what" is assumed to be more understandable by the average reader?

>From looking at the blame on GitHub, it looks like the use of the "from_what" argument in the tutorial has been there for more than 12 years, since the last commit was a massive move of the doc tree. The documentation for the IO module was added exactly 12 years (which included the usage of the *whence* argument rather than *from_what*) ago by birkenfield. Based on that information, I think the most likely answer is that the argument used to be *from_what* in a much older version of Python. To conform to the posix standard, it was changed to *whence*, but the tutorial was never updated.

If it was simply never updated, I think that it would be better to change it to *whence*. The difference would be more likely to confuse new users of the language, if they were to start with the tutorial and later refer to the IO module documentation.

Also the tutorial provides a fairly in-depth explanation of the purpose of the argument within seek(), so I don't think using "from_what" as the name makes its purpose any more clear to the users.

----------

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37635>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com
[issue37635] Using constant for whence arg in seek() [ In reply to ]
Kyle Stanley <aeros167@gmail.com> added the comment:

Clarification: By "latest commit" should be "oldest commit" with regards to the oldest commit in GitHub's history of the section of the "inputouput" tutorial that used the *from_what* argument for seek().

----------

_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue37635>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com