Naming is hard, right?
Today I was extending an argparse based CLI application.
I wanted to add an optional argument so that I can pass in environment variables.
For this argparse has a special “action”, called append.
From the argparse documentation:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['1', '2'])
Awesome!
Now I can access all the provided values as foo.
Wait a moment
Wait! This does not match. I do not access foo but foos!
The problem is more visible when I use a real argument name.
I pass in several environment variables with --environment-variable each,
and access them via environment_variable - this does not feel right.
Also it is not better to name the argument --environment-variables,
as I pass in only one variable at a time.
Nobody likes a confusing cli API.
Colleague to the rescue
My colleague Colin
pointed out that argparse’s add_argument method has a
dest keyword,
which determine the name under which the provided values are accessible.
Final solution
Combining append with dest is the way to go:
parser.add_argument('--foo', action='append', dest='foos')
and
parser.add_argument(
'--environment-variable', action='append', dest='environment_variables'
)