bw2 / ConfigArgParse

A drop-in replacement for argparse that allows options to also be set via config files and/or environment variables.
MIT License
723 stars 121 forks source link

"# normalize args by converting args like --key=value to --key value" breaks "--key=-value" #109

Open EvanED opened 6 years ago

EvanED commented 6 years ago

This is a discrepancy between configargparse and argparse.

Suppose I want to pass an argument to an option where the argument starts with a hyphen. This works with argparse:

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--stuff')
>>> args = parser.parse_args(['--stuff=--thing'])
>>> args.stuff
'--thing'

but the normalization step breaks this for configargparse:

>>> import configargparse
>>> parser = configargparse.ArgumentParser()
>>> parser.add_argument('--stuff')
>>> args = parser.parse_args(["--stuff=--thing"])
usage: [-h] [--stuff STUFF]
: error: argument --stuff: expected one argument

The reason this breaks is because of Python bug #9334, which will prevent arguments to an option as parsing as such when they have a leading hyphen. (Yes, this is contrary to every other argument parsing library ever written, including getopt_long.)

Is this normalization step required?

bw2 commented 6 years ago

Yeah, it's needed for the already_on_command_line(existing_args_list, potential_command_line_args) check to work - which is a key step in handling args that are for example specified in both on the command-line and in a config file: https://github.com/bw2/ConfigArgParse/blob/master/configargparse.py#L892

The fix is probably to have 2 separate lists - the args list that's being built up, and a separate list of previously-seen keys. I don't have time to implement this unfortunately.