There's no cross-platform way to do this in Python 2.x, because file
objects, including stdin
, are basically a thin wrapper around a lowest-common-denominator version of C stdio.
However, there are solutions for most *nix systems, and maybe for Windows, and between them, that covers everything you're likely to run a Python terminal program on.
On most *nix systems (pretty much everything you're likely to care about but Windows), if you only care about interactive input (that is, you want to skip anything the user types at the prompt, but don't want to skip anything if piped input from a file or another program), you can do this with the termios
library:
downloading(HUGE_FILE)
if sys.stdin.isatty():
sys.stdin.flush()
termios.flush(sys.stdin, termios.TCIFLUSH)
sys.stdin.flush()
input_var = raw_input("Enter:")
There are some edge cases where this may not work. Also, it can break readline
support on some platforms. But it will mostly work.
On Windows, it's not quite as simple—but if stdin is the real console input, you can manually drain characters until there are no more by using the Console I/O APIs.
downloading(HUGE_FILE)
if sys.stdin.isatty():
sys.stdin.flush()
while msvcrt.kbhit():
msvcrt.getch()
sys.stdin.flush()
input_var = raw_input("Enter:")
On both platforms, the stdin.flush
calls probably aren't necessary, but in theory it's illegal to switch between terminal/console I/O and stdio I/O without flushing, and in some edge cases you may end up with stuff that's already been read into the buffer that doesn't get thrown away if you don't do it, so, better safe than sorry.
So, how do you know which platform you're on? You could check platform.system()
or similar, but it's probably best to just check for the libraries you want to use (especially because there's a whole slew of Unix-like systems you'd have to check for, and not all of them have termios
, and some even have it optionally or only as of a certain version or …).
try:
import termios
# You can use the Unix code
except ImportError:
try:
import msvcrt
# You can use the Windows code
except ImportError:
# You can't use either, just accept the extra characters