PEP 421 – sys.implementation 추가
- Author:
- Eric Snow <ericsnowcurrently at gmail.com>
- BDFL-Delegate:
- Barry Warsaw
- Status:
- Final
- Type:
- Standards Track
- Created:
- 26-Apr-2012
- Python-Version:
- 3.3
- Post-History:
- 26-Apr-2012
- Resolution:
- Python-Dev message
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 sys 모듈에 새 속성인 sys.implementation을 도입합니다. 이 속성은 실행 중인 인터프리터의 구현에 관한 통합된 정보를 보유합니다. 따라서 sys.implementation은 표준 라이브러리가 구현별 정보를 찾을 수 있는 원천입니다.
이 PEP의 제안은 Python을 대체 구현에 더 친화적으로 만들려는 보다 광범위한 강조점과 맥락을 같이합니다. 이 제안은 새 변수와 해당 변수에 포함되는 내용에 대한 제약을 설명합니다. 또한 이 PEP는 sys.implementation의 몇 가지 즉각적인 사용 사례를 설명합니다.
동기
이제 수년 동안 Python 언어와 CPython(참조 구현) 사이의 구분이 점점 커지고 있습니다. 이러한 변화의 대부분은 Jython, IronPython 및 PyPy가 실행 가능한 Python 대체 구현으로 등장했기 때문입니다.
그러나 거의 20년에 걸친 CPython 중심의 Python(즉, Python이 존재한 기간의 대부분)을 생각해 보십시오. 이러한 초점은 표준 라이브러리와 인터프리터에 노출된 부분 모두에 상당수의 CPython 전용 산물이 생기는 데 당연히 기여했습니다. 핵심 개발자들이 최근 몇 년 동안 이를 해결하려고 노력했지만, 이러한 산물 중 상당수가 여전히 남아 있습니다.
이 PEP에서는 해결책의 일부로 구현 세부 사항을 통합할 단일 네임스페이스를 제시합니다. 이는 구현 세부 사항과 언어를 구분하는 데 노력을 집중하는 데 도움이 될 것입니다. 또한 여러 구현을 고려하는 사고방식을 조성할 것입니다.
제안
sys 모듈에 sys.implementation이라는 새 속성을 매핑이 아닌 속성 접근이 가능한 객체로 추가합니다. 이 객체는 구현별 정보를 포함합니다.
이 객체의 속성은 인터프리터 실행 중 및 구현 버전이 진행되는 동안 고정된 상태로 유지됩니다. 이는 sys.implementation의 속성에 의존하는 동작이 버전 간에 변경되지 않도록 보장합니다.
이 객체에는 아래의 Required Attributes 섹션에 설명된 각 속성이 있습니다. 이러한 속성 이름은 절대로 밑줄로 시작하지 않습니다. 표준 라이브러리와 언어 정의는 이러한 필수 속성에만 의존합니다.
이 제안은 적은 수의 속성만 요구하는 보수적인 접근 방식을 취합니다. 더 많은 속성이 적절해지면 Adding New Required Attributes 에 설명된 대로 신중하게 추가할 수 있습니다.
이 PEP는 sys.implementation에 다른 제약을 두지 않지만, 여기에서 설명한 범위를 벗어난 기능에 누구도 의존하지 않도록 권고합니다. 이 권고의 유일한 예외는 밑줄로 시작하는 속성입니다. 구현자는 구현별 데이터를 저장하는 데 필요에 따라 이러한 속성을 사용할 수 있습니다.
필수 속성
다음은 표준 라이브러리와 언어 정의가 의존하는 sys.implementation의 속성이므로, 구현자는 이를 정의해야 합니다:
- name
- 구현을 나타내는 소문자 식별자입니다. 예로 ‘pypy’, ‘jython’, ‘ironpython’, ‘cpython’이 있습니다.
- version
- 구현하는 언어의 버전이 아니라 구현의 버전입니다. 이 값은 Version Format에 설명된 형식을 따릅니다.
- hexversion
sys.hexversion과 동일한 16진수 형식의 구현 버전입니다.- cache_tag
- 이는 PEP 3147 캐시 태그에 사용되는 문자열입니다. 일반적으로 이름과 버전의 조합입니다(예: CPython 3.3의 경우 ‘cpython-33’). 그러나 구현에서 명시적으로 다른 캐시 태그를 사용할 수도 있습니다.
cache_tag를 None으로 설정하면 모듈 캐싱을 비활성화해야 함을 나타냅니다.
새 필수 속성 추가
시간이 지나면 sys.implementation에 더 많은 필수 속성이 추가될 것입니다. 그러나 각 속성이 검토 대상이 되려면 모든 Python 구현에서 의미 있는 사용 사례가 있어야 합니다. 이는 표준 라이브러리나 언어 사양에 사용 사례가 있을 때 가장 명확하게 입증됩니다.
새 필수 속성에 관한 모든 제안은 일반적인 PEP 절차를 거칩니다. 그러한 PEP는 길 필요 없이, 필요한 만큼만 작성하면 됩니다. 새 속성의 근거와 사용 사례, 그리고 다양한 Python 구현에 미칠 영향을 충분히 명시해야 합니다.
버전 형식
sys.implementation의 주요 목적은 표준 라이브러리 내부에서 사용될 정보를 포함하는 것입니다. 버전 속성의 유용성을 높이려면 그 값이 구현 전반에서 일관된 형식이어야 합니다.
따라서 sys.implementation.version의 형식은 사실상 명명된 튜플인 sys.version_info의 형식을 따릅니다. 이는 익숙한 형식이며 일반적인 버전 형식 규칙과 대체로 일관됩니다.
근거
구현별 정보의 현재 방식은 더 취약하고 유지 관리하기 어려운 형태로 해당 정보를 제공합니다. platform.python_implementation()에서 볼 수 있듯이, 정보가 여러 모듈에 분산되어 있거나 다른 정보에서 추론됩니다.
이 PEP는 그러한 접근 방식에 대한 주요 대안입니다. 구현별 정보를 단일 네임스페이스로 통합하고 암묵적이었던 것을 명시적으로 만듭니다.
타입 고려 사항
sys.implementation의 유형에 관한 논의에 빠져들기 쉽습니다. 그러나 그 목적은 표준 라이브러리와 언어 정의를 지원하는 것입니다. 따라서 더 일반적으로 사용될 기능과는 달리, 그 유형과 관련해 실제로 중요한 것은 많지 않습니다. 따라서 불변성이나 시퀀스성 같은 특성은 고려 대상에서 제외되었습니다.
유일하게 실질적인 선택은 속성 접근이 가능한 객체와 항목 접근이 가능한 매핑 중 하나였습니다. 이 PEP에서는 네임스페이스의 비교적 고정된 특성을 반영하기 위해 점 표기 접근을 지지합니다.
비필수 속성
이 PEP의 이전 버전에는 비필수 구현별 데이터를 보유하는 metadata라는 필수 속성이 포함되어 있었습니다 [12]. 그러나 sys.implementation의 목적을 고려하면 이것은 불필요한 추가 사항으로 판명되었습니다.
결국 이 PEP에서는 비필수 속성을 사실상 무시합니다. 부주의하게 사용하면 향후 필수 속성과 충돌할 수 있다는 점 외에는 아무런 영향도 없습니다. 그러나 이는 sys.implementation에 대해서는 사소한 우려에 불과합니다.
왜 sys의 일부입니까?
sys 모듈이 새 네임스페이스를 보유하는 이유는 sys가 인터프리터 중심 변수와 함수의 저장소이기 때문입니다. 구현별 속성 중 상당수가 이미 sys에 있습니다.
값에 엄격한 제약을 두는 이유는 무엇입니까?
Version Format에서 이미 언급했듯이, sys.implementation의 값은 표준 라이브러리에서 사용하도록 의도되었습니다. 본질적으로 해당 값에 대한 API를 지정하는 것인, 이러한 값에 제약을 두면 값이 다른 방식으로 구현되더라도 일관되게 사용할 수 있습니다. 그러나 제약을 과도하게 구체화하지 않도록 주의해야 합니다.
논의
sys.implementation에 관한 주제가 2009년에 python-ideas 목록에서 제기되었으며, 그곳에서의 반응은 대체로 긍정적이었습니다 [1]. 최근 순수 Python imp.get_tag()를 작업하면서 논의를 다시 시작했습니다 [2]. 논의는 계속 진행 중입니다 [3]. issue #14673의 메시지도 관련이 있습니다.
최근 논의의 상당 부분은 sys.implementation에 사용할 유형을 중심으로 진행되었습니다.
사용 사례
platform.python_implementation()
“명시적인 것이 암시적인 것보다 낫다”
platform 모듈은 서로 다른 두 개의 sys 변수에서 단서를 찾아 Python 구현을 판별합니다 [9]. 그러나 이 접근 방식은 취약하며, 구현이 변경될 때마다 표준 라이브러리를 변경해야 합니다. 그뿐 아니라 platform에서의 지원은 핵심 개발자가 platform 모듈에서 특별히 처리하여 인정한 구현으로 제한됩니다.
sys.implementation을 사용하면 다양한 구현이 각자의 sys 모듈 버전에서 값을 명시적으로 설정하게 됩니다.
또 다른 우려 사항은 platform 모듈이 표준 라이브러리의 일부라는 점이며, 표준 라이브러리는 이상적으로 sys.implementation으로 옮겨질 구현 세부 사항을 최소화해야 합니다.
sys.implementation과 platform 모듈 사이에 중복되는 부분이 있다면, 단순히 sys.implementation으로 위임하고 platform에서는 동일한 인터페이스로 이를 감싸게 됩니다.
동결된 importlib에서의 캐시 태그 생성
PEP 3147은 파일 이름에 모듈 캐시와 캐시 태그를 사용하는 방식을 정의했습니다. 3.3부터 Python 바이너리에 동결된 importlib 부트스트랩 코드는 가져오기 과정에서 캐시 태그를 사용합니다. importlib를 부트스트랩하는 프로젝트의 일부로, 더 이상 그곳에 있을 필요가 없는 코드를 Python/import.c에서 정리해 왔습니다.
Python/import.c에 정의된 캐시 태그는 hard-coded되어 "cpython" MAJOR MINOR로 지정되었습니다. importlib의 경우 선택지는 같은 방식으로 이를 하드코딩하거나, platform.python_implementation()이 하는 것과 같은 방식으로 구현을 추측하는 것입니다.
하드코딩된 태그가 CPython 전용 코드로 제한되는 한, 감수할 수 있습니다. 그러나 다른 Python 구현이 모듈 캐시와 연동하기 위해 importlib 코드를 사용하는 경우에는 하드코딩된 태그가 문제가 됩니다.
이 경우 platform 모듈을 직접 사용하는 것은 고려할 수 없는 방안입니다. importlib 부트스트랩에서 사용되는 모든 모듈은 내장되어 있거나 동결되어 있어야 하며, platform 모듈에는 어느 쪽도 해당하지 않습니다. 이것이 최근 sys.implementation에 관심을 갖게 된 계기입니다.
사용할 구현 이름의 결과와 관계없이, 또 다른 문제는 캐시 태그에 사용되는 버전과 관련됩니다. 해당 버전은 언어 버전이 아니라 구현 버전일 가능성이 큽니다. 그러나 표준 라이브러리 어디에서도 구현 버전을 쉽게 식별할 수 없습니다.
구현별 테스트
현재 Lib/test 아래의 테스트 모음에는 여러 구현별 테스트가 있습니다. 테스트 지원 모듈(Lib/test/support.py)은 이러한 테스트를 처리하는 일부 기능을 제공합니다. 그러나 platform 모듈과 마찬가지로 test.support는 sys.implementation이 있다면 불필요해질 추측을 해야 합니다.
Jython의 os.name 해킹
Jython에서는 표준 라이브러리에서 java 환경을 특별히 처리할 수 있도록 os.name을 ‘java’로 설정합니다 [10] [11]. 안타깝게도 이는 그렇지 않았다면 그곳에 설정되었을 OS 이름을 가립니다. sys.implementation은 이 특수 사례의 필요성을 없애는 데 도움이 됩니다. 현재 Jython은 일반적인 os.name 값에 대해 os._name을 설정합니다.
sys.(version|version_info|hexversion)의 문제
이 PEP의 이전 버전에서는 구현과 대조하여 sys.version_info 및 그와 같은 것들을 Python 언어의 버전이라고 잘못 불렀습니다. 그러나 그렇지 않습니다. 대신 이는 CPython 구현의 버전입니다. 참고로 sys.version_info의 첫 두 구성 요소(major 및 minor)는 언어 정의의 버전도 반영합니다.
Barry Warsaw가 지적했듯이, “sys.version_info의 의미 체계는 과거에 충분히 모호했습니다” [13]. sys.implementation을 사용하면 구현 버전을 위한 명시적 위치를 먼저 마련하여 이 상황을 개선할 기회가 생깁니다.
이 PEP는 sys.version_info의 의미를 직접 명확히 하기 위한 다른 노력은 하지 않습니다. 그럼에도 불구하고 구현에 대한 명시적인 버전이 있으면 언어 버전과의 차이를 명확히 하는 데 확실히 도움이 됩니다.
다른 Python 구현자들의 피드백
IronPython
Jeff Hardy는 피드백 요청에 응답했습니다 [4]. 그는 “승인된 다음 날 추가할 것 같습니다”라고 말했습니다 [5]. 또한 sys.implementation의 유형과 metadata속성(이후 PEP에서 제거됨)에 관해 유용한 피드백을 제공했습니다.
Jython
2009년에 Frank Wierzbicki는 Jython이 필수 속성을 구현하는 것과 관련하여 다음과 같이 말했습니다 [6]:
Speaking for Jython, so far it looks like something we would adopt
soonish after it was accepted (it looks pretty useful to me).
PyPy
PyPy 개발자 중 일부는 피드백 요청에 응답했습니다 [7]. Armin Rigo는 다음과 같이 말했습니다 [8]:
For myself, I can only say that it looks like a good idea, which we
will happily adhere to when we migrate to Python 3.3.
또한 필수 목록을 작게 유지하는 것을 지지한다고 밝혔습니다. Armin과 Laura Creighton은 모두 Python의 구현을 더 잘 목록화하려는 노력이 환영받을 것이라고 밝혔습니다. 이 PEP가 작은 시작점인 이러한 노력은 별도로 고려될 것입니다.
과거의 노력
PEP 3139
2008년에 작성된 PEP 3139는 구현별 변수와 함수를 별도의 모듈로 추출하는 등의 방식으로 sys 모듈을 정리할 것을 권고했습니다. PEP 421은 이 아이디어를 덜 야심 차게 적용한 버전입니다. 비록 PEP 3139가 거부되었지만, 그 목표는 PEP 421에 상당 부분 반영되어 있으며, 다만 훨씬 간소한 접근 방식을 취합니다.
PEP 399
PEP 399은 표준 라이브러리에 관한 정책을 규정하여 대체 구현에 더 친화적으로 만드는 데 도움을 줍니다. PEP 421은 동일한 정신으로 제안되었습니다.
더 큰 그림
이 PEP는 Python의 구현별 부분을 식별하고 대체 구현에 미치는 영향을 완화하려는 더 큰 규모의 지속적인 노력에서 작은 부분임을 다시 한번 언급할 가치가 있습니다.
sys.implementation은 구현별 데이터의 초점으로서, 언어와 표준 라이브러리 및 서로 다른 구현 간 협력의 중심점 역할을 합니다. 시간이 지나면서 적절한 경우 sys.implementation이 sys 및 기타 내장/표준 라이브러리 모듈의 현재 속성을 인수하는 것도 가능할 것입니다. 이런 방식으로 이는 PEP 3137의 간소화된 버전이지만, 가능한 한 작은 규모로 시작합니다.
그러나 이미 언급했듯이 다른 많은 노력은 sys.implementation보다 먼저 시작되었습니다. 또한 이것이 반드시 해당 노력의 주요 부분인 것도 아닙니다. 오히려 Python을 대체 구현에 더 친화적으로 만들기 위한 노력의 기반 시설 일부로 생각하십시오.
대안
sys 아래에 단일 네임스페이스를 두는 접근법은 비교적 straightforward하므로, 이 PEP에서는 대안을 고려하지 않았습니다.
다른 속성의 예시
이것들은 예시에 불과하며 제안의 일부가 아닙니다. 이들 대부분은 이전 논의에서 제안되었지만 이 PEP의 목표에는 맞지 않았습니다. 관심이 생긴다면 Adding New Required Attributes를 참조하십시오.
- common_name
- 구현을 나타내는 대소문자 구분 이름입니다.
- vcs_url
- 구현 프로젝트의 주 VCS 저장소 URL입니다.
- vcs_revision_id
- 구현의 VCS 리비전을 식별하는 값입니다.
- build_toolchain
- 인터프리터를 빌드하는 데 사용되는 도구입니다.
- build_date
- 인터프리터가 빌드된 시점의 타임스탬프입니다.
- homepage
- 구현 웹사이트의 URL입니다.
- site_prefix
- 구현에 선호되는 사이트 접두사입니다.
- runtime
- 인터프리터가 실행되는 런타임 환경으로, “Common Language Runtime” (.NET CLR) 또는 “Java Runtime Executable”과 같은 경우를 말합니다.
- gc_type
- “reference counting” 또는 “mark and sweep”과 같은 가비지 컬렉션 유형입니다.
공개 문제
현재는 없습니다.
구현
이 PEP의 구현은 issue #14673에서 다룹니다.
참고 문헌
- Dino Viehland이 자신의 의견을 제시합니다: https://mail.python.org/pipermail/python-dev/2009-October/092894.html
platform코드:
https://hg.python.org/cpython/file/2f563908ebc5/Lib/platform.py#l1247- CPython에서 캐시 태그의 원래 구현: https://hg.python.org/cpython/file/2f563908ebc5/Python/import.c#l121
- test.support에서 구현별 처리의 예:
os.name사용.
https://hg.python.org/cpython/file/2f563908ebc5/Lib/test/support.py#l512sys.implementation.metadata제안:
https://mail.python.org/pipermail/python-ideas/2012-May/014984.htmlCopyright
This document has been placed in the public domain.