2014-02-28 4 views
1

argparse 플래그를 결합 할 때 다른 결과가 나타납니다 (-x -y>-xy). 그것은 말로 설명하기 어려운, 그래서 나는 다음과 같은 최소한의 설정에 문제를 감소 :python : argparse에서 이상한 오류가 발생했습니다.

# test.py 
def invalid_argument_type(x): 
    raise Exception("can't parse this") # in my code, it doesn't *always* fail 

parser = argparse.ArgumentParser() 

parser.add_argument('args', type = invalid_argument_type) 
parser.add_argument('-x') 

print parser.parse_args() 

을 지금 잘못이 프로그램 수익률 예상치 못한 결과를 호출. 첫 번째 명령은 두 번째 잘못된 플래그가 정확하고, 세 번째는 두 번째와 동일해야합니다 : 플래그가 결합 될 때, '알 수없는 플래그 "오류가 삼킨 것으로 보인다

$ python test.py -x foo 
Namespace(args=[], x='foo') 

$ python test.py -A -x foo 
test.py: error: unrecognized arguments: -A 

$ python test.py -Ax foo 
Exception: can't parse this 

-xfoo 정규 인수로 취급됩니다. -A 플래그가있는 경우 -A-x 모두 모든 시나리오에서 예상대로 작동합니다.

이렇게하면 매우 혼란스러운 오류 메시지가 나타납니다.

argparse을 잘못 사용하고 있습니까? 이 문제를 해결할 수있는 방법이 있습니까? 아니면 오류 처리를 직접 처리해야합니까?

답변

1

인수 파싱 중에 발생하는 예외가 간단한 인수 오류보다 중요하기 때문에이 문제가 발생합니다. 인수가 인 경우-Ax이 유효하지 않은 플래그임을 인식하고 나중에 표시되는 것을 기록합니다. args의 구문 분석이 예외로 인해 실패하기 때문에 해당 예외가 즉시 표시되고 다른 잘못된 인수는 더 이상 언급되지 않습니다.

소스에서이 동작을 확인할 수도 있습니다. parse_args은 구문 분석 단계를 parse_known_args으로 위임하여 구문 분석 된 네임 스페이스와 잘못된 인수 목록을 반환합니다. parse_known_args 그러나 내부적으로 구문 분석하려고 시도하고 예외가 발생하면 즉시 표시합니다. 따라서 예외는 parse_args이 유효하지 않은 인수를 표시하기 전에 프로세스를 중단합니다.

이제 세 가지 예제 모두 다르게 작동하므로 마지막 예제에 대한 예외 만 표시됩니다. 그럼 자세히를 확인하자 :

  • -x foo을 : 여기, -x 유효한 인수 이름이며, foo는 값입니다. 그래서 모든 것이 잘됩니다.
  • -A -x foo : -A은 인식 할 수없는 인수이므로주의해야합니다. 나머지 부분은 -x foo이며 이는 다시 x 인수의 유효한 순서입니다.
  • -Ax foo : -Ax은 인식 할 수없는 인수이므로 다시 적어 두었습니다. 나머지 부분은 foo입니다. 인수 플래그가 없으므로 파서는이를 args 매개 변수와 일치 시키려고 시도합니다. 그러면 예외가 발생합니다.

argparse는 왼쪽에서 오른쪽으로 올바르게 구문 분석 할 수있는 경우 결합 된 플래그 (-Ax) 만 지원합니다. 단일 대시 플래그도 한 문자보다 길 수 있기 때문에 (예 : -foo이면 괜찮습니다.) 실제로는 -Ax 인수를 정의 할 수 있으므로 -A -x이 될 것이라고 안전하게 말할 수 없습니다.이 문장을 만들려면 실제로는 일치하는 인수를 찾으려고 시도하는 -Ax을 구문 분석하기 시작합니다. -A 인수가 없으므로 -Ax이어야한다고 가정합니다. 그러나 그것도 존재하지 않으므로 거기에서 실패합니다.

+0

그러나 플래그를 합치면 플래그가 정상적으로 작동하는 것 같습니다. ( – slezica

+0

맞아요, 제 대답이 약간 업데이트 되었어요. 기본적으로'-Ax'와 알려진 인수가 일치하지 않아서 안됩니다. 그것들을 분리 할 곳을 알지 못하기 때문에 단순히''-Ax''를 무효로 표시합니다. – poke

+0

'argparse'의 책임을 줄이고 나중에 에러 처리를 할 것입니다. – slezica

관련 문제