2016-12-12 1 views
2

다음은 함께 실행될 때 독립적으로 작동하는 3 개의 코드 행이 작동하지 않지만 플래그 이름 문자열을 "-a와 같이 간단한 것으로 변경하면 작동하는 흥미로운 경우를 보여주는 몇 가지 예제 코드입니다 ","- b "등, 또는 개별 플래그 중 하나를 주석 처리하는 경우. 테스트 스크립트의 사용법은 다양한 내부 실험 파서를 시작하는 테스트 스크립트의 외부 파서에 포함되어 있습니다. 구문 분석기 a, b 및 c는 모두 동일하지만 각 플래그가 하나씩 주석 처리되어 있습니다. 이 파서에 대한 도움은 모두 작동합니다. 깨진 구문 분석기는 모든 플래그가 현재 활성화되어있는 경우 (주석 처리되지 않은 경우)와 동일합니다.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']) 

출력 : 작업 파서 A :

ζ 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 :

012,351 깨진 6,
ζ 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 

:

이 당신이 metavar 변수를 사용하는 방법에 관한 argparse에서 버그가 수 있도록 보인다
ζ 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

전체 스택 추적을 포함하십시오. 오류 메시지는 사용자에게 유용하지 않을 수도 있지만 Google에서 이해할 수 있습니다. 그리고 "이름 문자열"은 무엇을 의미합니까? – skrrgwasme

+0

이것은 흥미 롭습니다 ... 당신은 argparse 그 자체에 깊은 주장을하고있는 것처럼 보입니다. 그래서 이것은 아마도 argparse에서 어떤 종류의 버그 일 것입니다. 또한'-O' (그냥 어설 션을 제거하는)로 파이썬을 실행하면 다시 작동하게하는 것 같습니다. – mgilson

답변

1

. 여기에이 정보를 추적하는 데 유용한 정보가 있습니다.

metavar'[' 또는 ']'자인 경우 먼저 발생합니다.

둘째, 인수의 수 (2 개 이상이 문제를 유발 함)에 따라 달라지는 것 같습니다. 실제 숫자 인수는 읽기 청어 일 수 있습니다. 형식화자가 인수를 여러 줄로 나눌 필요가 있는지 또는 인수 개수에 느슨하게 결합 된 다른 인수와 관련이있을 수 있습니다. ...

세 번째 이 AssertionErrorassert 문으로 제기됩니다. 우리는 -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로 분할 된 마지막 줄에 볼 수 있습니다.


그래서, 나는이 argparse에 낮은 우선 순위 버그가 될 가능성이 있다고 말할 것입니다.그리고 코멘트에서 @CharlesDuffy에 의해 지적한 may already be reported.

인수 입력에 대한 유효성 검사에 choices=...을 사용하는 것이 좋습니다. 당신이 그렇게 할 때, argparse 당신을 위해 다소 적합 metavar을 생성합니다 :

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

결과 :

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

이 아닌 당신을 말하지 않는다 (아주로 좋은 무엇을 기본값은 예를 들어), 쉽게 help 문자열에 넣을 수 있습니다. 실제로 필요한 경우 metavar에 중괄호를 사용할 수 있습니다. metavar='{{lin}|log}' 그러면 괜찮습니다.

+0

"choices = ..."규칙으로 변경할 수 있는지 확인합니다. – amoose136

관련 문제