Skip to content

shutil.get_terminal_size throws AttributeError #69108

Closed

Description

@IsaacLevy
mannequin
BPO 24920
Nosy @terryjreedy, @pfmoore, @tjguk, @bitdancer, @zware, @serhiy-storchaka, @eryksun, @zooba
Superseder
  • bpo-26801: Fix shutil.get_terminal_size() to catch AttributeError
  • 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 = <Date 2017-10-26.19:19:54.973>
    created_at = <Date 2015-08-24.03:35:14.674>
    labels = ['type-bug', '3.7', 'OS-windows']
    title = 'shutil.get_terminal_size throws AttributeError'
    updated_at = <Date 2017-10-26.19:19:54.971>
    user = 'https://bugs.python.org/IsaacLevy'

    bugs.python.org fields:

    activity = <Date 2017-10-26.19:19:54.971>
    actor = 'terry.reedy'
    assignee = 'none'
    closed = True
    closed_date = <Date 2017-10-26.19:19:54.973>
    closer = 'terry.reedy'
    components = ['Windows']
    creation = <Date 2015-08-24.03:35:14.674>
    creator = 'Isaac Levy'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 24920
    keywords = []
    message_count = 12.0
    messages = ['249039', '249040', '249171', '249195', '305018', '305034', '305076', '305078', '305079', '305082', '305083', '305084']
    nosy_count = 9.0
    nosy_names = ['terry.reedy', 'paul.moore', 'tim.golden', 'r.david.murray', 'zach.ware', 'serhiy.storchaka', 'eryksun', 'steve.dower', 'Isaac Levy']
    pr_nums = []
    priority = 'normal'
    resolution = 'duplicate'
    stage = 'resolved'
    status = 'closed'
    superseder = '26801'
    type = 'behavior'
    url = 'https://bugs.python.org/issue24920'
    versions = ['Python 3.6', 'Python 3.7']

    Activity

    1. IsaacLevy commented on Aug 24, 2015

      IsaacLevymannequin
      MannequinAuthor

      OS: windows 7, python 3.4.3, tk version 8.6.1

      os.get_terminal_size also fails.

      >>> shutil.get_terminal_size()
      Traceback (most recent call last):
        File "<pyshell#4>", line 1, in <module>
          shutil.get_terminal_size()
        File "C:\Python34\lib\shutil.py", line 1058, in get_terminal_size
          size = os.get_terminal_size(sys.__stdout__.fileno())
      AttributeError: 'NoneType' object has no attribute 'fileno'
      >>> os.get_terminal_size()
      Traceback (most recent call last):
        File "<pyshell#5>", line 1, in <module>
          os.get_terminal_size()
      ValueError: bad file descriptor
    2. eryksun commented on Aug 24, 2015

      @eryksun
      Contributor

      FYI, the size of the terminal associated with the C's stdout isn't related to the IDLE shell. For example, in Linux when I run IDLE from the GUI, the associated terminal size is 0x0.

      On Windows, os.get_terminal_size uses the console API GetConsoleScreenBufferInfo. This can't work given IDLE has no attached console. Also, for a GUI app the Windows C runtime leaves the standard FILE streams uninitialized to an invalid file descriptor (-1), so Python's sys.__stdout__ is None. That's why you get an AttributeError complaining that NoneType (i.e. type(None)) has no attribute 'fileno'.

      Currently shutil.get_terminal_size returns the fallback size when os.get_terminal_size(sys.__stdout__.fileno()) raises NameError or OSError. I think AttributeError and ValueError should be added to this list.

    3. IsaacLevy commented on Aug 26, 2015

      IsaacLevymannequin
      MannequinAuthor

      I guess users need to check standard streams for None. There's not many uses of stream attributes in core libs.

      Maybe catch should be Exception -- since it's documented to return a fallback on error.

    4. bitdancer commented on Aug 26, 2015

      @bitdancer
      Member

      I think checking for None would be better. Catching Exception might mask other errors that the user would want to know about.

    5. terryjreedy commented on Oct 26, 2017

      @terryjreedy
      Member

      If one starts IDLE from a command-line console (python -m idlelib) or Python console (import idlelib.idle), sys.__stdout__ is the TextIOWraper for that console and .fileno() returns 1. .get_terminal_size() will then return the console size. The exception occurs when IDLE is started from an icon.

      Implementing David's suggestion for shutil will be easy: insert just before the fileno call
      if not sys.__stdout__: raise ValueError()
      This is what os.get_terminal_size() raises on IDLE. Comments in the code in posixpath.c make it clear that this is intended guis and the low_level os function.

      This came up today on Stackoverflow when someone tried to use matplotlib.pyplot, which calls os.get_terminal_size, on IDLE.
      https://stackoverflow.com/questions/46921087/pyplot-with-idle
      (Patching shutil will not help for the os call.)

    6. added
      type-bugAn unexpected behavior, bug, or error
      and removed
      type-crashA hard crash of the interpreter, possibly with a core dump
      on Oct 26, 2017
    7. serhiy-storchaka commented on Oct 26, 2017

      @serhiy-storchaka
      Member

      This issue already is fixed in 3.5 (see bpo-26801). The Stackoverflow question is related to 3.4 which is too old for getting this fix.

      I'm wondering if it is worth to patch shutil.get_terminal_size() in IDLE so that it will return the size of PyShell output window (in characters).

    8. terryjreedy commented on Oct 26, 2017

      @terryjreedy
      Member

      If one starts IDLE from a command-line console (python -m idlelib) or Python console (import idlelib.idle), sys.__stdout__ is the TextIOWraper for that console and .fileno() returns 1. .get_terminal_size() will then return the console size. The exception occurs when IDLE is started from an icon.

      Implementing David's suggestion for shutil will be easy: insert just before the fileno call
      if not sys.__stdout__: raise ValueError()
      This is what os.get_terminal_size() raises on IDLE. Comments in the code in posixpath.c make it clear that this is intended guis and the low_level os function.

      This came up today on Stackoverflow when someone tried to use matplotlib.pyplot, which calls os.get_terminal_size, on IDLE.
      https://stackoverflow.com/questions/46921087/pyplot-with-idle
      (Patching shutil will not help for the os call.)

    9. serhiy-storchaka commented on Oct 26, 2017

      @serhiy-storchaka
      Member

      What do you want to do Terry?

    10. serhiy-storchaka commented on Oct 26, 2017

      @serhiy-storchaka
      Member

      Patching shutil will help for pandas.

    11. terryjreedy commented on Oct 26, 2017

      @terryjreedy
      Member

      I am preparing a PR for shutil.get_window_size. Pyplot should probably call that instead of the os version.

    12. serhiy-storchaka commented on Oct 26, 2017

      @serhiy-storchaka
      Member

      I think it is better to open a new issue for a new feature. The bug reported in this issue two years ago already is fixed.

    13. terryjreedy commented on Oct 26, 2017

      @terryjreedy
      Member

      Uh, sorry for the noise. I see now that shutil was already patched by Victor and you in bpo-26801, so that it already works with IDLE started from an icon. So now I don't understand your last comment, "Patching shutil will help for pandas."

    14. transferred this issue fromon Apr 10, 2022
    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

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions