PEP 262 – 설치된 Python 패키지 데이터베이스
- Author:
- A.M. Kuchling <amk at amk.ca>
- Status:
- Rejected
- Type:
- Standards Track
- Topic:
- Packaging
- Created:
- 08-Jul-2001
- Post-History:
- 27-Mar-2002
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
소개
이 PEP는 시스템에 설치된 Python 소프트웨어 데이터베이스의 형식을 설명합니다.
(이 문서에서는 “distribution”이라는 용어를 함께 개발되고 배포되는 코드 집합을 의미하는 데 사용합니다. “distribution”은 Red Hat 또는 Debian 패키지와 같지만, “package”라는 용어는 이미 Python 용어에서 __init__.py 파일이 포함된 디렉터리를 의미하므로 별도의 의미를 가지고 있습니다.)
요구 사항
시스템에 어떤 배포판이 설치되어 있는지, 그리고 해당 배포판의 어떤 버전이 설치되어 있는지 알아낼 방법이 필요합니다. CPAN, APT 또는 RPM과 유사한 기능을 제공하고자 합니다. 지원해야 하는 필수 사용 사례는 다음과 같습니다.
- 배포판 X가 시스템에 설치되어 있습니까?
- 배포판 X의 어떤 버전이 설치되어 있습니까?
- 배포판 X의 새 버전은 어디에서 찾을 수 있습니까? (이를 사용자가 방문하여 다운로드 링크를 찾을 수 있는 홈페이지 또는 프로그램이 최신 버전을 찾을 수 있는 장소로 정의할 수 있습니다. 둘 다 지원하는 것이 좋습니다.)
- 배포판 X는 어떤 파일을 시스템에 설치했습니까?
- 파일 x/y/z.py는 어떤 배포판에서 가져왔습니까?
- 누군가 로컬에서 x/y/z.py를 수정했습니까?
- 이 소프트웨어에는 어떤 다른 배포판이 필요합니까?
- 이 배포판은 어떤 Python 모듈을 제공합니까?
데이터베이스 위치
데이터베이스는 <prefix>/lib/python<version>/install-db/ 아래의 여러 파일에 저장됩니다. 이 PEP의 나머지 부분에서는 이 위치를 INSTALLDB라고 부릅니다.
데이터베이스의 구조는 의도적으로 단순하게 유지되며, 이 디렉터리 또는 그 하위 디렉터리(있는 경우)의 각 파일은 하나의 배포판을 설명합니다. RPM과 같은 Python 소프트웨어의 바이너리 패키징은 해당 파일을 INSTALLDB 디렉터리에 설치하는 것만으로 Python의 데이터베이스를 업데이트할 수 있습니다.
하위 디렉터리를 검색하는 근거는 데이터베이스 디렉터리에 항목이 너무 많아질 경우 디렉터리 기반 색인 방식으로 전환할 수 있기 때문입니다. 예를 들어 이를 통해 INSTALLDB/Numeric에서 INSTALLDB/N/Nu/Numeric 또는 이와 유사한 해싱 방식으로 투명하게 전환할 수 있습니다.
데이터베이스 내용
INSTALLDB 또는 그 하위 디렉터리의 각 파일은 하나의 배포판을 설명하며, 다음과 같은 내용을 포함합니다.
공백으로 구분하여 이 파일의 섹션을 나열하는 첫 번째 줄입니다. 현재는 항상 ‘PKG-INFO FILES REQUIRES PROVIDES’입니다. 이는 향후 확장을 위한 것입니다. 예를 들어 문서 파일을 나열하기 위한 새 섹션을 추가한다면 DOCS 섹션을 추가하고 해당 섹션을 내용에 나열합니다. 섹션은 항상 빈 줄로 구분됩니다.
설치에 Distutils를 사용하는 배포판은 데이터베이스를 자동으로 업데이트해야 합니다. 자체 설치 방식을 사용하는 배포판은 데이터베이스의 API를 사용하여 자체 항목을 수동으로 추가하거나 업데이트해야 합니다. RPM 또는 pkgadd와 같은 시스템 패키지 관리자는 INSTALLDB 디렉터리에 새 파일을 생성하기만 하면 됩니다.
파일의 각 섹션은 서로 다른 용도로 사용됩니다.
PKG-INFO 섹션
파일의 배포 정보를 담은 초기 RFC 822 헤더 집합으로, PEP 241의 “Python 소프트웨어 패키지의 메타데이터”에 설명되어 있습니다.
FILES 섹션
배포판이 설치한 각 파일에 대한 항목입니다. 배포로 설치된 원래 .py 파일뿐 아니라 .pyc 및 .pyo 파일과 같은 생성된 파일도 이 목록에 포함되지만, 해당 파일의 체크섬은 저장되거나 검사되지 않습니다.
각 파일의 항목은 다음 필드를 포함하는 하나의 탭으로 구분된 줄입니다.
- 시스템에 설치된 파일의 전체 경로입니다.
- 파일의 크기입니다.
- 파일의 권한입니다. Windows에서는 이 필드가 항상 ‘unknown’입니다.
- 탭으로 구분된 파일의 소유자와 그룹입니다. Windows에서는 이 두 필드가 모두 ‘unknown’입니다.
- 16진수로 인코딩된 파일의 SHA1 다이제스트입니다. *.pyc 파일과 같은 생성된 파일의 경우 이 필드에 문자열 “-“을 포함해야 하며, 이는 파일의 체크섬을 검증하지 않아야 함을 나타냅니다.
REQUIRES 섹션
이 섹션은 이 모듈 배포판이 올바르게 실행되는 데 필요한 서비스를 나타내는 문자열 목록입니다. 이 목록에는 배포판 이름(“python-stdlib”)과 모듈 이름(“rfc822”, “htmllib”, “email”, “email.Charset”)이 포함됩니다. 이 목록은 distutils.core.setup() 함수에 추가 ‘requires’ 인자를 전달하여 지정합니다. 예를 들면 다음과 같습니다.:
setup(..., requires=['xml.utils.iso8601',
장차 모든 코드를 살펴 요구 사항 목록을 생성하는 자동화 도구가 나올 수도 있지만, 이러한 도구가 가능한 모든 경우를 처리할 가능성은 낮으므로 요구 사항을 지정하는 수동 방법은 언제나 필요합니다.
PROVIDES 섹션
이 섹션은 설치된 배포판이 제공하는 서비스를 나타내는 문자열 목록입니다. 이 목록에는 배포판 이름(“python-stdlib”)과 모듈 이름(“rfc822”, “htmllib”, “email”, “email.Charset”)이 포함됩니다.
XXX 파일도 나열해야 합니까? 예: 데이터 파일, 필요한 스크립트 등을 포함하기 위한 $PREFIX/lib/color-table.txt입니다.
장차 모듈 개발자가 이 섹션에 자체 문자열을 추가할 수 있는 옵션이 생길 수도 있습니다. 예를 들어 이 섹션에 “XML parser”를 추가하면, 다른 모듈 배포판에서 여러 서로 다른 XML 파서를 사용할 수 있음을 나타내기 위해 “XML parser”를 종속성 중 하나로 나열할 수 있습니다. 현재는 여러 문제가 발생하므로 이 기능을 지원하지 않습니다. 적법한 문자열의 중앙 레지스트리가 필요합니까, 아니면 사람들이 원하는 문자열을 자유롭게 넣도록 하면 됩니까? 기타 등등…
API 설명
단일한 기본 클래스인 InstallationDatabase가 있습니다. 이 클래스의 코드는 distutils/install_db.py에 있습니다. (XXX 표준 라이브러리에서 다른 위치를 사용하거나 모듈 이름을 다르게 지정할 것을 제안하시겠습니까?)
InstallationDatabase는 설치된 배포판에 관한 모든 정보를 포함하는 Distribution 인스턴스를 반환합니다.
XXX Distribution의 여러 필드는 distutils.dist.Distribution의 필드와 중복됩니다. 아마도 이 필드들을 여기서 제안하는 Distribution 클래스에 추출해야 하지만, 이를 하위 호환성을 유지하는 방식으로 수행할 수 있습니까?
InstallationDatabase에는 다음과 같은 인터페이스가 있습니다.:
class InstallationDatabase:
def __init__ (self, path=None):
"""InstallationDatabase(path:string)
Read the installation database rooted at the specified path.
If path is None, INSTALLDB is used as the default.
"""
def get_distribution (self, distribution_name):
"""get_distribution(distribution_name:string) : Distribution
Get the object corresponding to a single distribution.
"""
def list_distributions (self):
"""list_distributions() : [Distribution]
Return a list of all distributions installed on the system,
enumerated in no particular order.
"""
def find_distribution (self, path):
"""find_file(path:string) : Distribution
Search and return the distribution containing the file 'path'.
Returns None if the file doesn't belong to any distribution
that the InstallationDatabase knows about.
XXX should this work for directories?
"""
class Distribution:
"""Instance attributes:
name : string
Distribution name
files : {string : (size:int, perms:int, owner:string, group:string,
digest:string)}
Dictionary mapping the path of a file installed by this distribution
to information about the file.
The following fields all come from PEP 241.
version : distutils.version.Version
Version of this distribution
platform : [string]
summary : string
description : string
keywords : string
home_page : string
author : string
author_email : string
license : string
"""
def add_file (self, path):
"""add_file(path:string):None
Record the size, ownership, &c., information for an installed file.
XXX as written, this would stat() the file. Should the size/perms/
checksum all be provided as parameters to this method instead?
"""
def has_file (self, path):
"""has_file(path:string) : Boolean
Returns true if the specified path belongs to a file in this
distribution.
"""
def check_file (self, path):
"""check_file(path:string) : Boolean
Checks whether the file's size, checksum, and ownership match,
returning true if they do.
"""
산출물
이 PEP에 추가할 데이터베이스 API 설명입니다.
- InstallationDatabase 클래스를 구현하고, 2) 새 배포판이 설치될 때 데이터베이스를 업데이트하며, 3) 간단한 패키지 관리 도구를 추가하는 Distutils용 패치입니다. (또는 별도의 PEP로 분리해야 합니까?) 현재 패치는 [2]를 참조하십시오.
미해결 문제
PJE는 설치 데이터베이스가 “sys.path의 모든 디렉터리에 잠재적으로 존재하고, 내용이 sys.path 순서에 따라 병합되어야 한다고” 제안합니다. 이렇게 하면 홈 디렉터리 또는 다른 대체 위치에 설치할 수 있고, distutils install 명령이 파일을 기록하는 과정도 간소화됩니다.” 훌륭한 기능입니다. 이는 패키지 관리자 도구가 사용자가 비공개로 설치한 Python 패키지도 고려할 수 있다는 의미이기 때문입니다.
AMK는 setup.py에 sys.path에 없는 디렉터리에 패키지를 설치하라고 지시하면 어떻게 되는지 궁금해합니다. 지정된 디렉터리에 install-db 디렉터리를 기록합니까, 아니면 아무 작업도 하지 않습니까?
패키지 데이터베이스 파일 자체를 파일 목록에 포함해야 합니까? (PJE는 그렇다고 생각하겠지만, 물론 파일 자체의 체크섬을 포함할 수는 없습니다. AMK는 DB 파일을 포함하는 것이 중요한 사용 사례를 생각해 낼 수 없습니다.)
PJE는 다른 파일을 설치하기 전에 패키지 DB 파일을 먼저 기록하여, 실패한 부분 설치를 되돌리고 손상된 설치로 인식할 수 있게 하는 방안을 궁금해합니다. 이 PEP는 이러한 상황을 인식하기 위한 알고리즘을 지정해야 할 수도 있습니다.
설치 데이터베이스의 형식이 Python 버전 간에 호환성을 유지한다고 보장해야 합니까, 아니면 임의로 변경될 수 있습니까? 아마도 호환성을 보장해야 할 것입니다.
거부된 제안
배포판마다 텍스트 파일 하나를 사용하는 대신, 하나의 큰 텍스트 파일이나 anydbm 파일을 사용할 수 있습니다. 이는 몇 가지 이유로 거부되었습니다. 첫째, 데이터베이스는 비교적 드물게 수행되는 작업인 소프트웨어 설치 또는 제거 시에만 사용되므로 성능은 아마도 매우 시급한 문제가 아닙니다. 확장성도 문제가 되지 않을 가능성이 큽니다. 사람들이 수백 개의 Python 패키지를 설치할 수는 있지만, 수천 개나 수만 개를 설치할 가능성은 낮아 보입니다. 마지막으로, 개별 텍스트 파일은 RPM이나 DPKG 같은 설치 프로그램과 호환됩니다. 바이너리 패키지 제작자는 새 데이터베이스 파일을 데이터베이스 디렉터리에 추가하기만 하면 되기 때문입니다. 하나의 큰 텍스트 파일이나 바이너리 파일을 사용한다면, Python 데이터베이스는 postinstall 스크립트를 실행하여 업데이트해야 합니다.
Windows에서는 파일의 권한과 소유자/그룹이 저장되지 않습니다. 실제로 Windows는 소유권과 액세스 권한을 지원하지만, 이를 읽고 설정하려면 win32all 확장이 필요하며, 해당 확장은 Windows용 기본 Python 설치 프로그램에 포함되어 있지 않습니다.
참고 문헌
[1] Michael Muller의 패치(1999년 12월 28일경 Distutils-SIG에 게시됨)는 설치된 파일 목록을 생성합니다.
감사의 말
이 PEP에 대한 아이디어는 원래 Greg Ward, Fred L. Drake Jr., Thomas Heller, Mats Wichmann, Phillip J. Eby 등의 게시물에서 비롯되었습니다.
이 문서에 대한 많은 변경과 재작성은 Distutils SIG 독자들의 제안에 따른 것입니다.
Copyright
This document has been placed in the public domain.