[Python-ideas] Suggestion: Clear screen command for the REPL

Terry Reedy tjreedy at udel.edu
Tue Sep 20 19:16:18 EDT 2016


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
> people use?

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
> py> shutil.get_terminal_size()
> os.terminal_size(columns=85, lines=10)
>
> That's spot on perfectly correct. I then resized the window and tried it
> again:
>
> py> shutil.get_terminal_size()
> os.terminal_size(columns=108, lines=13)

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 
a workaround.

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



More information about the Python-ideas mailing list