From e6a5042d2fc9bd3eb05d0b8dd4e6d35678bcf19d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Fri, 28 Jul 2023 21:43:26 +0300 Subject: [PATCH] bash `nounset` mode fixes Fixes issues I came across while briefly testing the shtab completions of `keyring` in `set -o nounset` mode, as well tests failing in that mode. This might not be a complete set, but it's a start. --- shtab/__init__.py | 8 ++++---- tests/test_shtab.py | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/shtab/__init__.py b/shtab/__init__.py index 2089de1..6d8dcb1 100644 --- a/shtab/__init__.py +++ b/shtab/__init__.py @@ -339,7 +339,7 @@ def complete_bash(parser, root_prefix=None, preamble="", choice_functions=None): # set default values (called for the initial parser & any subparsers) _set_parser_defaults() { local subparsers_var="${prefix}_subparsers[@]" - sub_parsers=${!subparsers_var} + sub_parsers=${!subparsers_var-} local current_option_strings_var="${prefix}_option_strings[@]" current_option_strings=${!current_option_strings_var} @@ -356,13 +356,13 @@ def complete_bash(parser, root_prefix=None, preamble="", choice_functions=None): current_action="${prefix}_$(_shtab_replace_nonword $1)" local current_action_compgen_var=${current_action}_COMPGEN - current_action_compgen="${!current_action_compgen_var}" + current_action_compgen="${!current_action_compgen_var-}" local current_action_choices_var="${current_action}_choices[@]" - current_action_choices="${!current_action_choices_var}" + current_action_choices="${!current_action_choices_var-}" local current_action_nargs_var="${current_action}_nargs" - if [ -n "${!current_action_nargs_var}" ]; then + if [ -n "${!current_action_nargs_var-}" ]; then current_action_nargs="${!current_action_nargs_var}" else current_action_nargs=1 diff --git a/tests/test_shtab.py b/tests/test_shtab.py index e07aff4..d525d65 100644 --- a/tests/test_shtab.py +++ b/tests/test_shtab.py @@ -20,7 +20,7 @@ def __init__(self, init_script=""): def test(self, cmd="1", failure_message=""): """Equivalent to `bash -c '{init}; [[ {cmd} ]]'`.""" init = self.init + "\n" if self.init else "" - proc = subprocess.Popen(["bash", "-o", "pipefail", "-ec", f"{init}[[ {cmd} ]]"]) + proc = subprocess.Popen(["bash", "-o", "pipefail", "-euc", f"{init}[[ {cmd} ]]"]) stdout, stderr = proc.communicate() assert (0 == proc.wait() and not stdout and not stderr), f"""\ {failure_message} @@ -36,7 +36,7 @@ def compgen(self, compgen_cmd, word, expected_completions, failure_message=""): ) -@pytest.mark.parametrize("init,test", [("export FOO=1", '"$FOO" -eq 1'), ("", '-z "$FOO"')]) +@pytest.mark.parametrize("init,test", [("export FOO=1", '"$FOO" -eq 1'), ("", '-z "${FOO-}"')]) def test_bash(init, test): shell = Bash(init) shell.test(test) @@ -192,7 +192,7 @@ def test_subparser_custom_complete(shell, caplog): shell.compgen('-W "${_shtab_test_subparsers[*]}"', "s", "sub") shell.compgen('-W "$_shtab_test_pos_0_choices"', "s", "sub") shell.test('"$($_shtab_test_sub_pos_0_COMPGEN o)" = "one"') - shell.test('-z "$_shtab_test_COMPGEN"') + shell.test('-z "${_shtab_test_COMPGEN-}"') assert not caplog.record_tuples @@ -217,7 +217,7 @@ def test_subparser_aliases(shell, caplog): shell.compgen('-W "${_shtab_test_subparsers[*]}"', "y", "ysub") shell.compgen('-W "${_shtab_test_pos_0_choices[*]}"', "y", "ysub") shell.test('"$($_shtab_test_sub_pos_0_COMPGEN o)" = "one"') - shell.test('-z "$_shtab_test_COMPGEN"') + shell.test('-z "${_shtab_test_COMPGEN-}"') assert not caplog.record_tuples @@ -235,7 +235,7 @@ def test_subparser_colons(shell, caplog): shell = Bash(completion) shell.compgen('-W "${_shtab_test_subparsers[*]}"', "s", "sub:cmd") shell.compgen('-W "${_shtab_test_pos_0_choices[*]}"', "s", "sub:cmd") - shell.test('-z "$_shtab_test_COMPGEN"') + shell.test('-z "${_shtab_test_COMPGEN-}"') assert not caplog.record_tuples