简体   繁体   中英

Argparse arguments number limits

I'm trying to convert a bash script into a python script, and I have to create a lot of argument with Argparser. When I run the code with this arguments I obtain the error

'
  File "/home/lmonari/anaconda3/envs/ChemFlowOfficial/lib/python3.9/argparse.py", line 338, in _format_usage
    assert ' '.join(opt_parts) == opt_usage

AssertionError'

If I randomly comment some arguments, the code works fine. Have I reached the maximum number of arguments for Argparse? I don't find anywhere a documented limit

The code:

create a parser for command line

parser = argparse.ArgumentParser(add_help=False)

# format the argument groups
parser._action_groups.pop()

# help arguments
help_args = parser.add_argument_group('[ Help ] ')
help_args.add_argument('-h', '--help', action='store_true',
                       help='Show this help message and exit.' )
help_args.add_argument("-H","--Help", action='help',
                    help="Detailed help.")                       

# checking the short help from the terminal_input
terminal_input=sys.argv
if '-h' in terminal_input or '--help' in terminal_input:
    DockFlow_help_short()
    parser.exit()
    
# required arguments
required = parser.add_argument_group('[ Required ] ')
required.add_argument('-p',"---project", metavar='',
                    help="STR : ChemFlow project.")
# required.add_argument("-r","--receptor", metavar='',
#                     help="Receptor's mol2 file.", required=True)
# required.add_argument("-l","--ligand", metavar='',
#                     help="FILE : Ligands  MOL2 file.", required=True) 
# required.add_argument("-dp","--program", metavar='',
#                     help="STR : plants, vina, qvina, smina.", required=True) 

# post processing
post_pro = parser.add_argument_group('[ Post Processing ]')
post_pro.add_argument("--postprocess", metavar='',
                      help="Process DockFlow output for the specified project/protocol/receptor.")
post_pro.add_argument("--postprocess-all", metavar='',
                      help="Process DockFlow output in a ChemFlow project.")
post_pro.add_argument('-n',"--n_poses", metavar='',
                      help="INT : Number of docked poses to keep.")
# post_pro.add_argument("--archive", metavar='',
#                       help="Compress the docking folders for the specified project/protocol/receptor.")
# post_pro.add_argument("--archive_all", metavar='',
#                       help="Compress the docking folders in a ChemFLow project.")


# optional argument
optional = parser.add_argument_group('[ Optional ]')
# optional.add_argument("-t","--test", metavar='',
#                     help="STR : Name for this specific protocol [default].") 
# optional.add_argument("-z",'--zeta', default="It's a trap", metavar='',
#                     help="testline", action=None) 

optional.add_argument('--foo', help=argparse.SUPPRESS)

parser.parse_args()

If I uncomment all your arguments, and use a parser.print_usage() on a wide enough screen I get

1155:~/mypy$ python3 stack71486789.py 
usage: stack71486789.py [-h] [-H] [-p] -r  -l  -dp  [--postprocess] [--postprocess-all] [-n] [--archive] [--archive_all] [-t] [-z]

On a narrower screen it tries to split usage into several lines, and hits

1155:~/mypy$ python3 stack71486789.py 
Traceback (most recent call last):
  File "stack71486789.py", line 56, in <module>
    parser.print_usage()
  File "/usr/lib/python3.8/argparse.py", line 2501, in print_usage
    self._print_message(self.format_usage(), file)
  File "/usr/lib/python3.8/argparse.py", line 2467, in format_usage
    return formatter.format_help()
  File "/usr/lib/python3.8/argparse.py", line 294, in format_help
    help = self._root_section.format_help()
  File "/usr/lib/python3.8/argparse.py", line 225, in format_help
    item_help = join([func(*args) for func, args in self.items])
  File "/usr/lib/python3.8/argparse.py", line 225, in <listcomp>
    item_help = join([func(*args) for func, args in self.items])
  File "/usr/lib/python3.8/argparse.py", line 349, in _format_usage
    assert ' '.join(opt_parts) == opt_usage

The usage formatter is brittle. If the usage as displayed above is too long, tries to split it. The assert is supposed to check that the split was done right. The metavars are messing that up. This problem is well known.

If I comment out all the metavar , the working multiline usage is:

1202:~/mypy$ python3 stack71486789.py 
usage: stack71486789.py [-h] [-H] [-p PROJECT] -r RECEPTOR -l LIGAND -dp PROGRAM [--postprocess POSTPROCESS]
                        [--postprocess-all POSTPROCESS_ALL] [-n N_POSES] [--archive ARCHIVE] [--archive_all ARCHIVE_ALL]
                        [-t TEST] [-z ZETA]

and full help

1203:~/mypy$ python3 stack71486789.py 
usage: stack71486789.py [-h] [-H] [-p PROJECT] -r RECEPTOR -l LIGAND -dp PROGRAM [--postprocess POSTPROCESS]
                        [--postprocess-all POSTPROCESS_ALL] [-n N_POSES] [--archive ARCHIVE] [--archive_all ARCHIVE_ALL]
                        [-t TEST] [-z ZETA]

[ Help ] :
  -h, --help            Show this help message and exit.
  -H, --Help            Detailed help.

[ Required ] :
  -p PROJECT, ---project PROJECT
                        STR : ChemFlow project.
  -r RECEPTOR, --receptor RECEPTOR
                        Receptor's mol2 file.
  -l LIGAND, --ligand LIGAND
                        FILE : Ligands MOL2 file.
  -dp PROGRAM, --program PROGRAM
                        STR : plants, vina, qvina, smina.

[ Post Processing ]:
  --postprocess POSTPROCESS
                        Process DockFlow output for the specified project/protocol/receptor.
  --postprocess-all POSTPROCESS_ALL
                        Process DockFlow output in a ChemFlow project.
  -n N_POSES, --n_poses N_POSES
                        INT : Number of docked poses to keep.
  --archive ARCHIVE     Compress the docking folders for the specified project/protocol/receptor.
  --archive_all ARCHIVE_ALL
                        Compress the docking folders in a ChemFLow project.

[ Optional ]:
  -t TEST, --test TEST  STR : Name for this specific protocol [default].
  -z ZETA, --zeta ZETA  testline

Shorter metavar without special characters or blank should also work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM