|
@@ -842,71 +842,69 @@ def is_slow_msgpack():
|
|
|
return msgpack.Packer is msgpack.fallback.Packer
|
|
|
|
|
|
|
|
|
-def yes(msg=None, retry_msg=None, false_msg=None, true_msg=None,
|
|
|
- default=False, default_notty=None, default_eof=None,
|
|
|
- falsish=('No', 'no', 'N', 'n'), truish=('Yes', 'yes', 'Y', 'y'),
|
|
|
- env_var_override=None, ifile=None, ofile=None, input=input):
|
|
|
+FALSISH = ('No', 'NO', 'no', 'N', 'n', '0', )
|
|
|
+TRUISH = ('Yes', 'YES', 'yes', 'Y', 'y', '1', )
|
|
|
+DEFAULTISH = ('Default', 'DEFAULT', 'default', 'D', 'd', '', )
|
|
|
+
|
|
|
+def yes(msg=None, false_msg=None, true_msg=None, default_msg=None,
|
|
|
+ retry_msg=None, invalid_msg=None, env_msg=None,
|
|
|
+ falsish=FALSISH, truish=TRUISH, defaultish=DEFAULTISH,
|
|
|
+ default=False, retry=True, env_var_override=None, ofile=None, input=input):
|
|
|
"""
|
|
|
Output <msg> (usually a question) and let user input an answer.
|
|
|
- Qualifies the answer according to falsish and truish as True or False.
|
|
|
+ Qualifies the answer according to falsish, truish and defaultish as True, False or <default>.
|
|
|
If it didn't qualify and retry_msg is None (no retries wanted),
|
|
|
return the default [which defaults to False]. Otherwise let user retry
|
|
|
answering until answer is qualified.
|
|
|
|
|
|
- If env_var_override is given and it is non-empty, counts as truish answer
|
|
|
- and won't ask user for an answer.
|
|
|
- If we don't have a tty as input and default_notty is not None, return its value.
|
|
|
- Otherwise read input from non-tty and proceed as normal.
|
|
|
- If EOF is received instead an input, return default_eof [or default, if not given].
|
|
|
+ If env_var_override is given and this var is present in the environment, do not ask
|
|
|
+ the user, but just use the env var contents as answer as if it was typed in.
|
|
|
+ Otherwise read input from stdin and proceed as normal.
|
|
|
+ If EOF is received instead an input or an invalid input without retry possibility,
|
|
|
+ return default.
|
|
|
|
|
|
:param msg: introducing message to output on ofile, no \n is added [None]
|
|
|
:param retry_msg: retry message to output on ofile, no \n is added [None]
|
|
|
- (also enforces retries instead of returning default)
|
|
|
:param false_msg: message to output before returning False [None]
|
|
|
:param true_msg: message to output before returning True [None]
|
|
|
- :param default: default return value (empty answer is given) [False]
|
|
|
- :param default_notty: if not None, return its value if no tty is connected [None]
|
|
|
- :param default_eof: return value if EOF was read as answer [same as default]
|
|
|
+ :param default_msg: message to output before returning a <default> [None]
|
|
|
+ :param invalid_msg: message to output after a invalid answer was given [None]
|
|
|
+ :param env_msg: message to output when using input from env_var_override [None],
|
|
|
+ needs to have 2 placeholders for answer and env var name, e.g.: "{} (from {})"
|
|
|
:param falsish: sequence of answers qualifying as False
|
|
|
:param truish: sequence of answers qualifying as True
|
|
|
+ :param defaultish: sequence of answers qualifying as <default>
|
|
|
+ :param default: default return value (defaultish answer was given or no-answer condition) [False]
|
|
|
+ :param retry: if True and input is incorrect, retry. Otherwise return default. [True]
|
|
|
:param env_var_override: environment variable name [None]
|
|
|
- :param ifile: input stream [sys.stdin] (only for testing!)
|
|
|
:param ofile: output stream [sys.stderr]
|
|
|
:param input: input function [input from builtins]
|
|
|
:return: boolean answer value, True or False
|
|
|
"""
|
|
|
- # note: we do not assign sys.stdin/stderr as defaults above, so they are
|
|
|
+ # note: we do not assign sys.stderr as default above, so it is
|
|
|
# really evaluated NOW, not at function definition time.
|
|
|
- if ifile is None:
|
|
|
- ifile = sys.stdin
|
|
|
if ofile is None:
|
|
|
ofile = sys.stderr
|
|
|
if default not in (True, False):
|
|
|
raise ValueError("invalid default value, must be True or False")
|
|
|
- if default_notty not in (None, True, False):
|
|
|
- raise ValueError("invalid default_notty value, must be None, True or False")
|
|
|
- if default_eof not in (None, True, False):
|
|
|
- raise ValueError("invalid default_eof value, must be None, True or False")
|
|
|
if msg:
|
|
|
- print(msg, file=ofile, end='')
|
|
|
- ofile.flush()
|
|
|
- if env_var_override:
|
|
|
- value = os.environ.get(env_var_override)
|
|
|
- # currently, any non-empty value counts as truish
|
|
|
- # TODO: change this so one can give y/n there?
|
|
|
- if value:
|
|
|
- value = bool(value)
|
|
|
- value_str = truish[0] if value else falsish[0]
|
|
|
- print("{} (from {})".format(value_str, env_var_override), file=ofile)
|
|
|
- return value
|
|
|
- if default_notty is not None and not ifile.isatty():
|
|
|
- # looks like ifile is not a terminal (but e.g. a pipe)
|
|
|
- return default_notty
|
|
|
+ print(msg, file=ofile, end='', flush=True)
|
|
|
while True:
|
|
|
- try:
|
|
|
- answer = input() # XXX how can we use ifile?
|
|
|
- except EOFError:
|
|
|
- return default_eof if default_eof is not None else default
|
|
|
+ answer = None
|
|
|
+ if env_var_override:
|
|
|
+ answer = os.environ.get(env_var_override)
|
|
|
+ if answer is not None and env_msg:
|
|
|
+ print(env_msg.format(answer, env_var_override), file=ofile)
|
|
|
+ if answer is None:
|
|
|
+ try:
|
|
|
+ answer = input()
|
|
|
+ except EOFError:
|
|
|
+ # avoid defaultish[0], defaultish could be empty
|
|
|
+ answer = truish[0] if default else falsish[0]
|
|
|
+ if answer in defaultish:
|
|
|
+ if default_msg:
|
|
|
+ print(default_msg, file=ofile)
|
|
|
+ return default
|
|
|
if answer in truish:
|
|
|
if true_msg:
|
|
|
print(true_msg, file=ofile)
|
|
@@ -915,11 +913,15 @@ def yes(msg=None, retry_msg=None, false_msg=None, true_msg=None,
|
|
|
if false_msg:
|
|
|
print(false_msg, file=ofile)
|
|
|
return False
|
|
|
- if retry_msg is None:
|
|
|
- # no retries wanted, we just return the default
|
|
|
+ # if we get here, the answer was invalid
|
|
|
+ if invalid_msg:
|
|
|
+ print(invalid_msg, file=ofile)
|
|
|
+ if not retry:
|
|
|
return default
|
|
|
if retry_msg:
|
|
|
print(retry_msg, file=ofile, end='', flush=True)
|
|
|
+ # in case we used an environment variable and it gave an invalid answer, do not use it again:
|
|
|
+ env_var_override = None
|
|
|
|
|
|
|
|
|
class ProgressIndicatorPercent:
|