Skip to content

Avoid calling isatty() for most open() calls #90102

Description

@collinanderson
BPO 45944
Nosy @pitrou, @benjaminp, @serhiy-storchaka, @eryksun, @collinanderson
PRs
  • bpo-45944: Avoid calling isatty() for most open() calls #29870
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2021-12-01.05:08:15.763>
    labels = ['3.11', 'expert-IO', 'performance']
    title = 'Avoid calling isatty() for most open() calls'
    updated_at = <Date 2021-12-01.11:53:13.388>
    user = 'https://github.com/collinanderson'

    bugs.python.org fields:

    activity = <Date 2021-12-01.11:53:13.388>
    actor = 'eryksun'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['IO']
    creation = <Date 2021-12-01.05:08:15.763>
    creator = 'collinanderson'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 45944
    keywords = ['patch']
    message_count = 3.0
    messages = ['407427', '407434', '407444']
    nosy_count = 6.0
    nosy_names = ['pitrou', 'benjamin.peterson', 'stutzbach', 'serhiy.storchaka', 'eryksun', 'collinanderson']
    pr_nums = ['29870']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'performance'
    url = 'https://bugs.python.org/issue45944'
    versions = ['Python 3.11']

    Linked PRs

    Activity

    1. collinanderson commented on Dec 1, 2021

      collinandersonmannequin
      MannequinAuthor

      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.

    2. 17 remaining items

    3. serhiy-storchaka commented on Dec 14, 2023

      @serhiy-storchaka
      Member

      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?

    4. vstinner commented on Jul 11, 2024

      @vstinner
      Member

      PR gh-112495 was closed. @serhiy-storchaka wrote:

      It does not work, because the file descriptor can be reassigned from tty to non-tty and vice versa. The result of isatty() can not be cached.

      Should we close the issue?

    5. cmaloney commented on Aug 25, 2024

      @cmaloney
      Contributor

      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".

    6. added 2 commits that reference this issue on Sep 10, 2024
    7. added 2 commits that reference this issue on Oct 3, 2024
    8. added a commit that references this issue on Oct 8, 2024
    9. added a commit that references this issue on Oct 8, 2024
    10. added a commit that references this issue on Oct 8, 2024
    11. vstinner commented on Oct 8, 2024

      @vstinner
      Member

      Optimization implemented by change cc9b9be.

    12. added a commit that references this issue on Oct 8, 2024
    13. added 2 commits that reference this issue on Oct 9, 2024
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      3.13only security fixesperformancePerformance or resource usagetopic-IO

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions