Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

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

Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

이 PEP는 sys 모듈에 새 속성인 sys.implementation을 도입합니다. 이 속성은 실행 중인 인터프리터의 구현에 관한 정보를 한데 모아 담고 있습니다. 따라서 sys.implementation은 표준 라이브러리가 구현별 정보를 찾을 때 참조할 수 있는 출처입니다.

이 PEP의 제안은 Python을 대체 구현에 더 친화적으로 만들려는 더 넓은 흐름과 맥을 같이합니다. 이 PEP는 새 변수와, 그 변수에 담기는 내용에 대한 제약을 설명합니다. 또한 이 PEP는 sys.implementation을 당장 활용할 수 있는 몇 가지 사용 사례도 설명합니다.

동기

지난 수년간 언어로서의 파이썬과 CPython(참조 구현) 사이의 구분은 점점 뚜렷해져 왔습니다. 이러한 변화는 대부분 Jython, IronPython, PyPy가 파이썬의 실용적인 대체 구현으로 등장한 데서 비롯되었습니다.

그러나 CPython 중심이었던 파이썬의 거의 20년(즉, 파이썬 역사의 대부분)을 생각해 보십시오. 그러한 편중은 당연하게도 표준 라이브러리 안에, 그리고 인터프리터에 노출된 형태로 상당수의 CPython 전용 잔재를 남기는 데 일조했습니다. 코어 개발자들이 최근 몇 년간 이 문제를 해결하려고 노력해 왔지만, 그러한 산물이 아직 상당수 남아 있습니다.

이 PEP는 해결책의 일부로, 구현별 세부 사항을 한데 모을 단일 네임스페이스를 제시합니다. 이는 구현별 세부 사항을 언어와 구별하려는 노력에 집중하는 데 도움이 될 것입니다. 또한 여러 구현을 염두에 두는 사고방식을 북돋울 것입니다.

제안

sys 모듈에 sys.implementation이라는 새 속성을 (매핑이 아닌) 속성으로 접근하는 객체로 추가합니다. 이 객체에는 구현별 정보가 담깁니다.

이 객체의 속성은 인터프리터가 실행되는 동안, 그리고 한 구현 버전이 유지되는 동안 고정된 상태로 유지됩니다. 이를 통해 sys.implementation의 속성에 의존하는 동작이 버전 사이에 바뀌지 않도록 보장합니다.

이 객체는 아래 Required Attributes 절에서 설명하는 속성을 모두 가집니다. 이러한 속성 이름은 절대 밑줄로 시작하지 않습니다. 표준 라이브러리와 언어 정의는 이 필수 속성에만 의존합니다.

이 제안은 소수의 속성만 필수로 요구하는 보수적인 접근 방식을 취합니다. 더 많은 속성이 적절해지면 Adding New Required Attributes에 설명된 대로 신중하게 추가할 수 있습니다.

이 PEP는 sys.implementation에 다른 제약을 두지 않지만, 여기에 설명된 것 이외의 기능에는 누구도 의존하지 않도록 권고합니다. 이 권고의 유일한 예외는 밑줄로 시작하는 속성입니다. 구현자는 구현별 데이터를 저장하는 데 이러한 속성을 적절히 사용할 수 있습니다.

필수 속성

다음은 표준 라이브러리와 언어 정의가 의존하는 sys.implementation의 속성들이며, 따라서 구현자는 이를 반드시 정의해야 합니다:

name
구현을 나타내는 소문자 식별자입니다. 예를 들어 ‘pypy’, ‘jython’, ‘ironpython’, ‘cpython’ 등이 있습니다.
버전
구현하고 있는 언어의 버전이 아니라 구현 자체의 버전입니다. 이 값은 Version Format에 기술된 형식을 따릅니다.
hexversion
sys.hexversion과 같은 16진수 형식으로 나타낸 구현의 버전입니다.
cache_tag
PEP 3147 캐시 태그에 사용되는 문자열입니다. 일반적으로 이름과 버전을 조합한 것입니다(예: CPython 3.3의 경우 ‘cpython-33’). 하지만 구현이 명시적으로 다른 캐시 태그를 사용할 수도 있습니다. cache_tag가 None으로 설정되면 모듈 캐싱을 비활성화해야 함을 나타냅니다.

새 필수 속성 추가

시간이 지나면서 더 많은 필수 속성이 sys.implementation에 추가될 것입니다. 하지만 각 속성이 고려 대상이 되려면 모든 Python 구현에 걸쳐 의미 있는 사용 사례가 있어야 합니다. 이는 표준 라이브러리나 언어 명세에 사용 사례가 있을 때 가장 명확하게 드러납니다.

새 필수 속성에 대한 모든 제안은 일반적인 PEP 절차를 거칩니다. 그러한 PEP는 길 필요가 없으며, 필요한 만큼의 길이면 충분합니다. 그러한 PEP는 새 속성의 근거, 사용 사례, 그리고 그 속성이 여러 Python 구현에 미칠 영향을 충분히 설명해야 합니다.

버전 형식

sys.implementation의 주요 목적은 표준 라이브러리 내부에서 사용될 정보를 담는 것입니다. 버전 속성이 유용하게 쓰일 수 있도록, 그 값은 구현 간에 일관된 형식이어야 합니다.

따라서 sys.implementation.version의 형식은 사실상 네임드 튜플인 sys.version_info의 형식을 따릅니다. 이는 익숙한 형식이며 일반적인 버전 형식 관례와도 대체로 일치합니다.

근거

구현별 정보를 다루는 현재 방식은 그 정보를 더 취약하고 유지 관리하기 어려운 방식으로 제공합니다. platform.python_implementation()에서 볼 수 있듯이, 그 정보는 여러 모듈에 흩어져 있거나 다른 정보로부터 추론됩니다.

이 PEP는 그러한 접근 방식에 대한 주요 대안입니다. 이 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 바이너리에 고정(frozen)되어 포함된 importlib 부트스트랩 코드는 임포트 과정에서 캐시 태그를 사용합니다. importlib를 부트스트랩하는 프로젝트에는 더 이상 필요 없는 코드를 Python/import.c에서 정리하는 작업도 포함되어 있었습니다.

Python/import.c에 정의된 캐시 태그는 "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 아래에 단일 네임스페이스를 두는 접근 방식은 비교적 간단하므로, 이 PEP에서는 대안을 검토하지 않았습니다.

다른 속성의 예

이것들은 예시일 뿐이며 제안의 일부가 아닙니다. 대부분은 이전 논의에서 제안되었지만 이 PEP의 목표에는 맞지 않았습니다. (흥미가 생긴다면 Adding New Required Attributes 절을 참조하십시오.)

common_name
구현을 가리키는 이름으로, 대소문자를 구분합니다.
vcs_url
구현 프로젝트의 주 VCS 저장소 URL입니다.
vcs_revision_id
구현의 VCS 리비전을 식별하는 값입니다.
build_toolchain
인터프리터를 빌드하는 데 사용한 도구입니다.
build_date
인터프리터를 빌드한 시점의 타임스탬프입니다.
homepage
구현 웹사이트의 URL입니다.
site_prefix
구현이 선호하는 site 접두사입니다.
런타임
인터프리터가 실행되는 런타임 환경으로, “Common Language Runtime” (.NET CLR)이나 “Java Runtime Executable”에서 말하는 런타임을 가리킵니다.
gc_type
사용하는 가비지 컬렉션 방식으로, “참조 카운팅”이나 “마크 앤 스윕” 등이 있습니다.

미해결 문제

현재는 없습니다.

구현

이 PEP의 구현은 issue #14673에서 다룹니다.

참고 문헌