1

I need to use a python script having the following usages:

script.py ( commands ) ( options )

My problem is how i add arguments for "commands" and "options"?

What i did now is this:

parser = argparse.ArgumentParser()
parser._optionals.title = "Options"
parser.add_argument('-help','--help', action="store_true", dest="help", help='help')
subparsers = parser.add_subparsers(help="All available commands", title="Commands")

parser_start = subparsers.add_parser('start', help='Starts the script', add_help=False)
parser_start._optionals.title = "Options"
parser_start.add_argument('--help', action="store_true", dest="help_start")
parser_start.add_argument('-f', type=str, dest="file", help='simulation file to start')

parser_ls = subparsers.add_parser('ls', help='Lists running simulations', add_help=False)
parser_ls._optionals.title = "Options"
parser_ls.add_argument('--help', action="store_true", dest="help_ls")
parser_ls.add_argument('--all', action="store_true", help='Display all simulations')

parser_stop = subparsers.add_parser('stop', help='Stops simulation', add_help=False)
parser_stop._optionals.title = "Options"
parser_stop.add_argument('--help', action="store_true", dest="help_down")
parser_stop.add_argument('--sim-name', type=str, dest="sim_name")

args = parser.parse_args()

If i try to access args.help_up i receive: AttributeError: 'Namespace' object has no attribute 'help_start'

How do i pass the parser_up, parser_stop and parser_ls to the parse_args? And how do i access them afterwards?

Objective is to have custom help messages ( which i have atm that is why i disabled the help ) and to run the script like this:

script.py start -f (name of file)
script.py stop --sim-name (name of simulation)

EDIT:

If i add args2 = parser_start.parse_args() i am able to get a read on args2.help_start, but i am not able to find any of the start, ls or down arguments!

hpaulj
  • 221,503
  • 14
  • 230
  • 353
happymatei
  • 113
  • 1
  • 12

1 Answers1

1

I've made a few changes to your code; hopefully it will clarify what's going on:

import argparse

parser = argparse.ArgumentParser()
parser._optionals.title = "Options"
#parser.add_argument('-help','--help', action="store_true", dest="help", help='help')
# conflicts with original help
subparsers = parser.add_subparsers(help="All available commands", title="Commands",
       dest='cmd')    # NEW

parser_start = subparsers.add_parser('start', help='Starts the script', add_help=False)
parser_start._optionals.title = "Options"
parser_start.add_argument('--help', action="store_true", dest="help_start")
parser_start.add_argument('-f', type=str, dest="file", help='simulation file to start')

parser_ls = subparsers.add_parser('ls', help='Lists running simulations', add_help=False)
parser_ls._optionals.title = "Options"
parser_ls.add_argument('--help', action="store_true", dest="help_ls")
parser_ls.add_argument('--all', action="store_true", help='Display all simulations')

parser_stop = subparsers.add_parser('stop', help='Stops simulation', add_help=False)
parser_stop._optionals.title = "Options"
parser_stop.add_argument('--help', action="store_true", dest="help_down")
parser_stop.add_argument('--sim-name', type=str, dest="sim_name")

args = parser.parse_args()

print(args)      # NEW

and sample runs:

0939:~/mypy$ python3 stack62716530.py 
Namespace(cmd=None)
0939:~/mypy$ python3 stack62716530.py --help
usage: stack62716530.py [-h] {start,ls,stop} ...

Options:
  -h, --help       show this help message and exit

Commands:
  {start,ls,stop}  All available commands
    start          Starts the script
    ls             Lists running simulations
    stop           Stops simulation
0939:~/mypy$ python3 stack62716530.py start
Namespace(cmd='start', file=None, help_start=False)
0939:~/mypy$ python3 stack62716530.py start --help
Namespace(cmd='start', file=None, help_start=True)

and if I add:

if getattr(args, 'help_start',False):
    parser_start.print_help()

I get

0940:~/mypy$ python3 stack62716530.py start --help
Namespace(cmd='start', file=None, help_start=True)
usage: stack62716530.py start [--help] [-f FILE]

Options:
  --help
  -f FILE  simulation file to start

The key is that help_start is an attribute only if the start subparser is invoked.

In first read(s) of your code I missed the dest='help_start' parameters. Thus I couldn't tell why you expected to see such an attribute in args.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • Thanks for answering, problem is i did this and it works for help_start, but it does not find help_ls and help_down. I receive *** AttributeError: 'Namespace' object has no attribute 'help_start' *** when trying to run script.py ls --help or stop --help. – happymatei Jul 03 '20 at 23:22
  • Of course `help_start` won't be present when you use 'ls' or 'stop' 'help_ls' isn't present in my sample run either! That's why I use `getattr`. I asked you to look at the `args` namespace before trying to use it. You need to understand what attributes are set when using different subparsers. – hpaulj Jul 04 '20 at 02:50
  • I understand that help_start won't be present, it is what i want. Please try for yourself also. Problem is i can't use the ls and stop --help arguments because it tells me i can't find help_start. Sorry if i don't understand it correctly, but this behavior is not what i want. I want when ls command is available to be able to use the ls arguments only and when start or stop are invoked, to use theirs. At the moment it is stopping me from using that! Best regards – happymatei Jul 04 '20 at 08:32