Python argparse断言错误

Python argparse断言错误,python,argparse,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

我刚开始使用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)))
使用参数-h运行脚本时将生成
AssertionError

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
回溯(最近一次呼叫最后一次):
文件“arg.py”,第10行,在
args=parser.parse_args()
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第1707行,在parse\u args中
args,argv=self.parse\u known\u args(args,名称空间)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第1739行,位于parse\u known\u args中
名称空间,args=self.\u解析\u已知\u args(args,名称空间)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第1945行,在_parse\u known\u args中
开始索引=消耗索引可选(开始索引)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第1885行,在consume\u optional中
执行操作(操作、参数、选项字符串)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第1813行,在take\u action中
操作(自身、名称空间、参数值、选项字符串)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第1017行,在调用中__
parser.print_help()
打印帮助中的文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第2341行
self.\u打印消息(self.format\u help(),文件)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第2325行,格式为\u help
返回格式化程序。格式化\u帮助()
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第278行,格式为\u help
help=self.\u root\u section.format\u help()
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第208行,格式为\u help
func(*args)
文件“C:\Users\user\AppData\Local\Continuum\Anaconda\envs\py3k\lib\argparse.py”,第329行,格式为
断言“”。连接(opt_部分)=opt_用法
断言错误
减少传递给ArgumentParser的描述字符串的长度可以使其正常工作。删除其中一个参数也会有所帮助

我做错什么了吗?我的环境是:

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


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

parser.add_argument('-o', '--out ', help='b', required = True)
致:

问题的根本原因是Python中的
assert
检查 仅当Python尝试将帮助文本拆分为 多行,因为太长。将文本拆分为列表后, Python代码将其重新连接在一起,并将其与原始代码进行比较 确保它是正确的。但是,将文本分开的代码会丢失 导致错误比较的相邻空间

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

结果是:

[-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()
[-h]-f FIN-o OUT-t TRANS
[-h]-f FIN-o OUT-t变速器
回溯(最近一次呼叫最后一次):
文件“blah.py”,第9行,在
args=parser.parse_args()
注意输出后的额外空间

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

  • 必须足够长才能触发包裹行为
  • 删除
    --trans
    参数将
    --out
    移动到否定行为的末尾
  • 删除
    --out
    参数否定了behvaior

    • 问题不在于您添加的额外-h。查看错误和
      -o
      参数:

      assert ' '.join(opt_parts) == opt_usage
      

      它在
      '--out'
      中加入空格。如果删除它,一切都会正常工作。

      我来到这里时遇到了完全相同的问题/错误,但在
      --out
      之后没有任何额外的空格。我的问题是metavar被设置为空字符串(
      metavar='
      )。更改解决了问题。

      Python 3.5.2

      这让我疯狂了一段时间,但我终于发现了问题所在。 这肯定是一个使用行长度问题,如果它超过了为控制台/终端设置的
      COLUMNS
      环境变量,则会出现该错误。 我尝试从命令行执行以下操作:

      $COLUMNS=80 python-h

      我得到一个例外:

      ...
        File "/usr/lib/python3.5/argparse.py", line 1735, in parse_args
          args, argv = self.parse_known_args(args, namespace)
        File "/usr/lib/python3.5/argparse.py", line 1767, in parse_known_args
          namespace, args = self._parse_known_args(args, namespace)
        File "/usr/lib/python3.5/argparse.py", line 1973, in _parse_known_args
          start_index = consume_optional(start_index)
        File "/usr/lib/python3.5/argparse.py", line 1913, in consume_optional
          take_action(action, args, option_string)
        File "/usr/lib/python3.5/argparse.py", line 1841, in take_action
          action(self, namespace, argument_values, option_string)
        File "/usr/lib/python3.5/argparse.py", line 1025, in __call__
          parser.print_help()
        File "/usr/lib/python3.5/argparse.py", line 2367, in print_help
          self._print_message(self.format_help(), file)
        File "/usr/lib/python3.5/argparse.py", line 2351, in format_help
          return formatter.format_help()
        File "/usr/lib/python3.5/argparse.py", line 287, in format_help
          help = self._root_section.format_help()
        File "/usr/lib/python3.5/argparse.py", line 217, in format_help
          func(*args)
        File "/usr/lib/python3.5/argparse.py", line 338, in _format_usage
          assert ' '.join(opt_parts) == opt_usage
      AssertionError
      
      但是:

      $COLUMNS=python-h

      其中XX>的结果用法行,一切正常,它打印用法+帮助并退出。 因此,要么缩短使用行,要么增加

      编辑:

      我在案例中发现了错误:我在程序/参数描述中使用了方括号
      []

      正如其他人正确指出的那样,查看发生异常的python代码,您可以看到argparse有一个自动将用法/帮助折叠到
      $COLUMNS
      COLUMNS的规定。 但要拆分长行,它将使用以下RE:

      (文件“/usr/lib/python3.5/argparse.py”,第333行:)

      当它重新加入行以进行检查时,如果用户引入了方括号,则断言失败,因为它们是argparse用来标记可选值的特殊字符


      简而言之,我从文本中删除了rogue方括号,一切正常,用法/帮助根据
      $COLUMNS
      值正确折叠和格式化。

      对我来说,它同时设置了required=True和metavar=''。删除一个并保留另一个解决了这个问题。

      请记住,
      ArgumentParser.\uuuu init\uuuu
      实际上并不接受位置参数。给定关键字参数的定义顺序,您将传递一个非常长的字符串来初始化
      prog
      属性,该属性用于存储出现在帮助消息中的程序名。您试图用该字符串初始化哪个属性?部分问题在于您不是sp
      assert ' '.join(opt_parts) == opt_usage
      
      ...
        File "/usr/lib/python3.5/argparse.py", line 1735, in parse_args
          args, argv = self.parse_known_args(args, namespace)
        File "/usr/lib/python3.5/argparse.py", line 1767, in parse_known_args
          namespace, args = self._parse_known_args(args, namespace)
        File "/usr/lib/python3.5/argparse.py", line 1973, in _parse_known_args
          start_index = consume_optional(start_index)
        File "/usr/lib/python3.5/argparse.py", line 1913, in consume_optional
          take_action(action, args, option_string)
        File "/usr/lib/python3.5/argparse.py", line 1841, in take_action
          action(self, namespace, argument_values, option_string)
        File "/usr/lib/python3.5/argparse.py", line 1025, in __call__
          parser.print_help()
        File "/usr/lib/python3.5/argparse.py", line 2367, in print_help
          self._print_message(self.format_help(), file)
        File "/usr/lib/python3.5/argparse.py", line 2351, in format_help
          return formatter.format_help()
        File "/usr/lib/python3.5/argparse.py", line 287, in format_help
          help = self._root_section.format_help()
        File "/usr/lib/python3.5/argparse.py", line 217, in format_help
          func(*args)
        File "/usr/lib/python3.5/argparse.py", line 338, in _format_usage
          assert ' '.join(opt_parts) == opt_usage
      AssertionError
      
      `part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'`