conflict_handler(action, confl_optionals)
File "/usr/local/lib/python3.6/argparse.py", line 1510, in _handle_conflict_error
raise ArgumentError(action, message % conflict_string)
argparse.ArgumentError: argument -h/--height: conflicting option string: -h
The above is the error message,
here is my code,
I don't see the error:
# 1) Parse the arguments
parser = argparse.ArgumentParser(description="Description for my parser")
parser.add_argument("-v", "--velocity", action="store", required=True, help="The velocity of the object is required")
parser.add_argument("-a", "--angle", action="store", type=float, required=True, help="The angle of the object is required")
parser.add_argument("-h", "--height", required=False, default= 1.2, help="The height of the object is not required. Default is set to 1.2 meters" )
Option "-h" is by default predefined as a "help" option, which prints the description and the list of arguments. Your custom "-h --height" conflicts with this, thus causing an error.
It wouldn't be nice to overwrite the default "-h --help" option, because many users expect "-h" option to print help message. (So if I were you I would find another way to name the option.) But you can ignore it if you really need to by using add_help parameter with the constructor. Like this:
parser = argparse.ArgumentParser(description="Description for my parser", add_help=False)
If you want to keep "--help" option, you have to add another line of parser.add_argument("--help", action="help"). (Thanks to chepner)
As the error suggests you are using a param name who is conflicting with other. Particularly in this case the -h option. The lib argparse always include the -h option to print the script help, so for the height, you must use a different param than -h, for example -ht.
parser = argparse.ArgumentParser(description="Description for my parser")
parser.add_argument("-v", "--velocity", action="store", required=True, help="The velocity of the object is required")
parser.add_argument("-a", "--angle", action="store", type=float, required=True, help="The angle of the object is required")
parser.add_argument("-ht", "--height", required=False, default= 1.2, help="The height of the object is not required. Default is set to 1.2 meters" )
Related
I use the following code to parse argument to my script (simplified version):
import argparse
ap = argparse.ArgumentParser()
ap.add_argument("-l", "--library", required=True)
ap.add_argument("--csv2fasta", required=False)
args = vars(ap.parse_args())
For every way the script can be run, the -l/--library flag should be required (required=True), but is there a way that it can use the setting required=False when you only use the --csv2fasta flag?
You have to write your test after parsing arguments, here's what I do for such cases:
def parse_args():
ap = argparse.ArgumentParser()
ap.add_argument("-l", "--library")
ap.add_argument("--csv2fasta")
args = ap.parse_args()
if not args.library and not args.csv2fasta:
ap.error("--library is required unless you provide --csv2fasta argument")
return args
$ python3 test-args.py
usage: test-args.py [-h] [-l LIBRARY] [--csv2fasta CSV2FASTA]
test-args.py: error: --library is required unless you provide --csv2fasta argument
$ python3 test-args.py --csv2fasta value
Subcommands like git commit and git status can be easily parsed with argparse using add_subparsers. How does one get nested settings input for choices selected from command line?
Let's say I want to play music with all custom settings:
play.py --path /path/to.file --duration 100 --filter equalizer --effect echo equalizer_settings 1 2 echo_settings 5
Here --filter equalizer and --effect echo are first level choices but I need to get settings for those as secondary arguments. Ex: echo_settings 5 and equalizer_settings 1 2.
Secondary settings could be more than one and preferably with named arguments.
Listed below is what I have so far...
import argparse
parser = argparse.ArgumentParser(description='Play music the way I want it.')
parser.add_argument('-p', '--path', type=str, required=True, help='File path')
parser.add_argument('-d', '--duration', type=int, default=50, help='Play duration')
parser.add_argument('-f', '--filter', choices=['none', 'equalizer'], default='none', help='Filter selection')
parser.add_argument('-e', '--effect', choices=['none', 'echo', 'surround'], default='none', help='Effect selection')
subparsers = parser.add_subparsers(help='Settings of optional parameters')
equalizer_parser = subparsers.add_parser("equalizer_settings")
equalizer_parser.add_argument('equalizer_min_range', type=int)
equalizer_parser.add_argument('equalizer_max_range', type=int)
echo_parser = subparsers.add_parser("echo_settings")
echo_parser.add_argument('echo_strength', type=int)
surround_parser = subparsers.add_parser("surround_settings")
surround_parser.add_argument('surround_strength', type=int)
args = parser.parse_args()
print(args)
Currently this errors in error: unrecognized arguments
You can only use one subparser at a time, i.e. one of those 3 settings. There are some advanced ways of using several subparsers in sequence, but I don't think we want to go there (see previous SO argparse questions).
But do you really need to use subparsers? Why not just another set of optionals (flagged) arguments, something like:
parser.add_argument("--equalizer_settings", nargs=2, type=int)
parser.add_argument("--echo_settings", type=int)
parser.add_argument("--surround_strength", type=int
You are just adding some parameters, not invoking some sort of action command.
I am trying to use argparse to accept required command line options. I have defined a function like so
def get_args():
parser = argparse.ArgumentParser(description='Help Desk Calendar Tool')
parser.add_argument('-s', '--start', type=str, required=True, metavar='YYYY-MM-DD')
parser.add_argument('-e','--end', type=str, required=True, metavar='YYYY-MM-DD')
parser.add_argument('-m','--mode', type=str, required=True , metavar='add|del')
args = parser.parse_args()
start = args.start
end = args.end
mode = args.mode
return start,end,mode
What I am trying to do is for the option --mode I would like it to ONLY accept an parameter of either add or del. I could do this from an if statement but was wondering if argparse has a built in way of accomplishing this task. I looked at nargs but wasn't too clear if that's the path I need to go down
I think you are asking about choices:
parser.add_argument('-m','--mode', type=str, required=True, choices=['add', 'del'])
Demo:
$ python test.py -s 10 -e 20 -m invalid
usage: test.py [-h] -m {add,del}
test.py: error: argument -m/--mode: invalid choice: 'invalid' (choose from 'add', 'del')
I'm running this as part of a call to the api using the url. I dont know what I'm doing wrong - the terminal keeps saying I have an Attribute error where the 'Namespace' object has no attribute to offset. I wanted to add search parameters "offset, sort and category_filter", but am not sure what I have to do to the parser.add_argument. I tried copying those that were in the sample code listed below, but it didnt seem to work. I'm a bit confused as to why that is...
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-q', '--term', dest='term', default=DEFAULT_TERM,
type=str, help='Search term (default: %(default)s)')
parser.add_argument('-l', '--location', dest='location',
default=DEFAULT_LOCATION, type=str,
help='Search location (default: %(default)s)')
parser.add_argument('--offset', dest='offset', default=DEFAULT_OFFSET,
type=int, help='Search offset (default: %(default)s)')
parser.add_argument('--sort', dest='sort', default=DEFAULT_SORT,
type=int, help='Sear sort (default:%(default)s)')
parser.add_argument('--category_filter', dest='category_filter', default=DEFAULT_CATEGORY_FILTER,
type=str, help='Search category_filter (default: %(default)s)')
input_values = parser.parse_args()
try:
query_api(input_values.term, input_values.location, input_values.offset, input_values.sort, input_values.category_filter)
except urllib2.HTTPError as error:
For example:
example.py
parser = argparse.ArgumentParser(description="Will take arguments... or none")
parser.add_argument("-a", action="store_true")
parser.add_argument("-b", action="store_true")
parser.add_argument("-c", action="store_true")
parser.add_argument("-d", action="store_true")
args = parser.parse_args()
print args
I want example.py to set a to True, but only if either:
The -a flag is used
No flags are used
I tried messing around with
parser.set_defaults(a=True, b=False)
and
parser.add_argument("-a", action="store_true", default=True)
but they will set a to True even if I decide to use the b flag.
yes using the default values will set a to True even other arguments are specified. This will violate your second requirement, following is a simple fix with a naive condition checking.
parser = argparse.ArgumentParser(description="Will take arguments... or none")
parser.add_argument("-a", action="store_true")
parser.add_argument("-b", action="store_true")
parser.add_argument("-c", action="store_true")
parser.add_argument("-d", action="store_true")
args = parser.parse_args()
if not (args.b or args.c or args.d):
args.a=True
print args
Sounds like you want a 'radio button' effect - choosing just one of several alternatives. An alternative to a set of flags would be an argument with choices.
parser.add_argument('flag', choices=['a','b','c','d'], default='a', nargs='?')
You can check the result in args.flag, which will be one of 4 strings.
Obviously the positional argument couple replaced by a flag, e.g. -f.
I went for the following solution:
parser = argparse.ArgumentParser(description="Will take arguments... or none")
lettergroup = parser.add_mutually_exclusive_group()
lettergroup.add_argument("-a", action="store_const", dest="letter", const="a", default="a")
lettergroup.add_argument("-b", action="store_const", dest="letter", const="b")
lettergroup.add_argument("-c", action="store_const", dest="letter", const="c")
lettergroup.add_argument("-d", action="store_const", dest="letter", const="d")
args = parser.parse_args()
Now, the value is stored in args.letter. If no flag is called, args.letter will have the value a. If two flags are called at the same time, the parser will throw an error.
Just another way to solve this problem.