gh-90102: Remove isatty call during regular open (#124922)

Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
Cody Maloney 2024-10-07 23:50:42 -07:00 committed by GitHub
parent 6e3c70c61b
commit cc9b9bebb2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 47 additions and 5 deletions

View file

@ -238,7 +238,7 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None,
result = raw
try:
line_buffering = False
if buffering == 1 or buffering < 0 and raw.isatty():
if buffering == 1 or buffering < 0 and raw._isatty_open_only():
buffering = -1
line_buffering = True
if buffering < 0:
@ -1794,6 +1794,21 @@ class FileIO(RawIOBase):
self._checkClosed()
return os.isatty(self._fd)
def _isatty_open_only(self):
"""Checks whether the file is a TTY using an open-only optimization.
TTYs are always character devices. If the interpreter knows a file is
not a character device when it would call ``isatty``, can skip that
call. Inside ``open()`` there is a fresh stat result that contains that
information. Use the stat result to skip a system call. Outside of that
context TOCTOU issues (the fd could be arbitrarily modified by
surrounding code).
"""
if (self._stat_atopen is not None
and not stat.S_ISCHR(self._stat_atopen.st_mode)):
return True
return os.isatty(self._fd)
@property
def closefd(self):
"""True if the file descriptor will be closed by close()."""