isatty() is a system call on linux. Most open()s are files, and we're already getting the size of the file. If it has a size, then we know it's not a atty, and can avoid calling it.
This is because the result of isatty() is not constant during the lifetime of the file object. The file descriptor can be reassigned to other file or device, so it should not be cached.
#29870 uses the cached value only in open(), immediately after creating the FileIO object, so it is not affected by this. But it is more complex, and making it more portable will make it even more complex. How much time it saves?
I think it's okay to rely on the fd not being modified inside of open() which is what #121593 does. It doesn't cache isatty generally (any future call still does a isatty libc call), just says "we can skip this call/check during open if we already have enough information from stat that the fd isn't a TTY".
Activity
collinanderson commented on Dec 1, 2021
isatty() is a system call on linux. Most open()s are files, and we're already getting the size of the file. If it has a size, then we know it's not a atty, and can avoid calling it.
17 remaining items
serhiy-storchaka commented on Dec 14, 2023
One test fails with #112495 if the stdin is not a terminal. For example:
$ ./python -m test -v test_builtin -m test_input_no_stdout_fileno <python ... test test_builtin failed -- Traceback (most recent call last): File "/home/serhiy/py/cpython/Lib/test/test_builtin.py", line 2393, in test_input_no_stdout_fileno self.assertSequenceEqual(lines, expected) ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^ AssertionError: Sequences differ: ['stdin.isatty(): False', "captured: 'prompt'"] != ('stdin.isatty(): True', "captured: 'prompt'") First differing element 0: 'stdin.isatty(): False' 'stdin.isatty(): True' - ['stdin.isatty(): False', "captured: 'prompt'"] ? ^ ^^^^ ^ + ('stdin.isatty(): True', "captured: 'prompt'") ? ^ ^^^ ^This is because the result of isatty() is not constant during the lifetime of the file object. The file descriptor can be reassigned to other file or device, so it should not be cached.
#29870 uses the cached value only in open(), immediately after creating the FileIO object, so it is not affected by this. But it is more complex, and making it more portable will make it even more complex. How much time it saves?
vstinner commented on Jul 11, 2024
PR gh-112495 was closed. @serhiy-storchaka wrote:
Should we close the issue?
cmaloney commented on Aug 25, 2024
I think it's okay to rely on the fd not being modified inside of open() which is what #121593 does. It doesn't cache isatty generally (any future call still does a isatty libc call), just says "we can skip this call/check during open if we already have enough information from stat that the fd isn't a TTY".
pythongh-90102: Shortcut isatty in _pyio open()
pythongh-90102: Shortcut isatty in _io open()
pythongh-90102: Shortcut isatty in _pyio open()
pythongh-90102: Shortcut isatty in _io open()
gh-90102: Remove isatty call during regular open (#124922)
pythongh-90102: Fix pyio return value
gh-90102: Fix pyio _isatty_open_only() (#125089)
vstinner commented on Oct 8, 2024
Optimization implemented by change cc9b9be.
Update to validate pythongh-90102 changes
pythongh-90102: Remove isatty call during regular open (python#124922)
pythongh-90102: Fix pyio _isatty_open_only() (python#125089)