2016-12-12 7 views
2

以下は、3つの独立して動作するコード行が一緒に実行されても機能しない興味深いケースを示していますが、フラグ名文字列を " "、" - b "など、または個々のフラグのいずれかをコメントアウトする場合に使用します。テストスクリプトの使用法は、テストスクリプトの外部パーサに含まれています。このパーサは、さまざまな内部テストパーサを起動します。パーサーa、b、cはすべて同じですが、それぞれ1つのフラグがコメントアウトされています。これらのパーサのための助けはすべて働きます。壊れたパーサは、すべてのフラグが現在アクティブ(コメントではありません)である場合を除き、他のフラグと同じです。argparse大括弧を持つmetavarを持つAssertionError

私は本当になぜこれが当てはまるのかわかりません。なぜなら、フラグはそれぞれ独自のメモリ割り当てとすべてのもので互いに独立したオブジェクトでなければならないからです。不思議なことに、 '[lin] | log'でフラグ名またはビットのランダムビットを変更するだけで、これも修正されます。これはパーサーdで示されています。

私はこれをバグとして報告しますが、実際にどの部分が壊れているのか、コードやargparseはわかりません。失敗したときのエラーはこれを特定するのにはあまり役に立ちませんが、argparseに何か間違っていると思われます。

from __future__ import print_function 
import argparse 
from pdb import set_trace as br 
mainparser=argparse.ArgumentParser(description='select whether to work or fail') 
mainparser.add_argument('p',action='store',type=str,metavar='[working_a|working_b|working_c|working_d|broken]', help='Type "working_a" or "working_b" or "working_c" or "working_d" or "broken" to see the parser succeed or fail') 

working_parser_a=argparse.ArgumentParser(description='a') 
# working_parser_a.add_argument('-cmap',metavar='hot_desaturated',nargs=1,default='hot_desaturated',help='Colormap to use for colorbar') 
working_parser_a.add_argument('-cbar_scale',metavar='[lin]|log',nargs=1,type=str,default='lin',help='Linear or log scale colormap') 
working_parser_a.add_argument('-title',metavar='The Plot Title',type=str,nargs=1,help='Define the plot title that goes above the plot') 

working_parser_b=argparse.ArgumentParser(description='b') 
working_parser_b.add_argument('-cmap',metavar='hot_desaturated',nargs=1,default='hot_desaturated',help='Colormap to use for colorbar') 
# working_parser_b.add_argument('-cbar_scale',metavar='[lin]|log',nargs=1,type=str,default='lin',help='Linear or log scale colormap') 
working_parser_b.add_argument('-title',metavar='The Plot Title',type=str,nargs=1,help='Define the plot title that goes above the plot') 

working_parser_c=argparse.ArgumentParser(description='c') 
working_parser_c.add_argument('-cmap',metavar='hot_desaturated',nargs=1,default='hot_desaturated',help='Colormap to use for colorbar') 
working_parser_c.add_argument('-cbar_scale',metavar='[lin]|log',nargs=1,type=str,default='lin',help='Linear or log scale colormap') 
# working_parser_c.add_argument('-title',metavar='The Plot Title',type=str,nargs=1,help='Define the plot title that goes above the plot') 

broken_parser=argparse.ArgumentParser(description='e') 
broken_parser.add_argument('-cmap',metavar='hot_desaturated',help='') 
broken_parser.add_argument('-cbar_scale',metavar='[lin]|log',default='lin',help='') 
broken_parser.add_argument('-title',metavar='The Plot Title',help='') 

working_parser_d=argparse.ArgumentParser(description='d') 
working_parser_d.add_argument('-a',metavar='hot_desaturated',nargs=1,default='hot_desaturated',help='Colormap to use for colorbar') 
working_parser_d.add_argument('-b',metavar='[lin]|log',nargs=1,type=str,default='lin',help='Linear or log scale colormap') 
working_parser_d.add_argument('-c',metavar='The Plot Title',type=str,nargs=1,help='Define the plot title that goes above the plot') 

args=mainparser.parse_args() 
if args.p=='working_a': 
    working_parser_a.parse_args(['-h']) 
elif args.p=='working_b': 
    working_parser_b.parse_args(['-h']) 
elif args.p=='working_c': 
    working_parser_c.parse_args(['-h']) 
elif args.p=='working_d': 
    working_parser_d.parse_args(['-h']) 
elif args.p=='broken': 
    broken_parser.parse_args(['-h']) 
else: 
    p=args.p 
    print("The argument "+p+" is not a valid parser",file=sys.stderr) 
    mainparser.parse_args(['-h']) 

出力: 作業パーサー:

ζ python test.py working_a 
usage: test.py [-h] [-cbar_scale [lin]|log] [-title The Plot Title] 

a 

optional arguments: 
    -h, --help   show this help message and exit 
    -cbar_scale [lin]|log 
         Linear or log scale colormap 
    -title The Plot Title 
         Define the plot title that goes above the plot 

作業パーサB:

ζ python test.py working_b 
usage: test.py [-h] [-cmap hot_desaturated] [-title The Plot Title] 

b 

optional arguments: 
    -h, --help   show this help message and exit 
    -cmap hot_desaturated 
         Colormap to use for colorbar 
    -title The Plot Title 
         Define the plot title that goes above the plot 

作業パーサC:

ζ python test.py working_c 
usage: test.py [-h] [-cmap hot_desaturated] [-cbar_scale [lin]|log] 

c 

optional arguments: 
    -h, --help   show this help message and exit 
    -cmap hot_desaturated 
         Colormap to use for colorbar 
    -cbar_scale [lin]|log 
         Linear or log scale colormap 

作業D:

ζ python test.py working_d 
usage: test.py [-h] [-a hot_desaturated] [-b [lin]|log] [-c The Plot Title] 

d 

optional arguments: 
    -h, --help   show this help message and exit 
    -a hot_desaturated Colormap to use for colorbar 
    -b [lin]|log  Linear or log scale colormap 
    -c The Plot Title Define the plot title that goes above the plot 

壊れた:

ζ python test.py broken 
Traceback (most recent call last): 
    File "test.py", line 42, in <module> 
    broken_parser.parse_args(['-h']) 
    File "/usr/local/lib/python2.7/site-packages/argparse.py", line 1703, in parse_args 
    args, argv = self.parse_known_args(args, namespace) 
    File "/usr/local/lib/python2.7/site-packages/argparse.py", line 1735, in parse_known_args 
    namespace, args = self._parse_known_args(args, namespace) 
    File "/usr/local/lib/python2.7/site-packages/argparse.py", line 1941, in _parse_known_args 
    start_index = consume_optional(start_index) 
    File "/usr/local/lib/python2.7/site-packages/argparse.py", line 1881, in consume_optional 
    take_action(action, args, option_string) 
    File "/usr/local/lib/python2.7/site-packages/argparse.py", line 1809, in take_action 
    action(self, namespace, argument_values, option_string) 
    File "/usr/local/lib/python2.7/site-packages/argparse.py", line 1015, in __call__ 
    parser.print_help() 
    File "/usr/local/lib/python2.7/site-packages/argparse.py", line 2328, in print_help 
    self._print_message(self.format_help(), file) 
    File "/usr/local/lib/python2.7/site-packages/argparse.py", line 2302, in format_help 
    return formatter.format_help() 
    File "/usr/local/lib/python2.7/site-packages/argparse.py", line 300, in format_help 
    help = self._root_section.format_help() 
    File "/usr/local/lib/python2.7/site-packages/argparse.py", line 230, in format_help 
    func(*args) 
    File "/usr/local/lib/python2.7/site-packages/argparse.py", line 351, in _format_usage 
    assert ' '.join(opt_parts) == opt_usage 
AssertionError 
+2

現時点では、あなたの質問は非常に不明です。正確な問題を定義するための情報を追加してください。 – SiHa

+0

完全なスタックトレースを含めてください。エラーメッセージはあなたにとって役に立たないかもしれませんが、私たちはそれを理解することができます。そして、あなたは「名前列」とはどういう意味ですか? – skrrgwasme

+0

これは面白いです...あなたはargparseそのものの深いところにアサーションを打っているようですが、これはおそらくargparseの何らかのバグでしょう。また、 '-O'(単にアサーションを削除する)を使ってPythonを実行すると、再び動作するようです。 – mgilson

答えて

1

これは、あなたがmetavar変数を使用しているかに関係argparseのバグに見えます。これを追跡するための有益な情報があります。

最初に、metavar'['または']'文字が含まれているとします。

第2に、引数の数に依存するように思われます(2つ以上が問題を引き起こします)。実際のの数字の引数は読んでいるかもしれません - フォーマッタが複数の行に引数を分割する必要があるかどうかは、引数の数に緩く結合されているかどうかに関係しています...

第3これは、assertステートメントで提起されたAssertionErrorです。私たちは、-Oでコードを実行すると何が起こるかを見ることができます。

$ python3 -O ~/sandbox/ap.py broken 
usage: ap.py [-h] [-cmap hot_desaturated] [-title The Plot Title] 
      [-cbar_scale [lin] |log] 
<snip> 

そして、我々は、アサーションが失敗した理由はおそらく私たちの[lin]|log[lin] |logに分割された最後の行に見ることができます。


これは、​​の優先度の低いバグです。コメントの中で@CharlesDuffyが指摘しているのはmay already be reportedです。

choices=...を使用して、引数への入力を検証する方がよいことに注意してください。で

broken_parser.add_argument('-cbar_scale',default='lin', type=str, nargs=1, help='', choices=('lin', 'log')) 

結果:あなたはargparseはあなたのためにやや適しmetavarを作成し、それを行うとき

usage: ap.py [-h] [-cmap hot_desaturated] [-title The Plot Title] 
      [-cbar_scale {lin,log}] 

これはかなり素敵として(それはあなたが何を教えてくれないではありません例えばデフォルトです)、それをhelp文字列に簡単に入れることができます。本当に必要な場合は、メタバのために中かっこを使用することができます:metavar='{{lin}|log}'それはちょうどいい動作します...

+0

「選択肢= ...」の規約に変更できるかどうかがわかります。 – amoose136

関連する問題