I have a file structure like this:
project/
main_prog.py
tools/
script.py
md_script/
__init__.py
md_script.py
I search in tools for local python modules. In this example it's md_script. And i want to use it as positional argument like install in my code, but when i use it, I'v got an error:
./jsh.py md_script
usage: jsh.py [-h] {install,call,list,log,restore} ... [md_script]
jsh.py: error: invalid choice: 'md_script' (choose from 'install', 'call', 'list', 'log', 'restore')
python3.4 on ubuntu14.10 Here is my code:
parser = argparse.ArgumentParser(prog='jsh.py',
description='Some help.', epilog='Example of usage: some help')
subparsers = parser.add_subparsers()
parser_install = subparsers.add_parser('install', help = 'Install new project.')
parser_install.add_argument('install', nargs='?', help = 'Name of project to be installed')
if os.path.isdir(full/path/to/tools/):
name_arg = next(os.walk(full/path/to/tools))[1]
tools_arg = parser.add_argument_group('Tools', 'Modules from tools')
for element in name_arg:
tools_arg.add_argument(element, nargs='?', help='md_script description')
args = parser.parse_args()
try:
if not len(sys.argv) > 1:
parser.print_help()
elif 'install' in args:
do_some_stuff
elif element in args:
do_some_md_script_stuff
else:
parser.print_help()
The
usage
line shows what's wrong:You need to use something like
You specified subparsers, so you have to give it a subparser name.
From the
usage
it also looks like you created other subparsers,call
,list
, etc that you don't show in the code.You also define positional arguments after creating subparser. That's where the
[md_script]
comes from. Be careful about making a lot ofnargs='?'
positionals (including the argument for theinstall
subparser). This could make things confusing for your users. In fact it seems to confusing you. Remember thatsubparser
is in effect a positional argument (one that requires 1 string).I'd suggest experimenting with a simplier parser before creating one this complicated.
So from your comments and examples I see that you goal is let the user name a module, so your script can invoke it in some way or other. For that populating the subparsers with these names makes sense.
I wonder why you also create an optional positional argument with the same name:
Is that because you are using the presence of the attribute as evidence that this subparser was invoked?
The
argparse
documentation has a couple of other ideas.and
These avoid the messiness of a '?' positional argument, freeing you to use subparser arguments for real information.
Now you can check:
or
With the alternative
set_defaults
, your original test should still work: