On Sat, Jan 28, 2017 at 8:03 AM, Steve D'Aprano <steve+pyt...@pearwood.info> wrote: > print('shutil:', shutil.get_terminal_size(fallback=(999, 999))) > print('os:', os.get_terminal_size(0)) [snip] > But if I pipe the output to something else, the shutil version fails to > determine the correct terminal size, and falls back on the default:
The high-level shutil wrapper uses sys.__stdout__, without falling back on sys.__stdin__ or sys.__stderr__, so it has to rely on the environment variables and/or fallback value when stdout isn't a terminal. OTOH, in this case you're calling os.get_terminal_size(0) on the STDIN file descriptor, which obviously works -- at least on Unix -- because it's a tty. On Windows that generally won't work because getting the screen size requires a handle for a screen buffer, not an input buffer. In this case, os.get_terminal_size(2) would generally work on Windows because stderr hasn't been redirected. I just wrote an extended version of shutil.get_terminal_size that tries six (minus two) ways to Sunday to get the terminal size, starting with /dev/tty on Unix and CONOUT$ on Windows. It's needlessly complicated by the Windows implementation of os.get_terminal_size, which is strangely hard coded. os.get_terminal_size calls GetStdHandle with a fake mapping of 0, 1, and 2 to the standard handles. It should just call get_osfhandle on the given file descriptor. That way someone could use something like the following: with open('CONOUT$', 'r+') as conout: size = os.get_terminal_size(conout.fileno()) which would be guaranteed to work if the process is attached to a console. The current implementation forces one to temporarily modify a standard handle, which has to be gated by a lock for thread safety. -- https://mail.python.org/mailman/listinfo/python-list