PEP 389 – argparse - 새로운 명령줄 구문 분석 모듈
- Author:
- Steven Bethard <steven.bethard at gmail.com>
- Status:
- Final
- Type:
- Standards Track
- Created:
- 25-Sep-2009
- Python-Version:
- 2.7, 3.2
- Post-History:
- 27-Sep-2009, 24-Oct-2009
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
승인
이 PEP는 2010년 2월 21일 python-dev에서 Guido의 승인을 받았습니다 [17].
초록
이 PEP는 Python 2.7 및 3.2에서 argparse [1] 모듈을 Python 표준 라이브러리에 포함할 것을 제안합니다.
동기
argparse 모듈은 표준 라이브러리에 있는 기존 명령줄 구문 분석 모듈인 getopt [2] 및 optparse [3]보다 더 많은 기능을 제공하는 명령줄 구문 분석 라이브러리입니다. 이 모듈은 위치 인자(옵션뿐만 아니라), 서브커맨드, 필수 옵션, “/f” 및 “+rgb”와 같은 옵션 구문, 0개 이상 및 1개 이상 스타일의 인자와 그 밖의 두 모듈에는 없는 여러 기능을 지원합니다.
argparse 모듈은 이미 이러한 모듈을 대체하는 인기 있는 서드파티 모듈이기도 합니다. 이 모듈은 IPython(Scipy Python 셸) [4]과 같은 프로젝트에서 사용되며, Debian testing 및 unstable [5]에 포함되어 있고, 2007년부터 표준 라이브러리에 포함해 달라는 다양한 요청이 있었습니다 [6] [7] [8]. 이러한 인기는 argparse가 Python 라이브러리에 추가될 가치가 있음을 시사합니다.
getopt와 optparse로는 왜 충분하지 않습니까?
argparse를 추가하는 것에 반대하는 한 가지 주장은 “표준 라이브러리에 이미 서로 다른 옵션 구문 분석 모듈이 두 개 있다”는 것입니다 [9]. 다음은 getopt 또는 optparse에는 없지만 argparse가 제공하는 기능의 목록입니다.
- 두 옵션 구문 분석 라이브러리가 있다는 것은 사실이지만, 완전한 명령줄 구문 분석 라이브러리는 없습니다. getopt와 optparse는 모두 옵션만 지원하며 위치 인자는 지원하지 않습니다. argparse 모듈은 두 가지를 모두 처리하므로 더 나은 도움말 메시지를 생성할 수 있으며, optparse에 일반적으로 필요한
usage=문자열과 같은 중복을 피할 수 있습니다. - argparse 모듈은 순수성보다 실용성을 중시합니다. 따라서 argparse는 필수 옵션과 옵션을 식별하는 데 사용되는 문자의 사용자 지정을 허용하지만, optparse는 “‘필수 옵션’이라는 표현은 자기모순입니다”라고 명시하며
-pf,-file,+f,+rgb,/f및/file옵션 구문은 “optparse에서 지원되지 않으며 앞으로도 지원되지 않을 것”이라고 합니다. - argparse 모듈은
nargs='?',nargs='*'또는nargs='+'를 사용하여 옵션이 가변 개수의 인자를 받아들이도록 합니다. optparse 모듈은 이 기능의 일부를 위한 검증되지 않은 방법을 제공하지만 [10], “옵션이 가변 개수의 인자를 받도록 하려면 일이 복잡해진다”고 인정합니다. - argparse 모듈은 서브커맨드를 지원하며, 여기서 주 명령줄 파서는 명령줄 인자에 따라 다른 명령줄 파서로 처리를 전달합니다. 이는 명령줄 인터페이스에서 흔히 사용되는 패턴으로, 예를 들면
svn co및svn up이 있습니다.
이 기능을 단순히 optparse에 추가하지 않는 이유는 무엇입니까?
위의 모든 기능이 optparse를 통해 제공되는 기능을 분명히 개선한다는 점은 명백합니다. 그렇다면 완전히 새로운 모듈을 도입하는 대신 이러한 기능을 optparse에 대한 패치로 간단히 제공하지 않는 이유가 무엇인지 묻는 것은 합리적입니다. 실제로 argparse의 초기 개발은 바로 그렇게 하는 것을 목표로 했지만, optparse의 여러 제약적인 설계 결정 때문에 실제로는 가능하지 않았습니다. 문제 중 일부는 다음과 같습니다.
- optparse 모듈은 구문 분석 알고리즘의 내부 구현을 노출합니다. 특히
parser.largs및parser.rargs는 콜백에서 사용할 수 있음이 보장됩니다 [11]. 이 때문에 argparse에서 위치 인자와 가변 길이 인자를 올바르게 처리하는 데 필요했던 것처럼 구문 분석 알고리즘을 개선하기가 매우 어렵습니다. 예를 들어 argparse의nargs='+'는 정규 표현식을 사용하여 매칭되므로parser.largs와 같은 항목에 대한 개념이 없습니다. - optparse 확장 API는 매우 복잡합니다. 예를 들어, 간단한 사용자 지정 문자열-객체 변환 함수를 사용하려면
Option을 서브클래싱하고, 클래스 속성을 조작한 다음, 다음과 같이 사용자 지정 옵션 유형을 파서에 지정해야 합니다.:class MyOption(Option): TYPES = Option.TYPES + ("mytype",) TYPE_CHECKER = copy(Option.TYPE_CHECKER) TYPE_CHECKER["mytype"] = check_mytype parser = optparse.OptionParser(option_class=MyOption) parser.add_option("-m", type="mytype")
비교해 보면, argparse는 변환 함수를
type=인자로 직접 사용할 수 있도록 간단히 허용합니다. 예를 들면 다음과 같습니다.:parser = argparse.ArgumentParser() parser.add_option("-m", type=check_mytype)
그러나 optparse의 매우 복잡한 사용자 지정 API를 고려하면 이러한 기능이 해당 API와 어떻게 상호 작용해야 하는지는 명확하지 않으며, 간단한 argparse API를 도입하면 기존 사용자 지정 Option 코드가 손상될 가능성도 상당히 높습니다.
- optparse와 argparse는 모두 명령줄 인자를 파싱하고, 이를
parse_args가 반환하는 객체의 속성으로 할당합니다. 그러나 optparse 모듈은 사용자 지정 액션의take_action메서드에 항상ensure_value메서드를 제공하는values객체가 전달된다는 것을 보장합니다 [12]. 반면 argparse 모듈은 어떤 객체에도 속성을 할당할 수 있도록 허용합니다. 예를 들면 다음과 같습니다.:foo_object = ... parser.parse_args(namespace=foo_object) foo_object.some_attribute_parsed_from_command_line
어떤 객체든 전달할 수 있도록 optparse를 수정하는 일은 어려울 것입니다.
Values인스턴스 대신foo_object를 전달하기만 해도ensure_value메서드에 의존하는 기존 사용자 지정 액션이 손상되기 때문입니다.
이러한 문제 때문에 argparse가 optparse API와 호환성을 유지하기가 비합리적으로 어려워졌으므로, argparse는 독립적인 모듈로 개발되었습니다. 이러한 문제를 고려하면, 하위 호환성 문제 없이 모든 argparse 기능을 optparse에 통합하는 일은 어려워 보입니다.
optparse의 사용 중단
optparse의 모든 기능을 argparse에서 사용할 수 있으므로 optparse 모듈은 사용 중단됩니다. 그러나 optparse가 널리 사용되고 있으므로 사용 중단 전략에는 기본적으로 표시되지 않는 문서 변경과 경고만 포함됩니다.
- Python 2.7 이상 및 3.2 이상 – 다음 참고 사항이 optparse 문서에 추가됩니다.optparse 모듈은 사용 중단되었으며 더 이상 개발되지 않습니다. 개발은 argparse 모듈에서 계속됩니다.
- Python 2.7 이상 – Python 3 호환성 플래그인
-3이 명령줄에 제공되면 optparse를 임포트할 때 DeprecationWarning이 발생합니다. 그렇지 않으면 경고가 발생하지 않습니다. - Python 3.2 이상 – optparse를 임포트하면 기본적으로 표시되지 않는 PendingDeprecationWarning이 발생합니다.
optparse의 제거 날짜는 제안되지 않았다는 점에 유의하십시오.
getopt 문서 업데이트
getopt 모듈은 사용 중단되지 않습니다. 그러나 해당 문서는 몇 군데에서 argparse를 가리키도록 업데이트됩니다. 모듈 상단에 다음 참고 사항이 추가됩니다.
getopt 모듈은 명령줄 옵션을 위한 파서이며, 그 API는 C getopt 함수 사용자에게 익숙하도록 설계되었습니다. C getopt 함수에 익숙하지 않거나 더 적은 코드를 작성하면서 더 나은 도움말과 오류 메시지를 얻고 싶은 사용자는 대신 argparse 모듈을 사용하는 것을 고려해야 합니다.
또한 최종 getopt 예제 뒤에 다음 참고 사항이 추가됩니다.
argparse 모듈을 사용하면 동일한 명령줄 인터페이스를 더 적은 코드로 만들 수 있다는 점에 유의하십시오.:import argparse if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('-o', '--output') parser.add_argument('-v', dest='verbose', action='store_true') args = parser.parse_args() # ... do something with args.output ... # ... do something with args.verbose ..
보류됨: 문자열 형식 지정
argparse 모듈은 Python 2.3부터 3.2까지를 지원하므로 기존의 %(foo)s스타일 문자열 형식 지정에 의존합니다. 새로운 스타일인 {foo} 문자열 형식 지정을 사용하는 편이 더 나을 수 있다는 제안이 있었습니다 [13]. 표준 라이브러리의 모듈에서 이를 가장 잘 수행하는 방법에 대한 논의가 있었고 [14], 여러 사람이 %-formatting을 {}-formatting으로 자동 변환하는 함수를 개발하고 있습니다 [15] [16]. 이러한 함수 중 하나가 표준 라이브러리에 추가되면 argparse는 두 형식 지정 스타일을 모두 지원하는 데 해당 함수를 사용합니다.
거부됨: getopt 호환성 메서드
이전에 이 PEP에서 getopt뿐 아니라 optparse의 사용 중단을 제안했을 때에는 다음과 같은 메서드를 추가하자는 논의가 있었습니다.:
ArgumentParser.add_getopt_arguments(options[, long_options])
그러나 이 메서드는 여러 이유로 추가되지 않습니다.
- getopt 모듈은 사용 중단되지 않으므로 필요성이 줄어듭니다.
- 위 API는 인자에 도움말 메시지를 추가할 방법을 제공하지 않으므로, 이미 사용법 메시지를 관리하고 있던 getopt 사용자에게는 이 메서드가 실제로 전환을 쉽게 해 주지 못합니다.
- 일부 getopt 사용자는 함수 호출이 단 한 번만 필요하다는 점을 매우 중요하게 여깁니다. 위 API는
ArgumentParser()와parse_args()도 호출해야 하므로 이 요구 사항을 충족하지 않습니다.
범위 제외: 다양한 기능 요청
이 PEP에 대한 논의에서 argparse에 관한 몇 가지 기능 요청이 제기되었습니다.
- 환경 변수에서 인자 기본값 지원
- 구성 파일에서 인자 기본값 지원
- 현재 지원되는 “foo subcommand –help”에 더하여 “foo –help subcommand” 지원
이는 모두 argparse 모듈에 대한 합리적인 기능 요청이지만 이 PEP의 범위를 벗어나며, argparse 이슈 추적기로 전달되었습니다.
논의: sys.stderr 및 sys.exit
잘못된 인자가 제공될 때 argparse가 기본적으로 항상 sys.stderr에 기록하고 항상 sys.exit을 호출한다는 우려가 있었습니다. 이는 단순 명령줄 인터페이스를 중심으로 하는 대부분의 argparse 사용 사례에서 바람직한 동작입니다. 그러나 경우에 따라 argparse가 종료되지 않도록 하거나 메시지를 sys.stderr가 아닌 다른 곳에 기록하도록 하는 것이 바람직할 수 있습니다. 이러한 사용 사례는 ArgumentParser를 서브클래싱하고 exit또는 _print_message메서드를 재정의하여 지원할 수 있습니다. 후자는 문서화되지 않은 구현 세부 사항이지만, 이것이 일반적인 요구 사항으로 판명되면 공식적으로 노출할 수 있습니다.
참고 자료
Copyright
This document has been placed in the public domain.