PyPy의 설정 처리

사용 가능한 설정 옵션이 점점 늘어나면서 필요한 옵션을 실제로 사용되는 곳까지 전달하는 일이 상당히 번거로워졌고, 새 옵션을 추가하는 일은 더욱 번거로워졌습니다. 이러한 문제를 피하기 위해 설정 관리(configuration management)가 도입되었습니다. 설정 관리에서는 필요한 모든 옵션이 설정 객체(configuration object)에 저장되며, 이 객체는 RPython toolchain과 표준 인터프리터의 거의 모든 곳에서 사용할 수 있으므로 새 옵션을 추가하는 일이 매우 간단해집니다. 옵션은 트리 형태로 구성됩니다. 설정 객체는 여러 가지 방법으로 생성할 수 있으며, optparse 명령줄 파서를 자동으로 생성하는 기능도 지원합니다.

주요 가정

설정 객체는 진입점에서 생성되어 실제로 사용되는 곳까지 전달됩니다. 이렇게 하면 설정을 지역적으로 유지하면서도 어디서나 사용할 수 있고 일관성도 유지할 수 있습니다. 설정 값은 명령줄을 통해 생성됩니다.

API 세부 사항

옵션 처리는 두 부분으로 나뉩니다. 하나는 어떤 옵션을 사용할 수 있는지, 각 옵션이 가질 수 있는 값과 기본값은 무엇인지, 옵션들이 트리 형태로 어떻게 구성되는지에 대한 설명입니다. 구체적으로 선택한 옵션들은 설정 객체 하나로 묶이며, 이 설정 객체는 자신의 옵션 설명에 대한 참조를 가집니다(따라서 설정 값이 옵션 설명을 따르도록 보장합니다). 이러한 분리는 rtyper의 타입 시스템에서 타입과 인스턴스를 구분하는 방식과 어렴풋이 비슷합니다. 타입은 인스턴스가 어떤 종류의 필드를 가지는지를 기술합니다.

옵션은 트리 구조로 구성되어 있습니다. 모든 옵션에는 이름이 있으며, 모든 옵션 그룹에도 이름이 있습니다. 옵션의 전체 이름을 이루는 각 부분은 점으로 구분됩니다. 예: config.translation.thread.

옵션 설명

모든 생성자는 옵션이나 옵션 그룹에 이름을 붙이고 이를 문서화하기 위해 name과 doc 인자를 첫 번째 인자로 받습니다. 대부분의 생성자는 옵션의 기본값을 지정하는 default 인자를 받습니다. 이 인자가 주어지지 않으면 기본값은 None으로 간주됩니다. 또한 대부분의 생성자는 명령줄 옵션의 형태를 지정할 수 있는 cmdline 인자도 받습니다(예: cmdline=”-v –version”). cmdline이 지정되지 않으면 옵션의 이름과 전체 경로를 함께 사용하는 기본 cmdline 옵션이 생성됩니다. cmdline으로 None이 전달되면 명령줄 옵션이 전혀 생성되지 않습니다.

일부 옵션 타입은 요구 사항을 지정하여, 한 옵션의 특정 선택이 다른 옵션에서 특정 값을 선택한 경우에만 동작하도록 할 수 있습니다. 요구 사항은 쌍의 리스트로 지정합니다. 쌍의 첫 번째 요소는 반드시 설정되어야 하는 옵션의 경로이고, 두 번째 요소는 그 옵션에 요구되는 값입니다.

OptionDescription

이 클래스는 하위 옵션을 묶는 데 사용됩니다.

__init__(self, name, doc, children)
children은 옵션 설명의 리스트입니다(중첩된 네임스페이스를 위한 OptionDescription 인스턴스도 포함합니다).

ChoiceOption

여러 객체 중 하나를 선택하는 옵션을 나타냅니다. 이 옵션은 None 값을 가질 수도 있습니다.

__init__(self, name, doc, values, default=None, requires=None, cmdline=DEFAULT)
values는 옵션이 가질 수 있는 값의 목록이고, requires는 각 값을 두 요소로 이루어진 튜플의 목록에 대응시키는 딕셔너리입니다.

BoolOption

True와 False 중 하나의 선택을 나타냅니다.

__init__(self, name, doc, default=None, requires=None, suggests=None, cmdline=DEFAULT, negation=True)
default는 옵션의 기본값을 지정합니다. requires는 옵션이 참으로 설정되었을 때의 요구 사항을 기술하는 두 요소 튜플의 리스트이고, suggests는 같은 구조의 리스트이지만 그 안의 옵션은 반드시 필요한 것이 아니라 제안될 뿐입니다. 차이는 크지 않습니다. 현재 옵션이 True로 설정되면 요구되는 옵션과 제안되는 옵션이 모두 설정됩니다. 다만 요구되는 옵션은 나중에 변경할 수 없습니다. negation은 부정형 명령줄 옵션을 생성할지 여부를 지정합니다.

IntOption

정수 선택을 나타냅니다.

__init__(self, name, doc, default=None, cmdline=DEFAULT)

FloatOption

부동소수점 수의 선택을 나타냅니다.

__init__(self, name, doc, default=None, cmdline=DEFAULT)

StrOption

문자열 선택을 나타냅니다.

__init__(self, name, doc, default=None, cmdline=DEFAULT)

구성 객체

Config 객체는 옵션에 대해 선택된 값(아무것도 선택하지 않았다면 기본값)을 담습니다. Config 객체는 OptionDescription 인스턴스로 기술됩니다. Config 객체의 속성은 OptionDescription의 자식들의 이름입니다. 예제:

>>> from rpython.config.config import OptionDescription, Config, BoolOption
>>> descr = OptionDescription("options", "", [
...     BoolOption("bool", "", default=False)])
>>>
>>> config = Config(descr)
>>> config.bool
False
>>> config.bool = True
>>> config.bool
True

Config의 (유용한) 메서드에 대한 설명:

__init__(self, descr, **overrides):
descr는 설정 객체를 설명하는 OptionDescription의 인스턴스입니다. overrides를 사용하여 다른 기본값을 설정할 수 있습니다(override 메서드 참고).
override(self, overrides):
기본값을 재정의합니다. 이렇게 하면 재정의된 값이 기본값으로 표시되므로 해당 값을 변경할 수 있습니다(일반적으로 값은 한 번만 변경할 수 있습니다). overrides는 경로 문자열을 값에 대응시키는 딕셔너리입니다.
set(self, **kwargs):
옵션 설정을 위한 “do what I mean”(의도한 대로 동작하는) 인터페이스입니다. 해당 config에서 시작하는 모든 경로를 검색하여 선택적 인자와 일치하는 항목을 찾고, 일치 결과가 모호하지 않으면 찾아낸 옵션을 설정합니다.

optparse 파서 생성

optparse 파서를 만들려면 to_optparse 함수를 사용하십시오. 이 함수는 콜백을 사용하여 옵션 파서를 생성하며, 파서를 생성하는 데 사용된 설정 객체가 자동으로 갱신되도록 합니다.

to_optparse(config, useoptions=None, parser=None):
optparse 파서를 반환합니다. config는 파서를 생성할 대상이 되는 설정 객체입니다. useoptions는 명령줄 옵션을 생성할 대상이 되는 옵션들의 목록입니다. 이 목록에는 옵션의 전체 경로를 넣을 수 있습니다. 또는 옵션 설명(option description)의 경로 뒤에 “.*”를 붙여 넣으면 해당 설명에 속한 모든 하위 옵션에 대해 명령줄 옵션이 생성됩니다. useoptions가 None이면 모든 하위 옵션이 명령줄 옵션으로 변환됩니다. parser에는 기존 파서 객체를 넘길 수 있으며, None을 넘기면 새 파서가 생성됩니다.

PyPy에서 config 객체의 사용법

PyPy의 두 가지 큰 구성 요소인 Python 인터프리터와 RPython 툴체인은 각각 별도의 옵션 집합을 가집니다. 변환 툴체인 옵션은 모든 TranslationContext 인스턴스의 config 속성에서 찾을 수 있으며, rpython/config/translationoption.py에 설명되어 있습니다. 인터프리터 옵션은 객체 공간(object space)에 붙어 있으며, 이름은 마찬가지로 config이고, pypy/config/pypyoption.py에 설명되어 있습니다. 두 옵션 집합 모두 PyPy 설정 옵션 섹션에 문서화되어 있습니다.