Skip to content

Instantly share code, notes, and snippets.

@lomalkin
Forked from ali1234/input.py
Last active July 3, 2023 01:44
Show Gist options
  • Save lomalkin/9aa8f0c426655a252180b13bbe8e82c2 to your computer and use it in GitHub Desktop.
Save lomalkin/9aa8f0c426655a252180b13bbe8e82c2 to your computer and use it in GitHub Desktop.
Unbuffered, non-blocking stdin in Python
import fcntl
import termios
import sys
import os
import time
class NonBlockingInput(object):
def __enter__(self):
# canonical mode, no echo
self.old = termios.tcgetattr(sys.stdin)
new = termios.tcgetattr(sys.stdin)
new[3] = new[3] & ~(termios.ICANON | termios.ECHO)
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, new)
# set for non-blocking io
self.orig_fl = fcntl.fcntl(sys.stdin, fcntl.F_GETFL)
fcntl.fcntl(sys.stdin, fcntl.F_SETFL, self.orig_fl | os.O_NONBLOCK)
def __exit__(self, *args):
# restore terminal to previous state
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.old)
# restore original
fcntl.fcntl(sys.stdin, fcntl.F_SETFL, self.orig_fl)
with NonBlockingInput():
while True:
c = sys.stdin.read(1)
print('tick', repr(c))
time.sleep(0.1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment