3 """Utilities related to user input."""
5 import readchar # type: ignore
8 from typing import List
11 def single_keystroke_response(
12 valid_responses: List[str],
15 default_response: str = None,
16 timeout_seconds: int = None,
18 class TimeoutError(Exception):
21 def _handle_timeout(signum, frame) -> None:
24 def _single_keystroke_response_internal(
25 valid_responses: List[str], timeout_seconds=None
27 if timeout_seconds is not None:
28 signal.signal(signal.SIGALRM, _handle_timeout)
29 signal.alarm(timeout_seconds)
33 response = readchar.readchar()
34 if response in valid_responses:
38 if timeout_seconds is not None:
41 if prompt is not None:
45 response = _single_keystroke_response_internal(
46 valid_responses, timeout_seconds
49 if default_response is not None:
50 response = default_response
51 if prompt is not None:
56 def yn_response(prompt: str = None, *, timeout_seconds=None) -> str:
57 return single_keystroke_response(
58 ["y", "n", "Y", "N"], prompt=prompt, timeout_seconds=timeout_seconds
62 def keystroke_helper() -> None:
63 print("Watching for keystrokes; ^C to quit.")
65 key = readchar.readkey()
67 print(f'That was "{key}" ({ord(key)}).')
71 print(f'That was sequence "{key}" (', end="")
73 print(f" {ord(_)} ", end="")