簡體   English   中英

Python argparse AssertionError

[英]Python argparse AssertionError

我剛開始使用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

減少傳遞給ArgumentParser的描述字符串的長度使其正常工作。 刪除其中一個參數也會有所幫助。

我在這里做錯了嗎? 我的環境是:

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

代碼中的--out有一個額外的空格。 更改:

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

至:

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

問題的根本原因是Python代碼中的assert檢查只有在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

結果如下:

[-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()

注意OUT后的額外空間。

這解釋了所有觀察到的行為:

  • 必須足夠長才能觸發包裝行為。
  • 刪除--trans參數移動--out到結尾否定行為。
  • 刪除--out參數否定了behvaior。

問題不在於您添加的額外-h。 查看錯誤和-o參數:

assert ' '.join(opt_parts) == opt_usage

它正在加入'--out '的空白'--out ' 如果你刪除它,一切都應該正常。

我帶着完全相同的問題/錯誤來到這里,但是在--out之后沒有任何額外的空格。 我的問題是metavar被設置為空字符串( metavar='' )。 改變這解決了問題。

Python 3.5.2

它讓我瘋狂了一段時間,但我終於找到了問題。 這肯定是一個使用行長度問題,如果它超過為控制台/終端設置的COLUMNS環境變量,則會出現該錯誤。 我從命令行嘗試:

$ COLUMNS=80 python <myprog.py> -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=<XX> python <myprog.py> -h

結果使用行的XX>,一切正常,它打印用法+幫助並退出。 因此,要么縮短使用線,要么增加COLUMNS值。

編輯:

我在我的案例中發現了錯誤:我在程序/參數描述中使用了方括號[]

正如其他人正確指出的那樣,查看發生異常的python代碼,您可以看到argparse有一個自動將使用/幫助折疊到$COLUMNS列的規定。 但要分割長行,它使用以下RE:

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

`part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'`

當它重新加入要檢查的行時,如果用戶引入了方括號,則斷言失敗,因為它們是argparse用來標記可選值的特殊字符。

簡而言之,我從文本中刪除了流氓方括號,一切正常,使用/幫助正確折疊並根據$COLUMNS值進行格式化。

對我來說,它設置了required = True和metavar =''。 刪除一個並保持另一個解決它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM