Python argparse AssertionError

ohc*_*mel 12 python argparse

我刚开始使用argparse模块.我编写了以下简化代码片段来演示我遇到的问题.

from argparse import ArgumentParser

if __name__ == '__main__':
    parser = ArgumentParser('Test argparse. This string needs to be relatively long to trigger the issue.')
    parser.add_argument('-f', '--fin', help='a', required = True)
    parser.add_argument('-o', '--out ', help='b', required = True)
    parser.add_argument('-t', '--trans', help='c', required = True)

    args = parser.parse_args()
    print(repr(vars(args)))
Run Code Online (Sandbox Code Playgroud)

AssertionError将使用参数-h运行脚本时生成

Traceback (most recent call last):
  File "arg.py", line 10, in <module>
    args = parser.parse_args()
  File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 1707, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 1739, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 1945, in _parse_known_args
    start_index = consume_optional(start_index)
  File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 1885, in consume_optional
    take_action(action, args, option_string)
  File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 1813, in take_action
    action(self, namespace, argument_values, option_string)
  File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 1017, in __call__
    parser.print_help()
  File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 2341, in print_help
    self._print_message(self.format_help(), file)
  File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 2325, in format_help
    return formatter.format_help()
  File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 278, in format_help
    help = self._root_section.format_help()
  File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 208, in format_help
    func(*args)
  File "C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py", line 329, in _format_usage
    assert ' '.join(opt_parts) == opt_usage
AssertionError
Run Code Online (Sandbox Code Playgroud)

减少传递给ArgumentParser的描述字符串的长度使其正常工作.删除其中一个参数也会有所帮助.

我在这里做错了吗?我的环境是:

Python 3.3.5 | Anaconda 1.9.2(64位)| (默认情况下,2014年3月10日,11:25:04)[winv上的MSC v.1600 64位(AMD64)]

eso*_*ton 11

--out代码后面有一个额外的空格.更改:

parser.add_argument('-o', '--out ', help='b', required = True)
Run Code Online (Sandbox Code Playgroud)

至:

parser.add_argument('-o', '--out', help='b', required = True)
Run Code Online (Sandbox Code Playgroud)

问题的根本原因是assert在Python代码中进行检查,这只有在Python试图将帮助文本分成多行时才会发生,因为它太长了.在将文本分成列表之后,Python代码将它连接在一起并将其与原始文件进行比较以确保它是正确的.但是,将文本分开的代码会丢弃相邻的空格,从而导致错误比较.

我在代码中添加了print(argparse.py,Python 2.7):

# wrap the usage parts if it's too long
text_width = self._width - self._current_indent
if len(prefix) + len(usage) > text_width:
    # break usage into wrappable parts
    part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
    opt_usage = format(optionals, groups)
    pos_usage = format(positionals, groups)
    opt_parts = _re.findall(part_regexp, opt_usage)
    pos_parts = _re.findall(part_regexp, pos_usage)
    print ' '.join(opt_parts)
    print opt_usage
    assert ' '.join(opt_parts) == opt_usage
Run Code Online (Sandbox Code Playgroud)

结果如下:

[-h] -f FIN -o OUT -t TRANS
[-h] -f FIN -o OUT  -t TRANS
Traceback (most recent call last):
  File "blah.py", line 9, in <module>
    args = parser.parse_args()
Run Code Online (Sandbox Code Playgroud)

注意OUT后的额外空间.

这解释了所有观察到的行为:

  • 必须足够长才能触发包装行为.
  • 删除--trans参数移动--out到最后否定行为.
  • 删除--out论点否定了behvaior.


pee*_*eol 8

我带着完全相同的问题/错误来到这里,但在--out. 我的问题是元变量设置为空字符串 ( metavar='')。改变它解决了问题。