当参数数量超过阈值时,Python argparse AssertionError

时间:2015-03-20 01:22:31

标签: python-2.7 argparse

我正在尝试编写一个包含很多参数的Python脚本,我希望使用argparse模块将其拆分为明确的组,如下所示:

import argparse
parser = argparse.ArgumentParser(description='Placeholder text', add_help=False)
req = parser.add_argument_group('required arguments')
req.add_argument('-m','--mode', action='store', dest='mode', help='Operation mode', choices=['single', 'multi'], required=True, metavar='')
req.add_argument('-s','--snps', action='store', dest='snps', help='SNP BED file', required=True, metavar='')
req.add_argument('-r','--reads', action='store', dest='reads', help='Mapped reads file [sam or bam]', required=True, metavar='')
uni = parser.add_argument_group('universal optional arguments')
uni.add_argument('-p','--prefix', action='store', dest='prefix', help='Prefix for temp files and output [Default: TEST]', default='TEST', metavar='')
uni.add_argument('-b','--bam', action='store_true', dest='bam', help='Mapped read file type is bam (auto-detected if *.bam)')
uni.add_argument('-t','--single', action='store_true', dest='single', help='Mapped reads are single-end [Default: False]')
uni.add_argument('-n','--noclean', action='store_true', dest='noclean', help='Do not delete intermediate files (for debuging)')
uni.add_argument('-h', '--help', action='help', help='show this help message and exit')
mult = parser.add_argument_group('multi(plex) mode arguments')
mult.add_argument('-j','--jobs', action='store', dest='jobs', type=int, help='Divide into # of jobs [Default: 100]', default=100, metavar='')
mult.add_argument('-w','--walltime', action='store', dest='walltime', help='Walltime for each job [Default: 3:00:00]', default='3:00:00', metavar='')
mult.add_argument('-k','--mem', action='store', dest='memory', help='Memory for each job [Default: 5000MB]', default='5000MB', metavar='')
single = parser.add_argument_group('single mode arguments')
single.add_argument('-f','--suffix', action='store', dest='suff', help='Suffix for multiplexed files [set automatically]', default='', metavar='')

args = parser.parse_args()

但是,当我运行此脚本时,使用'-h'选项,而不是打印帮助文本,它会发出以下错误:

Traceback (most recent call last):
  File "CountSNPLevelASE.py", line 61, in <module>
    args = parser.parse_args()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1688, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1720, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1926, in _parse_known_args
    start_index = consume_optional(start_index)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1866, in consume_optional
    take_action(action, args, option_string)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1794, in take_action
    action(self, namespace, argument_values, option_string)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 994, in __call__
    parser.print_help()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 2327, in print_help
    self._print_message(self.format_help(), file)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 2301, in format_help
    return formatter.format_help()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 279, in format_help
    help = self._root_section.format_help()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 209, in format_help
    func(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 330, in _format_usage
    assert ' '.join(opt_parts) == opt_usage
AssertionError

奇怪的是,如果我注释掉任何非必需参数,我会得到正确的帮助文本输出,如下所示:

usage: CountSNPLevelASE.py -m  -s  -r  [-b] [-t] [-n] [-h] [-j] [-w] [-k] [-f]

Placeholder text

required arguments:
  -m , --mode       Operation mode
  -s , --snps       SNP BED file
  -r , --reads      Mapped reads file [sam or bam]

universal optional arguments:
  -b, --bam         Mapped read file type is bam (auto-detected if *.bam)
  -t, --single      Mapped reads are single-end [Default: False]
  -n, --noclean     Do not delete intermediate files (for debuging)
  -h, --help        show this help message and exit

multi(plex) mode arguments:
  -j , --jobs       Divide into # of jobs [Default: 100]
  -w , --walltime   Walltime for each job [Default: 3:00:00]
  -k , --mem        Memory for each job [Default: 5000MB]

single mode arguments:
  -f , --suffix     Suffix for multiplexed files [set automatically]

我无法找到解释为什么会发生这种情况的明确解释。我已经尝试删除所有空格无济于事。有任何想法吗? (如果有帮助的话,我在Mac OS X 10.10.2上使用Python 2.7.6)。

2 个答案:

答案 0 :(得分:4)

问题在于包装用法。当usage适合一行时显示正常,但当它分成2时失败。

有一个涉及此assertion的已知错误问题。使用格式代码很脆弱,如果使用中包含“常用”字符,可能会引发此assertion错误,包括额外空格。

这是提出问题的3个必需参数的metavar=''。可选的选项可以有一个''metavar。

请注意短使用行中这些参数之间的双重空格?

...py -m  -s  -r  [-b]...

assertion error是那些没有完整包装代码的空格的结果。

如果您无法为这3个参数找到合适的替代元变量,那么我们必须弄清楚如何修改argparse代码。可能性包括评论断言声明,或从一行使用中删除那些额外的空白。最重要的解决方案是更强大的使用格式化程序。

答案 1 :(得分:0)

您的示例在OS X 10.10.2和Python 2.7.9上运行良好

我建议升级你的Python,因为Python 2.7.7包含几个与argparse相关的错误修正,请参阅changelog:

https://hg.python.org/cpython/raw-file/f89216059edf/Misc/NEWS