ArgumentParser -h (help) will not work - python

I cannot get ArgumentParser to work. What's wrong with the following:
import argparse
parser=argparse.ArgumentParser(description='''I wish this description would output''',
epilog='''Please out the epilog''')
parser.add_argument('-l', type=str, default='info', help='logging level. Default is info. Use debug if you have problems.')
args=parser.parse_args()
def main():
print("goodbye")
if __name__ == "__main__":
#main
main()
When I run myscript -h I see no help.
I am running Python 2.7 on Windows 7. I have Python on my path and also pathext set as:
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.py

The argsparse code never actually gets executed. By executing the script from the command line, you're calling main(), which simply prints and exits. You have to call parse_args() in the main() function for this to work.
import argparse
# Personally, I think these belong in the main()
# function as well, but they don't need to be.
parser = argparse.ArgumentParser(
description="I wish this description would output",
epilog="Please out the epilog"
)
parser.add_argument(
"-l",
type=str,
default="info",
help="logging level. Default is info. Use debug if you have problems."
)
def main():
args = parser.parse_args() # Parses arguments
print("goodbye")
if __name__ == "__main__":
main() # Calls main
Produces:
~/Desktop $ python untitled.py --help
usage: untitled.py [-h] [-l L]
I wish this description would output
optional arguments:
-h, --help show this help message and exit
-l L logging level. Default is info. Use debug if you have problems.
Please out the epilog
jcollado claims your code worked fine on Ubuntu--I find this very curious.

If you run this script from the command line you're going to just print 'goodbye', put the argparse code after if __name__ == "__main__":.

OK weird answer for this. The problem was resolved by calling the program as:
python myscript.py -h
If you add python to your path, set file associations and then just do:
myscript.py -h
it will not pick up the -h

Related

some question when i use python_lib --click

here is my code from my demo.py:
import sys, click, os
#click.command()
#click.option('-f', '--file', required=True, help="file")
def tshark_do(file):
click.echo(file)
def two_function(DataFile="test"):
print(DataFile)
if __name__ == "__main__":
tshark_do()
two_function()
when i run python demo.py -f file, it just output file
seemd that the two_function() didn`t work
i guess that maybe it caused by #click.command() . but i don't know how to solve
please help your friend

How to call a python script with parsing arguments on jupyter notebook

I have a python script that I defined:
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--task', type=str)
parser.add_argument('--scale', type=int)
args = parser.parse_args()
... # Do things with my arguments
if __name__ == '__main__':
main()
And I call this script on command line doing:
python myscript.py --task mytask --scale 1
I would like to call this script in a jupyter notebook. Is there a way to do this parsing the arguments and not modifying my script at all? I.e., doing something that looks like to this:
import myscript
myscript.main(--task=mytask,scale=1)
P.S.: I tried using magic line such as %run (that probably could work in my case as well) but I had trouble collecting the returns of my script.
You can pass args to parser.parse_args:
# myscript.py
import argparse
def main(args=None):
parser = argparse.ArgumentParser()
parser.add_argument('--task', type=str)
parser.add_argument('--scale', type=int)
args = parser.parse_args(args=args)
print("task is: ", args.task)
print("scale is: ", args.scale)
if __name__ == "__main__":
main()
Output from cli:
python3 myscript.py --task aaa --scale 10
# task is: aaa
# scale is: 10
Output from python
import myscript
myscript.main("--task aaa --scale 10".split())
# task is: aaa
# scale is: 10

coverage.py: Why the expected lines are not marked green in html report?

Sample code:
#!/usr/bin/env python
import os
import sys
from coverage import Coverage
class Cover_Diy(object):
def cover_diy(self, cmd):
if cmd == "hostname":
os.system(cmd)
elif cmd == "uptime":
os.system(cmd)
else:
os.system(cmd)
def main(args):
covd = Cover_Diy()
covd.cover_diy(args[1])
if __name__ == "__main__":
cov = Coverage()
print dir(cov)
cov.start()
args = sys.argv
try:
sys.exit(main(args))
except Exception as ex:
print ex
cov.stop()
cov.html_report(directory="/home/username/scripts/html")
The code is executed using this command:
python sample.py hostname
Problem:
Lines 3,4,5,7,9,10,11,18 are marked as missing which means not executed, why is that so?
enter image description here
Your def and class lines are executed when the file is run. This happens before you start coverage on line 23. Coverage can't observe execution that happens before it is started.
You'll need to separate the code that runs coverage from the code you want coverage to measure. I'm not sure what the goal of this program is. Usually it's simpler to just use the coverage command line to run an existing Python program, and not use the coverage API at all.

subprocess.popen working on windows and not on ubuntu

I am trying to create a new process to run another python file using the following code.
proc = subprocess.Popen(["python test.py"],shell=True)#,stdout=DEVNULL, stderr=STDOUT
proc.wait()
It works on window but when I tried in an ubuntu console. It would trigger the python console/interpreter instead of running the python file.
Any help would be appreciated
As i commented the previews answer, do not use shell=True if you don't need it, please refer to python doc, there are serious security implication using this option.
working example:
╭─root#debi /tmp
╰─# cat 1.py
def main():
print("ok")
if __name__ == '__main__':
main()
╭─root#debi /tmp
╰─# cat 2.py
import subprocess
def main():
proc = subprocess.Popen(["python", "1.py"])
proc.wait()
if __name__ == '__main__':
main()
╭─root#debi /tmp
╰─# python3 2.py
ok
╭─root#debi /tmp
╰─#
You have to separate arguments python and test.py for the things to work properly:
proc = subprocess.Popen(["python", "test.py"],shell=True)
proc.wait()

Make my python command line program interactive with argparse

i'm trying to make my python program interactive in command line, user should be able to do stuff like :
python myprogram.py --create
then
python myprogram.py --send
The problem in this when is that the program stop and restart each time so i lose my variable and object that i created with the first command.
I'm using argparse on this way:
parser = argparse.ArgumentParser()
parser.add_argument('-c','--create' ,help='',action='store_true')
parser.add_argument('-s','--send',help='',action='store_true')
args = parser.parse_args()
if args.create:
create()
elif args.send :
send()
I don't want to stop the program between the command, how to do this ?
example : https://coderwall.com/p/w78iva
Here's a simple interactive script. I use argparse to parse the input lines, but otherwise it is not essential to the action. Still it can be an handy way of adding options to your 'create' command. For example, ipython uses argparse to handle its %magic commands:
import argparse
parser = argparse.ArgumentParser(prog='PROG', description='description')
parser.add_argument('cmd', choices=['create','delete','help','quit'])
while True:
astr = raw_input('$: ')
# print astr
try:
args = parser.parse_args(astr.split())
except SystemExit:
# trap argparse error message
print 'error'
continue
if args.cmd in ['create', 'delete']:
print 'doing', args.cmd
elif args.cmd == 'help':
parser.print_help()
else:
print 'done'
break
This could be stripped down to the while loop, the raw_input line, and your own evaluation of the astr variable.
The keys to using argparse here are:
parse_args can take a list of strings (the result of split()) instead of using the default sys.argv[1:].
if parse_args sees a problem (or '-h') it prints a message and tries to 'exit'. If you want to continue, you need to trap that error, hence the try block.
the output of parse_args is a simple namespace object. You access the arguments as attributes.
you could easily substitute your own parser.
The diffrence in cmd and argparse is that cmd is a "line-oriented command interpreter" while argparse is a parser for sys.argv.
Your example parses sys.argv that you pass while running your program and then if it gets the value you start a function and then quits.
argparse will only parse the sys.argv while running the program.
You could add some code to be able to work with the args you pass like a function or class or make in program menu that you could operate with raw_input.
Example:
class Main():
def __init__(self, create=None, send=None):
if create:
self.create(create)
elif send:
self.send(send)
option = raw_input('What do you want to do now?')
print option
def create(self, val):
print val
def send(self, val):
print val
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('-c','--create' ,help='',action='store_true')
parser.add_argument('-s','--send',help='',action='store_true')
args = parser.parse_args()
Main(args.create, args.send)
Other then that Python argparse and controlling/overriding the exit status code or python argparse - add action to subparser with no arguments? might help.
In the first it shows how you can override the quit and in the second how can you add subcommands or quitactions.

Categories