diff --git a/src/argh/assembling.py b/src/argh/assembling.py index fdfc4a0..eca5f64 100644 --- a/src/argh/assembling.py +++ b/src/argh/assembling.py @@ -516,6 +516,16 @@ def _merge_inferred_and_declared_args( # specs_by_func_arg_name = OrderedDict() + # eliminate inferred options that conflict with declared ones + for inferred in inferred_args: + for declared in declared_args: + if inferred.func_arg_name == declared.func_arg_name: + continue + inferred.cli_arg_names = [ + name for name in inferred.cli_arg_names + if name not in declared.cli_arg_names + ] + # arguments inferred from function signature for parser_add_argument_spec in inferred_args: specs_by_func_arg_name[parser_add_argument_spec.func_arg_name] = ( diff --git a/tests/test_regressions.py b/tests/test_regressions.py index 2d5b7fd..d3c29e5 100644 --- a/tests/test_regressions.py +++ b/tests/test_regressions.py @@ -261,3 +261,22 @@ def func(*, list_files=False): assert run(parser, "").out == "list_files=False\n" assert run(parser, "-l").out == "list_files=True\n" + + +def test_regression_issue233(): + """ + Issue #233: conflict when short option does not match first letter + of long option + + Use case: assigning short names to options + """ + + @argh.arg("-n", "--user-name") + @argh.arg("-N", "--note") + def func(*, user_name="world", note=""): + return f"hello, {user_name}! {note}" + + parser = DebugArghParser() + parser.set_default_command(func) + + assert run(parser, "-n Sam -N Cheers").out == "hello, Sam! Cheers\n"