On 9/20/2016 9:31 AM, Steven D'Aprano wrote:
On Mon, Sep 19, 2016 at 06:18:38AM -0400, Terry Reedy wrote:
On 9/19/2016 4:31 AM, Paul Moore wrote:
shutil.get_terminal_size() is available on all platforms.
On windows, it works with Command Prompt and PowerShell but fails in
IDLE, as it must.
Why "must" it fail?
Good question. When I wrote that, I had in mind the qualification 'in
IDLE's default mode, as IDLE is currently structured'. In the default
mode with user code executed in a separate no-window process, there is
currently no way for the child process to know the current size of
Shell's tk text window in the parent process. But this is not the real
story. See below.
What is it about the IDLE terminal that prevents it from emulating an
actual terminal, like all(?) the other terminal emulation programs
IDLE's Shell is based on a tk Text and by design is not a terminal
emulation. (Which terminal would it emulate?). Note that with
proportional fonts, a text editor does not really have character
columns, though it can be sized according to some 'average' character
width. Also, IDLE is a development environment, not a run environment,
and this impacts a few decisions.
I just opened my Konqueror file & web browser, gave the command "Show
Terminal Emulator", and ran Python:
py> import shutil
That's spot on perfectly correct. I then resized the window and tried it
This is what I did and equivalently got with Command Prompt.
I then quit Python, and ran idle3.3 from the Konqueror terminal.
Unfortunately, get_terminal_size() returned the size of the *Konqueror*
terminal, instead of the IDLE terminal. I think that's a bug. I don't
know if its a bug in IDLE or get_terminal_size() or both.
If I run IDLE from Command Prompt, without or with the currently
deprecated -n option, to run user code in the original IDLE process
instead of a separate subprocess, I get the same -- the current size of
the parent Command Prompt.
The reason is that shutil.get_terminal_size first looks for
int(os.environ['COLUMNS']) (or 'LINES') and if that fails, calls
os.get_terminal_size(sys.__stdout__.fileno()). In both cases, the
latter refer to the parent console.
The 'obvious' possible solution is for Shell to set the environment
variables when created or modified. On creation would be easy.
Unfortunately, there is not, AFAIK, an application-accessible Resize
event. A feature of tk is that geometry managers handle resizing
automatically once the user sets the parameters of which widgets can be
resized, and if so, min sizes and relative weights. But maybe there is
I am also not sure if modified environ is propagated to subprocesses.
On Posix, subprocess.Popen uses os.execvp, so the parent environment is
inherited by the new process. I don't know if this means that
subsequent changes are inherited. On Windows, Popen used the system
CreateProcess and I don't know what this does.
A workaround would be to monkeypatch the function. In the rarely used
-n mode, this would be easy. In normal mode, this would require the
execution server to send an rpc message to the Shell client asking for
its dimensions so the server can format the string to send to the
client. I do not know if the current rpc mechanism is set up for
requests from server to client.
If not fixed soon, I should add the limitation to the IDLE doc.
Terry Jan Reedy
Python-ideas mailing list
Code of Conduct: http://python.org/psf/codeofconduct/