Using Signals
you can use signal module (linux / unix only)
import signal
class UserInputTimeoutError(Exception):
pass
def handler(signum, frame):
raise UserInputTimeoutError('no input from user')
# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)
try:
# This may hang indefinitely
user_input = raw_input('please insert something here:')
print('got %s from user' % user_input)
# cancel the alarm signal
signal.alarm(0)
except UserInputTimeoutError:
print('\nno input from user')
output when input is 'hello':
please insert something here:hello
got hello from user
output when no input for 5 seconds:
please insert something here:
no input from user
Using Select
another option is to use select.select()
for non-blocking io operation.
the get_user_input
function tries to read every 0.1 sec the sys.stdin, if there is data to read it reads single byte. if it encounters a new line it returns the string.
if the timeout passed we exit returning None
the code:
import select
import sys
import time
def get_user_input(msg, timeout=5):
print(msg)
user_input = []
stime = time.time()
while time.time() - stime <= timeout:
readables, _, _ = select.select([sys.stdin], [], [], 0.1)
if not readables:
continue
chr = readables[0].read(1)
if chr == '\n':
return ''.join(user_input)
user_input.append(chr)
user_input = get_user_input('please insert something:')
if user_input is None:
print('no user input')
else:
print('input is %s' % user_input)
example output for input hello select
:
please insert something:
hello select
input is hello select
example when no input for 5 seconds:
please insert something:
no user input
Windows support
if you use windows for some reason you can check out this answer about msvcrt
module.
basically its the same as select.select
for non-blocking io using msvcrt.kbhit()
to check if user returned input.
if you need more info please update about your OS.