I have been Googling this problem most of the morning and find no solution.
Using the following:
parser.add_argument('-t', '--task', dest='task', action='store')
args = parser.parse_args(cmd_args)
When cmd_args contains "['-t my_task']" everything works as I expect.
When cmd_args contains "['--task my_task']" an exception is thrown.
The important part of the error says: "error: unrecognized arguments: --task mytask"
Related
I have a script which basically asks the user for the argument to be passed to the program as below:
parser = argparse.ArgumentParser()
parser.add_argument("-t" , required = True)
args , unknown = parser.parse_known_args()
#rest of the code
Now I wanna do error handling so it shows the message I want and run the functions I want in case the user didn't enter the argument or entered it incorrectly. I have tried putting everything in try and except however I couldn't find the proper error type to do it for me
try:
parser = argparse.ArgumentParser()
parser.add_argument("-t" , required = True)
args , unknown = parser.parse_known_args()
#rest of the code
except argparse.ArgumentError:
myfunc()
However, this way if I get any other errors in my code, it still caught here and not in their own try and except.
Argparse raises a SystemExit when a required argument is missing.
You could use the else clause in the try/except to execute the rest of your code only if the arguments were parsed correctly:
try:
parser = argparse.ArgumentParser()
parser.add_argument("-t" , required = True)
args , unknown = parser.parse_known_args()
except SystemExit:
func_for_wrong_args()
else:
func_for_correct_args()
I have to implement a --pos flag in Python and create a new condition if it exists, but argparse does not recognize it when I enter it in the command line argument.
parser = argparse.ArgumentParser()
parser.add_argument('lang', type=str, help='Language')
parser.add_argument('mode', help='the mode you want to output the results with')
parser.add_argument('flag', help='the flag that triggers pos-tags')
args = parser.parse_args()
So when I run the command:
python3 pi.py en lemma --pos
I get the following error message:
error: unrecognized arguments: --pos
Is there a way to catch that flag as a third argument?
In your code you are defining a "positional argument" which is not what you want. If you want to implement a flag (true/false) --pos just do that.
...
parser.add_argument('--pos', action='store_true', help='the flag that triggers pos-tags')
args = parser.parse_args()
if args.pos:
...
and call it as
python3 pi.py en lemma --pos
I have a python script that requires the user to enter two arguments to run it, the arguments could be named anything.
I have also used argparse to allow the users to use a switch '-h' to get instructions of what is required to run the script.
The problem is that now I have used argparse I am getting an error when I pass my two randomly named arguments with the script.
import argparse
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-h', '--help', action='help',
help='To run this script please provide two arguments')
parser.parse_args()
currently when I run python test.py arg1 arg2 the error is
error: unrecognized arguments: arg1 arg2
I would like the code to allow the user to run test.py with a -h if required to see the instructions but also allow them to run the script with any two arguments as well.
Resolution with help tag to provide the user with context regarding the arguments required.
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-h', '--help', action='help', help='To run this script please provide two arguments: first argument should be your scorm package name, second argument should be your html file name. Note: Any current zipped folder in the run directory with the same scorm package name will be overwritten.')
parser.add_argument('package_name', action="store", help='Please provide your scorm package name as the first argument')
parser.add_argument('html_file_name', action="store", help='Please provide your html file name as the second argument')
parser.parse_args()
Try the following code :-
import argparse
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-h', '--help', action='help',
help='To run this script please provide two arguments')
parser.add_argument('arg1')
parser.add_argument('arg2')
args, unknown = parser.parse_known_args()
All your unknown arguments will be parsed in unknown and all known in args.
import argparse
parser = argparse.ArgumentParser(description='sample')
# Add mandatory arguments
parser.add_argument('arg1', action="store")
parser.add_argument('arg2', action="store")
# Parse the arguments
args = parser.parse_args()
# sample usage of args
print (float(args.arg1) + float(args.arg2))
You need to add those arguments to the parser:
parser.add_argument("--arg1", "-a1", dest='arg1', type=str)
parser.add_argument("--arg2","-a2", dest='arg2', type=str)
If those arguments don't have the param required=true, you will be able to call the program without this arguments, so you can run the program with only the -h flag. To run the program with the arguments:
python test.py --arg1 "Argument" --arg2 "Argument"
Then, to have the arguments in variables you have to read them:
args = parser.parse_args()
argument1=args.arg1
argument2=args.arg2
I am creating an app with Click in python 3.6. I seem to have an error that I cannot find. I have posted my code below.
The problem is that when I type:
python clickapp.py --help
all is good. But when I type
python clickapp.py simplerequest --help
I get an error indicating that I am missing the argument "directory", but there is no traceback to indicate the source of the error. The exact output is:
Usage: clickapp.py [OPTIONS] STARTDATE ENDDATE DIRECTORY COMMAND [ARGS]...
Error: Missing argument "directory".
Here is the code that I used. This is a minimal example with filename clickapp.py.
import click
#click.group()
#click.argument('startdate')
#click.argument('enddate')
#click.argument('directory', type=click.Path())
#click.pass_context
def cli(ctx,
startdate,
enddate,
directory):
ctx.obj['directory'] = directory
ctx.obj['startdate'] = startdate
ctx.obj['enddate'] = enddate
#click.command()
#click.argument('arg1', type=str)
#click.argument('arg2', type=click.Path(exists=True))
#click.argument('arg3', type=int)
#click.pass_context
def SimpleRequest(ctx,
arg1,
arg2,
arg3):
"""Simple request processor"""
ctx.obj['arg1'] = arg1
ctx.obj['arg2'] = arg2
ctx.obj['arg3'] = arg3
cli.add_command(SimpleRequest)
if __name__ == '__main__':
cli(obj={})
Can anyone see the source of the error?
I tried a few things:
I removed the type=click.Path(exists=True) in arg2 to see if that might be causing the problem. But that did not change anything.
I also tried to remove some validation logic around inserting the variables into the ctx dictionary, but that did not help either.
Your help parsing problem is that click is attempting to fill in the startdate endate directory arguments first.
So your simplerequest --help fills in the first two and then it complains that the third (directory) is missing.
Usually the command (simplerequest) would be the first argument. You could then add optional args before, since click can easily distinguish those from the command.
Or you could coerce click to see the first arg as a valid command and do the help anyways, but this is non-standard and would require some code. Also it would preclude the command name being the start date, although they are likely easily differentiated.
I am trying to upgrade from pythons now deprecated optparse module into the new argparse module. However I am having some trouble upgrading my code. I have been using pythons documentation on doing just that yet I seem to have hit a wall.
Here is the original snippet of code using the optparse module
if __name__ == "__main__":
parser = optparse.OptionParser(usage="%prog [options] hostname")
parser.add_option("-p","--port", dest="port",
help="Port to use for socket connection [default: %default]",
default=33434, metavar="PORT")
parser.add_option("-m", "--max-hops", dest="max_hops",
help="Max hops before giving up [default: %default]",
default=30, metavar="MAXHOPS")
(options, args) = parser.parse_args()
if len(args) != 1:
parser.error('Incorrect number of arguments')
else:
dest_name = args[0]
sys.exit(main(dest_name=dest_name,
port=int(options.port),
max_hops=int(options.max_hops)))
Now here is the partial upgraded code I was able to do
if __name__ == "__main__":
parser = argparse.ArgumentParser(usage="%(prog)s [options] hostname")
parser.add_argument("-p","--port", dest="port",
help="Port to use for socket connection [default: %(default)s]",
default=33434, metavar="PORT")
parser.add_argument("-m", "--max-hops", dest="max_hops",
help="Max hops before giving up [default: %(default)s]",
default=30, metavar="MAXHOPS")
args = parser.parse_args()
if len(sys.argv) != 1:
parser.error('Incorrect number of arguments')
else:
dest_name = sys.argv
sys.exit(main(dest_name=dest_name,
port=int(options.port),
max_hops=int(options.max_hops)))
When I try running the code I keep receiving this error:
*port=int(options.port),
NameError: name 'options' is not defined*
In the optparse() module I defined it here
(options, args) = parser.parse_args()
When I tried to define it the same way as the optparse module it gives me another error:
*TypeError: 'Namespace' object is not iterable*
(I understand that the (options, args) = parser.parse_args() was changed to args = parser.parse_args() in the argparse module. I was just messing around trying to find a solution. I was desperate at this point)
Finally I tried to change 'options' in port=int(options.port) to port=int(args.port) Which gave me even more errors. After reading the documentation about upgrading optparse to argparse I think I might know where my problems resides. The documentation states
"Replace options, args = parser.parse_args() with args = parser.parse_args() and add additional add_argument() calls for the positional arguments."
So I think my problem is that I'm not adding the additional add_argument() calls for the positional arguments. Since I am new and still trying to learn pythons parsing modules I do not know exactly how to go about accomplishing that.
Get rid of this optparse bollocks:
if len(sys.argv) != 1:
parser.error('Incorrect number of arguments')
else:
dest_name = sys.argv
And add a positional argument instead
parser.add_argument('hostname')
...
dest_name = args.hostname