classification
Title: shutil.get_terminal_size throws AttributeError
Type: behavior Stage: resolved
Components: Windows Versions: Python 3.7, Python 3.6
process
Status: closed Resolution: duplicate
Dependencies: Superseder: Fix shutil.get_terminal_size() to catch AttributeError
View: 26801
Assigned To: Nosy List: Isaac Levy, eryksun, paul.moore, r.david.murray, serhiy.storchaka, steve.dower, terry.reedy, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2015-08-24 03:35 by Isaac Levy, last changed 2017-10-26 19:19 by terry.reedy. This issue is now closed.

Messages (12)
msg249039 - (view) Author: Isaac Levy (Isaac Levy) Date: 2015-08-24 03:35
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
msg249040 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2015-08-24 05:20
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.
msg249171 - (view) Author: Isaac Levy (Isaac Levy) Date: 2015-08-26 00:59
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.
msg249195 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-08-26 11:53
I think checking for None would be better.  Catching Exception might mask other errors that the user would want to know about.
msg305018 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2017-10-26 01:47
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.)
msg305034 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-10-26 08:18
This issue already is fixed in 3.5 (see issue26801). 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).
msg305076 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2017-10-26 18:05
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.)
msg305078 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-10-26 18:32
What do you want to do Terry?
msg305079 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-10-26 18:35
Patching shutil will help for pandas.
msg305082 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2017-10-26 18:59
I am preparing a PR for shutil.get_window_size.  Pyplot should probably call that instead of the os version.
msg305083 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-10-26 19:10
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.
msg305084 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2017-10-26 19:19
Uh, sorry for the noise. I see now that shutil was already patched by Victor and you in #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."
History
Date User Action Args
2017-10-26 19:19:54terry.reedysetstatus: open -> closed
resolution: duplicate
messages: + msg305084

stage: test needed -> resolved
2017-10-26 19:10:47serhiy.storchakasetmessages: + msg305083
2017-10-26 18:59:08terry.reedysetmessages: + msg305082
2017-10-26 18:35:02serhiy.storchakasetmessages: + msg305079
2017-10-26 18:32:42serhiy.storchakasetmessages: + msg305078
2017-10-26 18:05:09terry.reedysetstatus: closed -> open
resolution: out of date -> (no value)
messages: + msg305076

stage: resolved -> test needed
2017-10-26 08:18:54serhiy.storchakasetstatus: open -> closed

superseder: Fix shutil.get_terminal_size() to catch AttributeError

nosy: + serhiy.storchaka
messages: + msg305034
resolution: out of date
stage: test needed -> resolved
2017-10-26 01:47:11terry.reedysetversions: + Python 3.7, - Python 3.4, Python 3.5
nosy: + terry.reedy

messages: + msg305018

type: crash -> behavior
stage: test needed
2015-08-26 11:53:58r.david.murraysetnosy: + r.david.murray
messages: + msg249195
2015-08-26 00:59:06Isaac Levysetmessages: + msg249171
2015-08-24 05:20:32eryksunsetversions: + Python 3.5, Python 3.6
nosy: + paul.moore, tim.golden, eryksun, zach.ware, steve.dower

messages: + msg249040

components: + Windows, - IDLE
2015-08-24 03:35:14Isaac Levycreate