Q: argparse.add_argument()

Chris Angelico rosuav at gmail.com
Sat Mar 18 16:05:51 EDT 2023


On Sun, 19 Mar 2023 at 06:35, Gisle Vanem via Python-list
<python-list at python.org> wrote:
>
> Thomas Passin wrote:
>
> > Are you trying to troll here?
> >
> You just showed how you got an error with this construction, so why are you asking how to
> > get an error with this construction?
>
> I meant (obviously), another error-message besides:
>    error: unrecognized arguments: -cn
>
> Perhaps from 'parser.add_argument ("-c, --clean", dest="clean", action="store_true")'
>    error: "-c, --clean", 2 options are unsupported.
>
> BTW, accusing someone of 'trolling' is rather rude IMHO.
> And thanks to ChrisA for a nice and normal answer.

I suspect the reason you were accused of trolling was that it was
quite unobvious what the difference was. When you ask for help with
something where the distinction is subtle (and you generally know it
was subtle by how long it took you to spot it!), it's often valuable
to pinpoint the exact issue, so people don't gloss over it and think
you posted the same code twice. For example:

"""
I accidentally used 'argparse' like this in my Python 3.9 program:
   parser.add_argument ("-c, --clean",  dest="clean", action="store_true")
   parser.add_argument ("-n, --dryrun", dest="dryrun", action="store_true")

instead of:
   parser.add_argument ("-c", "--clean",  dest="clean", action="store_true")
   parser.add_argument ("-n", "--dryrun", dest="dryrun", action="store_true")

Instead of having the short and long forms as separate parameters to
add_argument, I mistakenly put them in a single string.
"""

Now everyone can see immediately what your bug was, how easy it is to
make (and how hard to spot if not pointed out), and how likely it is
for this to be actually desired behaviour (in this case: highly
unlikely).

As to the reason you didn't get any other error message - that's
because, technically, what you did was perfectly valid.

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument ("-c, --clean",  dest="clean", action="store_true")
_StoreTrueAction(option_strings=['-c, --clean'], dest='clean',
nargs=0, const=True, default=False, type=None, choices=None,
required=False, help=None, metavar=None)
>>> parser.add_argument ("-n, --dryrun", dest="dryrun", action="store_true")
_StoreTrueAction(option_strings=['-n, --dryrun'], dest='dryrun',
nargs=0, const=True, default=False, type=None, choices=None,
required=False, help=None, metavar=None)
>>> parser.parse_args(["-c, --clean"])
Namespace(clean=True, dryrun=False)

It's just that the argument needed to make this happen is... a tad
unlikely in the real world. So I do see that there's a problem here,
but I'm not sure what the true solution is. Is it reasonable to
mandate that arguments do not contain spaces? (Dubious.) What if
they're not allowed to contain commas? (Also dubious.) Maybe something
really complicated like ", -" as an entire construct? (Could easily be
confusing.) It's definitely worth opening the conversation on this,
and I'd be curious to know how many other people have made this same
bug.

ChrisA


More information about the Python-list mailing list