[Withdrawn] PEP 650 - Specifying Installer Requirements for Python Projects
원문 링크: PEP 650 - Specifying Installer Requirements for Python Projects
상태: Withdrawn 유형: Standards Track 작성일: 16-Jul-2020
PEP 650 – Python 프로젝트를 위한 설치 프로그램 요구사항 명세 (Withdrawn)
작성자: Vikram Jayanthi, Dustin Ingram, Brett Cannon 토론: Discourse 스레드 상태: 철회됨 (Withdrawn) 유형: 표준 트랙 (Standards Track) 주제: 패키징 (Packaging) 생성일: 2020년 7월 16일 이력: 2021년 1월 14일
초록 (Abstract)
현재 Python 패키지 설치 프로그램들은 서로 완전히 상호 운용되지 않습니다. pip
이 가장 널리 사용되는 사실상의 표준이지만, Poetry나 Pipenv 같은 다른 설치 프로그램들도 특정 워크플로우에 최적화된 고유한 기능을 제공하여 인기가 많습니다.
다양한 설치 프로그램 옵션이 특정 요구사항을 가진 최종 사용자에게는 좋지만, 이들 간의 상호 운용성 부족은 모든 잠재적 설치 프로그램을 지원하기 어렵게 만듭니다. 특히, 종속성을 선언하는 표준화된 요구사항 파일이 없기 때문에, 각 도구는 해당 형식으로 지정된 종속성을 설치하기 위해 명시적으로 사용되어야 합니다. 그렇지 않으면 도구는 요구사항 파일을 내보내야 하는데, 이는 설치 프로그램에 대한 잠재적인 정보 손실과 개발자 워크플로우의 추가적인 내보내기 단계를 초래합니다.
호환 가능한 설치 프로그램을 호출하는 데 사용할 수 있는 표준화된 API를 제공함으로써, 우리는 다양한 설치 프로그램과 그들의 록 파일(lock file) 간의 개별적인 문제, 고유한 요구사항 및 비호환성을 해결할 필요 없이 이 문제를 해결할 수 있습니다.
이 사양을 구현하는 설치 프로그램은 균일한 방식으로 호출될 수 있으며, 사용자는 마치 직접 호출하는 것처럼 원하는 설치 프로그램을 사용할 수 있습니다.
용어 (Terminology)
- Installer interface (설치 프로그램 인터페이스): 설치 프로그램 백엔드와 범용 설치 프로그램이 상호 작용하는 인터페이스입니다.
- Universal installer (범용 설치 프로그램): 설치 프로그램 인터페이스의 선택적 호출 메서드를 호출하여 설치 프로그램 백엔드를 호출할 수 있는 설치 프로그램입니다. 이는 PEP 517의
build
프로젝트처럼 설치 프로그램 프런트엔드로도 생각할 수 있습니다. - Installer backend (설치 프로그램 백엔드): 설치 프로그램 인터페이스를 구현하여 범용 설치 프로그램에 의해 호출될 수 있는 설치 프로그램입니다. 설치 프로그램 백엔드는 범용 설치 프로그램일 수도 있지만 필수는 아닙니다. PEP 517과 비교하면
Flit
에 해당합니다. 설치 프로그램 백엔드는 기반 설치 프로그램(backing installer)을 감싸는 래퍼(wrapper) 패키지일 수 있습니다. 예를 들어, Poetry는 이 API를 지원하지 않기로 선택할 수 있지만, 패키지는 Poetry를 사용하여 설치를 수행하는 데 적절하게 Poetry를 호출하는 래퍼 역할을 할 수 있습니다. - Dependency group (종속성 그룹): 어떤 목적을 위해 동시에 설치해야 하는 관련 종속성 집합입니다. 예를 들어, “test” 종속성 그룹에는 테스트 스위트를 실행하는 데 필요한 종속성이 포함될 수 있습니다. 종속성 그룹을 지정하는 방법은 설치 프로그램 백엔드에 달려 있습니다.
동기 (Motivation)
이 사양은 지정된 인터페이스를 구현하는 설치 프로그램 백엔드를 누구나 호출하고 상호 작용할 수 있도록 하여, 기존 도구별 설치 프로세스 위에 보편적으로 지원되는 계층을 가능하게 합니다.
이는 결과적으로 이 사양을 구현하는 모든 설치 프로그램이 단일 범용 설치 프로그램을 지원하는 환경에서 사용될 수 있도록 합니다.
아래에서는 Python 커뮤니티의 이해관계자와 Python 패키지 설치 프로그램과 상호 작용하는 모든 사람에게 적용할 수 있는 다양한 사용 사례를 식별합니다. 개발자나 기업의 경우, 이 PEP는 Python 패키지 설치 프로그램의 기능과 유연성을 증가시킬 것입니다.
제공자 (Providers)
제공자는 Python 패키징 및 Python 패키지 설치 프로그램과 상호 작용하는 서비스 또는 소프트웨어 도구를 제공하는 당사자(조직, 사람, 커뮤니티 등)입니다. 두 가지 유형의 제공자가 고려됩니다.
-
플랫폼/인프라 제공자 (Platform/Infrastructure Providers): 클라우드 환경, 애플리케이션 호스팅 등 플랫폼 제공자와 인프라 서비스 제공자는 사용자가 Python 종속성을 설치할 수 있도록 패키지 설치 프로그램을 지원해야 합니다. 대부분
pip
만 지원하지만, 다른 Python 설치 프로그램에 대한 사용자 요구도 있습니다. 대부분의 제공자는 소프트웨어 또는 서비스에 추가되는 복잡성과 그에 필요한 리소스 때문에 두 개 이상의 설치 프로그램을 유지 관리하는 것을 원하지 않습니다. 이 사양을 통해 제공자 지원 범용 설치 프로그램은 제공자 플랫폼이 해당 백엔드에 대한 특정 지식이 없더라도 사용자가 원하는 설치 프로그램 백엔드를 호출할 수 있습니다. 이는 Poetry가 이 PEP가 제안한 설치 프로그램 백엔드 API를 구현한다면(또는 다른 패키지가 Poetry를 래핑하여 API를 제공한다면), 플랫폼 제공자가 Poetry를 암묵적으로 지원할 것이라는 의미입니다. -
IDE 제공자 (IDE Providers): 통합 개발 환경(IDE)은 Python 패키지 설치 및 관리와 상호 작용할 수 있습니다. 대부분
pip
만 Python 패키지 설치 프로그램으로 지원하며, 사용자는 다른 패키지 설치 프로그램을 사용하여 종속성을 설치하기 위한 해결 방법을 찾아야 합니다. PaaS 및 IaaS 제공자와 유사하게, IDE 제공자는 N개의 다른 Python 설치 프로그램을 지원하는 것을 원하지 않습니다. 대신, 설치 프로그램 인터페이스(설치 프로그램 백엔드)를 구현하는 사람들은 IDE가 범용 설치 프로그램 역할을 함으로써 호출될 수 있습니다.
개발자 (Developers)
개발자는 Python 패키지 설치 프로그램과 Python 패키지를 코딩하고 사용하는 팀, 사람 또는 커뮤니티입니다. 세 가지 유형의 개발자가 고려됩니다.
-
PaaS 및 IaaS 제공자를 사용하는 개발자 (Developers using PaaS & IaaS providers): 대부분의 PaaS 및 IaaS 제공자는 하나의 Python 패키지 설치 프로그램인
pip
만 지원합니다. (예외로는pip
과Pipenv
를 모두 지원하는 Heroku의 Python 빌드팩이 있습니다.) 이는 개발자가 이러한 제공자와 작업할 때 사용할 수 있는 설치 프로그램을 제한하며, 이는 애플리케이션이나 워크플로우에 최적이지 않을 수 있습니다. 이 PEP를 채택하여 설치 프로그램 백엔드가 되는 설치 프로그램은 사용자가 제공자가 범용 설치 프로그램을 사용하는 한, 어떤 Python 패키지 설치 프로그램을 사용해야 하는지 걱정할 필요 없이 타사 플랫폼/인프라를 사용할 수 있도록 합니다. -
IDE를 사용하는 개발자 (Developers using IDEs): 대부분의 IDE는
pip
또는 몇 가지 Python 패키지 설치 프로그램만 지원합니다. 결과적으로, 개발자는 지원되지 않는 패키지 설치 프로그램을 사용하는 경우 종속성을 설치하기 위해 해결 방법이나 임시방편적인 방법을 사용해야 합니다. IDE가 범용 설치 프로그램을 사용/제공한다면, 개발자가 원하는 설치 프로그램 백엔드를 사용하여 종속성을 설치할 수 있게 되어, IDE의 워크플로우에 더 밀접하게 통합하기 위해 종속성을 설치하는 데 필요한 추가 작업을 없앨 수 있습니다. -
다른 개발자와 협업하는 개발자 (Developers working with other developers): 개발자는 다른 개발자와 협업할 때 자신이 선택한 설치 프로그램을 사용하고 싶어 하지만, 현재는 종속성 설치의 호환성을 위해 설치 프로그램 선택을 동기화해야 합니다. 모든 선호 설치 프로그램이 대신 지정된 인터페이스를 구현한다면, 설치 프로그램의 상호 사용이 가능해져 개발자가 협업자의 선호도와 관계없이 설치 프로그램을 선택할 수 있습니다.
업그레이더 및 패키지 인프라 제공자 (Upgraders & Package Infrastructure Providers)
Dependabot, PyUP 등 CI/CD의 패키지 업그레이더 및 패키지 인프라는 현재 몇 가지 설치 프로그램을 지원합니다. 이들은 requirements.txt
또는 poetry.lock
과 같은 설치 프로그램별 종속성 파일을 관련 패키지 정보(업그레이드, 다운그레이드 또는 새 해시)로 직접 파싱하고 편집하여 작동합니다. 플랫폼 및 IDE 제공자와 유사하게, 이러한 제공자들은 N개의 다른 파일 유형을 지원해야 하므로 N개의 다른 Python 패키지 설치 프로그램을 지원하는 것을 원하지 않습니다.
현재 이러한 서비스/봇은 각 패키지 설치 프로그램에 대해 개별적으로 지원을 구현해야 합니다. 필연적으로 가장 인기 있는 설치 프로그램이 먼저 지원되며, 덜 인기 있는 도구는 종종 전혀 지원되지 않습니다. 이 사양을 구현함으로써 이러한 서비스/봇은 모든 (준수하는) 설치 프로그램을 지원할 수 있으므로, 사용자는 원하는 도구를 선택할 수 있습니다. 이는 플랫폼과 IDE가 더 이상 “승자”를 조기에 선택할 필요가 없으므로 해당 분야의 혁신을 더욱 촉진할 것입니다.
오픈 소스 커뮤니티 (Open Source Community)
설치 프로그램 요구사항을 명시하고 이 PEP를 채택하면 Python 패키지 설치 프로그램과 사람들의 워크플로우 간의 마찰이 줄어들 것입니다. 결과적으로 Python 패키지 설치 프로그램과 PaaS 또는 IDE와 같은 타사 인프라/기술 간의 마찰도 줄어들 것입니다. 전반적으로 Python 패키지 설치가 더 간단하고 상호 운용성이 높아지면서 Python 프로젝트의 개발, 배포 및 유지 관리가 더 쉬워질 것입니다.
설치 프로그램에 대한 요구사항을 명시하고 인터페이스를 생성하면 설치 프로그램 주변의 혁신 속도를 높일 수도 있습니다. 이는 설치 프로그램이 나머지 생태계가 동일하게 따를 필요 없이 고유한 기능을 실험하고 추가할 수 있도록 할 것입니다. 새로운 설치 프로그램에 대한 지원은 추가하는 기능과 종속성을 작성하는 형식에 관계없이 더 쉬워지고 가능성이 높아지며, 이를 위해 필요한 개발자 시간과 리소스를 줄일 수 있습니다.
명세 (Specification)
PEP 517이 빌드 시스템을 지정하는 방식과 유사하게, 설치 시스템 정보는 pyproject.toml
파일의 [install-system]
테이블에 저장됩니다.
[install-system]
테이블은 설치 시스템 관련 데이터 및 정보를 저장하는 데 사용됩니다. 이 테이블에는 requires
와 install-backend
라는 여러 필수 키가 있습니다. requires
키는 설치 프로그램 백엔드가 실행하는 데 필요한 최소 요구사항을 담고 있으며, 이는 범용 설치 프로그램에 의해 설치될 것입니다. install-backend
키는 설치 백엔드의 진입점(entry point) 이름을 담고 있습니다. 이는 범용 설치 프로그램이 설치 프로그램 백엔드 자체(설치 프로그램 백엔드 자체가 설치할 요구사항이 아님)를 실행하는 데 필요한 요구사항을 설치하고 설치 프로그램 백엔드를 호출할 수 있도록 합니다.
필수 키 중 하나라도 누락되거나 비어 있으면 범용 설치 프로그램은 오류를 발생시켜야 합니다 (SHOULD
raise an error).
이 인터페이스와 상호 작용하는 모든 패키지 이름은 PEP 508의 “Python 소프트웨어 패키지 종속성 명세” 형식을 따르는 것으로 가정합니다.
install-system
테이블의 예시:
#pyproject.toml
[install-system]
#Eg : pipenv
requires = ["pipenv"]
install-backend = "pipenv.api:main"
설치 프로그램 요구사항: (Installer Requirements:)
requires
키로 지정된 요구사항은 PEP 517이 지정한 제약 조건 내에 있어야 합니다. 특히 종속성 순환은 허용되지 않으며, 순환이 감지되면 범용 설치 프로그램은 종속성 설치를 거부해야 합니다 (SHOULD
refuse to install).
추가 매개변수 또는 도구별 데이터 (Additional parameters or tool specific data)
추가 매개변수 또는 도구(설치 프로그램 백엔드) 데이터도 pyproject.toml
파일에 저장될 수 있습니다. 이는 PEP 518에 지정된 대로 “tool.*” 테이블에 있을 것입니다. 예를 들어, 설치 프로그램 백엔드가 Poetry이고 여러 종속성 그룹을 지정하려면 tool.poetry
테이블은 다음과 같을 수 있습니다.
[tool.poetry.dev-dependencies]
dependencies = "dev"
[tool.poetry.deploy]
dependencies = "deploy"
데이터는 설치 프로그램 백엔드가 적절하다고 판단하는 다른 방식으로도 저장될 수 있습니다 (예: 별도의 구성 파일).
설치 프로그램 인터페이스: (Installer interface:)
설치 프로그램 인터페이스에는 필수 mandatory hooks
와 선택적 optional hooks
이 포함됩니다. 규격을 준수하는 설치 프로그램 백엔드는 필수 hooks
를 구현해야 하고(MUST
), 선택적 hooks
는 구현할 수도 있습니다(MAY
). 범용 설치 프로그램은 자체적으로 설치 프로그램 백엔드 hooks
를 구현하여 범용 설치 프로그램이자 설치 프로그램 백엔드 역할을 할 수 있지만, 필수는 아닙니다.
모든 hook
는 **kwargs
임의 매개변수를 받는데, 이는 설치 프로그램 백엔드가 아직 지정되지 않은 추가 정보를 필요로 할 수 있도록 하여 하위 호환성을 허용합니다. 예상치 못한 매개변수가 설치 프로그램 백엔드로 전달되면 무시해야 합니다.
다음 정보는 PEP 517의 해당 섹션과 유사합니다. hook
는 키워드 인수를 사용하여 호출될 수 있으므로, 이를 구현하는 설치 프로그램 백엔드는 해당 서명이 위 인수의 순서와 이름 모두와 일치하는지 확인해야 합니다.
모든 hook
는 임의의 정보성 텍스트를 stdout
및 stderr
로 출력할 수 있습니다 (MAY
print). stdin
에서 읽어서는 안 되며 (MUST NOT
), 범용 설치 프로그램은 hook
를 호출하기 전에 stdin
을 닫을 수 있습니다 (MAY
close).
범용 설치 프로그램은 백엔드의 stdout
및/또는 stderr
를 캡처할 수 있습니다. 백엔드가 출력 스트림이 터미널/콘솔이 아님을 감지하면 (예: sys.stdout.isatty()
가 아님), 해당 스트림에 기록하는 모든 출력이 UTF-8로 인코딩되도록 해야 합니다 (SHOULD
ensure). 범용 설치 프로그램은 캡처된 출력이 유효한 UTF-8이 아니더라도 실패해서는 안 되지만 (MUST NOT
fail), 이 경우 모든 정보를 보존하지 못할 수 있습니다 (예: Python에서 replace
오류 핸들러를 사용하여 디코딩할 수 있음). 출력 스트림이 터미널인 경우, 설치 프로그램 백엔드는 터미널에서 실행되는 모든 프로그램과 마찬가지로 출력을 정확하게 표시할 책임이 있습니다.
hook
가 예외를 발생시키거나 프로세스가 종료되면 이는 오류를 나타냅니다.
필수 Hooks (Mandatory hooks):
invoke_install
종속성을 설치합니다:def invoke_install( path: Union[str, bytes, PathLike[str]], *, dependency_group: str = None, **kwargs ) -> int: ...
path
: 설치 프로그램 백엔드가 호출되어야 하는 절대 경로입니다 (예:pyproject.toml
이 있는 디렉터리).dependency_group
: 설치 프로그램 백엔드가 설치해야 하는 종속성 그룹을 지정하는 선택적 플래그입니다. 종속성 그룹이 존재하지 않으면 설치는 오류를 발생시킬 것입니다. 종속성 그룹이 설치 프로그램 백엔드에서 지원되는 경우get_dependency_groups()
를 호출하여 모든 종속성 그룹을 찾을 수 있습니다.**kwargs
: 설치 프로그램 백엔드가 필요할 수 있는 임의의 매개변수이며, 아직 지정되지 않은 것들을 포함하여 하위 호환성을 허용합니다.Returns
: 종료 코드(int
). 성공 시 0, 실패 시 양의 정수입니다.
범용 설치 프로그램은 종료 코드를 사용하여 설치 성공 여부를 판단하고 자체적으로 종료 코드를 반환해야 합니다 (
SHOULD
return).
선택적 Hooks (Optional hooks):
invoke_uninstall
지정된 종속성을 제거합니다:def invoke_uninstall( path: Union[str, bytes, PathLike[str]], *, dependency_group: str = None, **kwargs ) -> int: ...
path
: 설치 프로그램 백엔드가 호출되어야 하는 절대 경로입니다 (예:pyproject.toml
이 있는 디렉터리).dependency_group
: 설치 프로그램 백엔드가 제거해야 하는 종속성 그룹을 지정하는 선택적 플래그입니다.**kwargs
: 설치 프로그램 백엔드가 필요할 수 있는 임의의 매개변수이며, 아직 지정되지 않은 것들을 포함하여 하위 호환성을 허용합니다.Returns
: 종료 코드(int
). 성공 시 0, 실패 시 양의 정수입니다.
범용 설치 프로그램은 범용 설치 프로그램 자체가 호출된 것과 동일한 경로에서 설치 프로그램 백엔드를 호출해야 합니다 (
MUST
invoke).범용 설치 프로그램은 종료 코드를 사용하여 제거 성공 여부를 판단하고 자체적으로 종료 코드를 반환해야 합니다 (
SHOULD
return).get_dependencies_to_install
invoke_install(...)
에 의해 설치될 종속성을 반환합니다. 이를 통해 패키지 업그레이더(예: Dependabot)는 종속성 파일을 파싱하지 않고도 설치하려는 종속성을 검색할 수 있습니다.def get_dependencies_to_install( path: Union[str, bytes, PathLike[str]], *, dependency_group: str = None, **kwargs ) -> Sequence[str]: ...
path
: 설치 프로그램 백엔드가 호출되어야 하는 절대 경로입니다 (예:pyproject.toml
이 있는 디렉터리).dependency_group
: 해당 종속성 그룹에 대해invoke_install(...)
이 설치할 종속성을 가져올 종속성 그룹을 지정합니다.**kwargs
: 설치 프로그램 백엔드가 필요할 수 있는 임의의 매개변수이며, 아직 지정되지 않은 것들을 포함하여 하위 호환성을 허용합니다.Returns
: 설치할 종속성 목록 (PEP 508 문자열)입니다.
그룹이 지정된 경우, 설치 프로그램 백엔드는 제공된 종속성 그룹에 해당하는 종속성을 반환해야 합니다 (
MUST
return). 지정된 그룹이 존재하지 않거나 종속성 그룹이 설치 프로그램 백엔드에서 지원되지 않는 경우, 설치 프로그램 백엔드는 오류를 발생시켜야 합니다 (MUST
raise an error).그룹이 지정되지 않고 설치 프로그램 백엔드가 기본/미지정 그룹의 개념을 제공하는 경우, 설치 프로그램 백엔드는 기본/미지정 그룹에 대한 종속성을 반환할 수 있지만 (
MAY
return), 그렇지 않으면 오류를 발생시켜야 합니다 (MUST
raise an error).get_dependency_groups
설치 가능한 종속성 그룹을 반환합니다. 이를 통해 범용 설치 프로그램은 설치 프로그램 백엔드가 알고 있는 모든 종속성 그룹을 열거할 수 있습니다.def get_dependency_groups( path: Union[str, bytes, PathLike[str]], **kwargs ) -> AbstractSet[str]: ...
path
: 설치 프로그램 백엔드가 호출되어야 하는 절대 경로입니다 (예:pyproject.toml
이 있는 디렉터리).**kwargs
: 설치 프로그램 백엔드가 필요할 수 있는 임의의 매개변수이며, 아직 지정되지 않은 것들을 포함하여 하위 호환성을 허용합니다.Returns
: 알려진 종속성 그룹의 집합 (set
)이며, 문자열입니다. 빈 집합은 종속성 그룹이 없음을 나타냅니다.
update_dependencies
입력된 패키지 목록을 기반으로 종속성 파일을 출력합니다.def update_dependencies( path: Union[str, bytes, PathLike[str]], dependency_specifiers: Iterable[str], *, dependency_group=None, **kwargs ) -> int: ...
path
: 설치 프로그램 백엔드가 호출되어야 하는 절대 경로입니다 (예:pyproject.toml
이 있는 디렉터리).dependency_specifiers
: 예를 들어["requests==2.8.1", ...]
와 같이 업데이트되는 PEP 508 문자열 형태의 종속성 이터러블(iterable)입니다. 특정 종속성 그룹에 대한 선택 사항입니다.dependency_group
: 패키지 목록이 속한 종속성 그룹입니다.**kwargs
: 설치 프로그램 백엔드가 필요할 수 있는 임의의 매개변수이며, 아직 지정되지 않은 것들을 포함하여 하위 호환성을 허용합니다.Returns
: 종료 코드(int
). 성공 시 0, 실패 시 양의 정수입니다.
예시 (Example)
pip
과 requirements
파일을 종속성 그룹에 사용하는 설치 프로그램 백엔드를 구현한다고 가정해 봅시다. 구현은 (매우 대략적으로) 다음과 같을 수 있습니다.
import subprocess
import sys
def invoke_install(path, *, dependency_group=None, **kwargs):
try:
return subprocess.run(
[
sys.executable,
"-m",
"pip",
"install",
"-r",
dependency_group or "requirements.txt",
],
cwd=path,
).returncode
except subprocess.CalledProcessError as e:
return e.returncode
이 패키지의 이름을 pep650pip
이라고 한다면, pyproject.toml
에 다음과 같이 지정할 수 있습니다.
[install-system]
#Eg : pipenv
requires = ["pep650pip", "pip"]
install-backend = "pep650pip:main"
이론적 근거 (Rationale)
모든 hook
가 **kwargs
를 받는 것은 하위 호환성을 허용하고, hook
에서 요구하지 않는 추가 정보를 사용자에게 제공해야 하는 도구별 설치 프로그램 백엔드 기능을 허용하기 위함입니다.
설치 프로그램 백엔드는 Python 패키지여야 하지만, 호출될 때 무엇을 하는지는 해당 도구의 구현 세부 사항입니다. 예를 들어, 설치 프로그램 백엔드는 플랫폼 패키지 관리자(예: apt
)의 래퍼 역할을 할 수 있습니다.
이 인터페이스는 설치 프로그램 백엔드가 어떻게 작동해야 하는지에 대해 어떤 식으로든 지정하려고 하지 않습니다. 이는 설치 프로그램 백엔드가 자체적인 방식으로 혁신하고 문제를 해결할 수 있도록 하기 위함입니다. 이는 또한 이 PEP가 OS 패키징에 대한 입장을 취하지 않음을 의미하며, 이는 설치 프로그램 백엔드의 영역입니다.
API를 Python으로 정의한다는 것은 결국 일부 Python 코드가 실행되어야 함을 의미합니다. 그러나 이는 비-Python 설치 프로그램 백엔드(예: mamba
)가 사용되는 것을 배제하지 않는데, 이러한 백엔드는 Python 코드에서 서브프로세스로 실행될 수 있기 때문입니다.
하위 호환성 (Backwards Compatibility)
이 PEP는 범용 설치 프로그램에 새로운 기능을 추가할 뿐이므로 기존 코드 및 기능에는 영향을 미치지 않습니다. 모든 기존 설치 프로그램은 기존 기능 및 사용 사례를 유지해야 하므로, 하위 호환성 문제가 없습니다. 이 새로운 기능을 활용하려는 코드만이 기존 코드를 변경할 동기를 가질 것입니다.
보안 관련 사항 (Security Implications)
표준화된 설치 프로그램 사양의 추가로 악의적인 사용자가 어떤 것에 대한 능력이나 접근 권한을 더 쉽게 얻는 것은 없습니다. 이 PEP에 지정된 인터페이스를 통해 범용 설치 프로그램이 호출할 수 있는 설치 프로그램은 사용자에 의해 명시적으로 선언될 것입니다. 사용자가 악의적인 설치 프로그램을 선택했다면, 범용 설치 프로그램으로 호출하는 것은 사용자가 설치 프로그램을 직접 호출하는 것과 다르지 않습니다. 악의적인 설치 프로그램이 설치 프로그램 백엔드라고 해서 추가적인 권한이나 능력을 얻는 것은 아닙니다.
거부된 아이디어 (Rejected Ideas)
표준화된 록 파일 (A standardized lock file)
표준화된 록 파일은 설치 프로그램 요구사항을 명시하는 것과 동일한 많은 문제를 해결할 수 있을 것입니다. 예를 들어, PaaS/IaaS가 생성한 설치 프로그램과 관계없이 표준화된 록 파일을 읽을 수 있는 단일 설치 프로그램만 지원할 수 있도록 할 것입니다. 표준화된 록 파일의 문제는 Python 패키지 설치 프로그램 간의 요구사항 차이와 록 파일을 통한 재현 가능한 환경 생성(주요 이점 중 하나)에 대한 근본적인 문제입니다.
설치 프로그램 간의 종속성 파일에 저장되는 요구사항과 정보는 상당히 다르며 설치 프로그램 기능에 따라 달라집니다. 예를 들어, Poetry와 같은 Python 패키지 설치 프로그램은 모든 Python 버전 및 플랫폼에 대한 정보를 요구하고 적절한 해시를 계산하는 반면, pip
은 그렇지 않습니다. 또한 pip
은 자체 기능 범위 밖이므로 동일한 환경을 재현(정확히 동일한 종속성을 설치)하는 것을 보장할 수 없습니다. 이는 표준화된 록 파일을 구현하기 어렵게 만들고 록 파일이 도구별로 되는 것이 더 적절해 보입니다.
설치 프로그램 백엔드가 가상 환경 생성을 지원하도록 함 (Have installer backends support creating virtual environments)
설치 프로그램 백엔드가 가상 환경 및 그 안에 설치하는 방법에 대한 개념을 가질 가능성이 매우 높기 때문에, 가상 환경 생성도 지원하도록 하는 것이 잠시 고려되었습니다. 그러나 결국 이는 직교적인(orthogonal) 아이디어로 간주되었습니다.
열린 문제 (Open Issues)
dependency_group
인수가 이터러블을 받아야 하는가? (Should the dependency_group argument take an iterable?)
이는 단일 호출에서 겹치지 않는 종속성 그룹을 지정할 수 있도록 할 것입니다. 예를 들어, 독립적인 종속성을 가지지만 개발자가 개발 중에 동시에 설치하기를 원할 수 있는 “docs” 및 “test” 그룹과 같습니다.
설치 프로그램 백엔드는 프로세스 내에서 실행되는가? (Is the installer backend executed in-process?)
설치 프로그램 백엔드가 프로세스 내에서 실행되면, 라이브 Python 환경에서 적절한 정보를 질의할 수 있으므로 설치할/설치될 환경을 아는 것이 크게 단순화됩니다.
프로세스 외부에서 실행하면 설치될 환경과 설치 프로그램 백엔드(및 잠재적으로 범용 설치 프로그램) 간의 충돌 가능성을 최소화할 수 있습니다.
제안된 인터페이스의 결과가 다른 부분으로 전달되도록 강제해야 하는가? (Enforce that results from the proposed interface feed into other parts?)
예를 들어, get_dependencies_to_install()
및 get_dependency_groups()
의 결과는 invoke_install()
로 전달될 수 있습니다. 이는 제안된 인터페이스의 다양한 부분 결과 간의 불일치를 방지하지만, 인터페이스의 더 많은 부분을 선택 사항이 아닌 필수로 만듭니다.
실패 조건에 대해 종료 코드 대신 예외를 발생시키는가? (Raising exceptions instead of exit codes for failure conditions)
API가 종료 코드를 반환하는 대신 예외를 발생시켜야 한다는 제안이 있었습니다. 이 PEP를 현재 설치 프로그램을 설치 프로그램 백엔드로 변환하는 데 도움이 되는 것으로 본다면, 종료 코드에 의존하는 것이 합리적입니다. 또한 API에 특정 반환 값이 없으므로 종료 코드를 전달하는 것이 함수의 반환 값과 충돌하지 않는다는 점도 있습니다.
오류 발생 시 예외를 발생시키는 것과 비교해 보세요. 이는 오류 발생에 대한 보다 구조화된 접근 방식을 제공할 수 있지만, 오류를 캡처하려면 인터페이스의 일부로 예외 유형을 지정해야 합니다.
저작권 (Copyright)
이 문서는 퍼블릭 도메인 또는 CC0-1.0-Universal 라이선스 중 더 허용적인 조건으로 제공됩니다.
출처: https://peps.python.org/pep-0650/ 최종 수정일: 2025-02-01 08:55:40 GMT
⚠️ 알림: 이 문서는 AI를 활용하여 번역되었으며, 기술적 정확성을 보장하지 않습니다. 정확한 내용은 반드시 원문을 확인하시기 바랍니다.
Comments