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

Python 개선 제안 한국어 번역

PEP 364 – Py3K 표준 라이브러리로의 전환

Author:
Barry Warsaw <barry at python.org>
Status:
Withdrawn
Type:
Standards Track
Created:
01-Mar-2007
Python-Version:
2.6
Post-History:


Table of Contents

번역·라이선스 안내

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

초록

PEP 3108은 Python 3.0 릴리스에 맞춘 Python 표준 라이브러리의 재구성을 설명합니다. 이 PEP는 Python 2.x 표준 라이브러리에서 Python 3.0 표준 라이브러리로 전환하는 메커니즘을 설명합니다. 이 전환을 통해 Python 프로그래머는 Python 2.6부터 새로운 Python 3.0 라이브러리 이름을 사용하도록 허용되고 장려되며, 하위 호환성을 위해 기존 이름은 유지됩니다. 이러한 방식으로 Python 프로그래머는 기존 Python 프로그램과의 상호 운용성을 희생하지 않고 향후 호환 가능한 코드를 작성할 수 있습니다.

근거

PEP 3108은 Python 표준 라이브러리(stdlib) 재구성의 근거를 제시합니다. 라이브러리가 재구성되는 이유와 방법에 대한 자세한 내용은 해당 PEP를 참고하시기 바랍니다. Python 2.x에서 PEP 3108이 일부 또는 전체적으로 채택된다면, Python 프로그래머가 새 stdlib 모듈 이름으로의 전환을 시작할 수 있도록 허용하는 것이 유리하며, 이를 통해 Python 2.6부터 향후 호환 가능한 코드를 작성할 수 있습니다.

참고로 PEP 3108은 일부 “어리석은 오래된 것들”, 즉 더 이상 유용하거나 필요하지 않은 모듈을 제거할 것을 제안합니다. 제거될 모듈에 대해서는 그러한 모듈의 사용을 중단하는 것 외에 향후 호환성 문제가 없으므로, 현재 읽고 계신 PEP에서는 이 문제를 다루지 않습니다.

이 PEP는 이전 stdlib 이름에서 새로운 stdlib 이름으로의 매핑을 유지하는 메커니즘만을 다룹니다. 구체적인 모든 모듈 이름 변경 제안은 PEP 3108을 참고하시기 바랍니다. 특히 이전 이름에서 새로운 이름으로 매핑하는 지침은 Modules to Rename이라는 제목의 절을 확인하시기 바랍니다. 이 PEP의 몇 가지 예는 설명을 위한 것일 뿐이며, 구체적인 이름 변경 권고로 사용해서는 안 됩니다.

지원되는 이름 변경

이 PEP는 최소 4가지 사용 사례를 명시적으로 지원합니다.

  • StringIO에서 stringio로 변경하는 것과 같은 단순한 최상위 패키지 이름 변경;
  • 패키지 이름 자체가 변경될 수도 있고 변경되지 않을 수도 있는 하위 패키지 이름 변경, 예를 들어 email.MIMEText에서 email.mime.text로 변경하는 것;
  • cStringIO에서 cstringio로 변경하는 것과 같은 확장 모듈 이름 변경;
  • 위 항목 중 어느 것이든 서드 파티에서 이름을 변경하는 경우.

이 PEP가 지원하는 두 가지 사용 사례에는 StringIO와 같은 단순한 최상위 모듈의 이름 변경과 email.MIMEText와 같은 패키지 내부 모듈의 이름 변경이 포함됩니다.

전자의 경우 PEP 3108은 현재 PEP 8의 권고에 따라 StringIOstringio로 변경할 것을 권장합니다.

후자의 경우 Python 2.5와 함께 배포된 email 4.0 패키지는 이미 email.MIMETextemail.mime.text로 변경했지만, email 패키지 내부에서 일회성의 독특하게 해킹스러운 방식으로 변경했습니다. 이 PEP에서 설명하는 메커니즘은 모든 모듈 이름 변경을 처리할 수 있을 만큼 일반적이므로, Python 2.5의 해킹이 필요하지 않게 됩니다(이전 Python 버전과의 하위 호환성을 위한 경우는 제외합니다).

추가적인 사용 사례는 C 확장 모듈의 이름 변경을 지원하는 것입니다. C 모듈의 새로운 이름을 가져올 수 있기만 하면 해당 모듈을 새로운 이름으로 다시 매핑할 수 있습니다. 예: cStringIOcstringio로 이름 변경.

Python 모듈이라면 누구나 접근할 수 있는 여러 공개 인터페이스를 통해 서드 파티 패키지 이름 변경도 지원됩니다.

다시 매핑은 재귀적으로 수행되지 않습니다.

.mv 파일

리매핑 파일을 .mv 파일이라고 부릅니다. 이 접미사는 유닉스 mv(1) 명령을 연상시키도록 선택되었습니다. .mv 파일은 단순한 줄 단위 텍스트 파일입니다. 모든 빈 줄과 #으로 시작하는 줄은 무시됩니다. 그 밖의 모든 줄에는 공백으로 구분된 두 개의 필드가 있어야 합니다. 첫 번째 필드는 이전 모듈 이름이고, 두 번째 필드는 새 모듈 이름입니다. 두 모듈 이름 모두 전체 점 경로 이름을 사용하여 지정해야 합니다. 다음은 Python 2.6의 .mv 파일 예입니다.:

# Map the various string i/o libraries to their new names
StringIO    stringio
cStringIO   cstringio

.mv 파일은 파일 시스템의 어디에나 있을 수 있으며, 파일을 구문 분석하고 파일 안의 리매핑을 등록하는 프로그래밍 인터페이스가 제공됩니다. 기본적으로 Python이 시작될 때 oldlib 패키지의 모든 .mv 파일을 읽고, 해당 리매핑을 자동으로 등록합니다. 최상위 Python 2.x 표준 라이브러리 모듈에 대한 모든 모듈 리매핑은 이곳에 지정해야 합니다.

구현 명세

이 절에서는 Python 2.x에서 모듈 이름 변경이 구현되는 방식에 대한 전체 명세를 제공합니다. 핵심 메커니즘은 PEP 302에 설명된 다양한 임포트 훅에 의존합니다. 구체적으로 sys.path_importer_cache, sys.path, sys.meta_path를 모두 사용하여 필요한 기능을 제공합니다.

Python의 임포트 메커니즘이 초기화되면 oldlib 패키지가 임포트됩니다. oldlib 내부에는 OldStdlibLoader라는 클래스가 있습니다. 이 클래스는 PEP 302 인터페이스를 구현하며 인수 없이 자동으로 인스턴스화됩니다. 생성자는 oldlib 패키지 디렉터리의 모든 .mv파일을 읽고, 해당 .mv파일에서 발견되는 모든 재매핑을 자동으로 등록합니다. 이것이 Python 2.x 표준 라이브러리가 리매핑되는 방식입니다.

다른 Python 모듈에서 OldStdlibLoader 클래스를 인스턴스화해서는 안 됩니다. 대신 sys.stdlib_remapper 인스턴스를 통해 전역 OldStdlibLoader 인스턴스에 액세스할 수 있습니다. 리매핑 메커니즘에 프로그래밍 방식으로 액세스하려면 이 인스턴스를 사용하십시오.

한 가지 중요한 구현 세부 사항은 PEP 302 API에 필요한 대로 리매핑 로더를 연결하기 위해 sys.path와 모듈 __path__ 속성에 특수 문자열을 추가한다는 것입니다. 이 특수 문자열은 현재 <oldlib>이며, <로 시작하는 모든 sys.path 항목을 특수 항목으로 처리하도록 Python의 site.py 파일을 일부 변경해야 했습니다. 구체적으로 이러한 항목을 절대 파일 이름으로 만들려고 시도하지 않습니다. 실제로 파일 이름이 아니기 때문입니다.

리매핑 임포트 훅이 작동하려면 모듈 또는 패키지가 새 이름 아래에 물리적으로 위치해야 합니다. 이는 임포트 훅이 아직 임포트되지 않은 모듈만 포착하며 Python의 기본 제공 임포트 규칙으로 임포트할 수 없는 모듈은 포착하지 않기 때문입니다. 따라서 모듈이 예를 들어 Lib/StringIO.py에서 Lib/stringio.py로 이동되었고 이전 파일의 .pyc 파일이 제거되었다면, 리매퍼 없이는 다음 임포트가 실패합니다.:

import StringIO

반면 리매퍼를 사용하면 이 실패하는 임포트를 포착하고, 등록된 리매핑에서 이전 이름을 조회하여 이 경우 새 이름인 stringio를 찾습니다. 그런 다음 리매퍼는 새 이름을 임포트하려고 시도하며, 임포트에 성공하면 결과 모듈을 이전 이름과 새 이름 모두로 sys.modules에 바인딩합니다. 따라서 위 임포트의 결과로 sys.modules에는 ‘StringIO’와 ‘stringio’에 대한 항목이 생성되며, 두 항목 모두 정확히 동일한 모듈 객체를 가리킵니다.

모든 .mv 파일을 다른 곳으로 옮기거나 사용자 정의 시작 코드에서 프로그램적으로 제거하는 것 외에는, 리매핑 기능을 비활성화하는 방법이 제안되지 않았다는 점에 유의하십시오. Python 3.0에서는 리매핑이 제거되어 “새” 이름만 남게 됩니다.

프로그램적 인터페이스

써드파티 패키지가 자체 리매핑을 등록하는 데 사용할 수 있도록 sys.stdlib_remapper 객체에 여러 메서드가 추가됩니다. 그러나 모든 경우에 이전 이름에서 새 이름으로의 매핑은 오직 하나뿐이라는 점에 유의하십시오. 두 개의 .mv 파일이 이전 이름에 대해 서로 다른 매핑을 포함하고 있거나, 이미 리매핑된 이전 이름으로 프로그램적 호출이 이루어지면, 이전 매핑은 유실됩니다. 이는 이미 임포트된 모듈에는 영향을 미치지 않습니다.

sys.stdlib_remapper 객체에서 다음 메서드를 사용할 수 있습니다:

  • read_mv_file(filename) – 주어진 파일을 읽고 그 파일에서 발견된 모든 리매핑을 등록합니다.
  • read_directory_mv_files(dirname, suffix='.mv') – 주어진 디렉터리의 목록을 나열하여, 그 디렉터리에서 일치하는 접미사(기본값은 .mv)를 가진 모든 파일을 읽습니다. 파싱된 각 파일에 대해, 그 파일에서 발견된 모든 리매핑을 등록합니다.
  • set_mapping(oldname, newname) – 이전 모듈 이름에서 새 모듈 이름으로의 새로운 매핑을 등록합니다. 둘 다 모듈에 대한 전체 점(dot) 경로 이름이어야 합니다. newname은 None일 수 있으며, 이 경우 oldname에 대한 기존 매핑이 있다면 제거됩니다(기존 매핑이 없어도 오류는 아닙니다).
  • get_mapping(oldname, default=None) – 주어진 oldname에 대해 등록된 newname을 반환합니다. 등록된 재매핑이 없으면 default가 반환됩니다.

미해결 문제

  • 모든 재매핑을 비활성화하는 명령줄 스위치 및/또는 환경 변수가 있어야 합니까?
  • 재매핑이 재귀적으로 일어나야 합니까?
  • 패키지의 __init__.py가 로드될 때 패키지 디렉터리에서 .mv 파일을 자동으로 파싱해야 합니까? 이렇게 하면 패키지가 자신의 재매핑을 위한 .mv 파일을 쉽게 포함할 수 있습니다. .mv 파일을 oldlib 패키지 대신 email 패키지에 두는 경우, email 패키지가 현재 해야 하는 작업과 비교해 보십시오.:
    # Expose old names
    import os, sys
    sys.stdlib_remapper.read_directory_mv_files(os.path.dirname(__file__))
    

    패키지에 포함될 수 있는 .mv 파일들을 패키지 디렉터리에서 자동으로 읽어야 한다고 생각합니다.

참조 구현

참조 구현은 (이 글을 쓰는 시점 기준) 현재의 Python 2.6 svn 트렁크 상태에 대한 패치 형태로, SourceForge 패치 #1675334 [1]로 제공됩니다. 이 패치에는 cStringIOcstringio로 이름을 바꾸는 것도 포함되어 있지만, 이는 주로 예시 및 단위 테스트 목적임에 유의하십시오. 이 패치가 승인될 경우, 이 변경 사항을 다른 PEP 3108 변경 사항으로 분리하고자 할 수 있습니다.

참고 문헌