PEP 771 – Python 소프트웨어 패키지를 위한 기본 엑스트라
- Author:
- Thomas Robitaille <thomas.robitaille at gmail.com>, Jonathan Dekhtiar <jonathan at dekhtiar.com>
- Sponsor:
- Pradyun Gedam <pradyunsg at gmail.com>
- Discussions-To:
- Discourse thread
- Status:
- Draft
- Type:
- Standards Track
- Topic:
- Packaging
- Created:
- 13-Jan-2025
- Post-History:
- 15-Jan-2025, 06-Feb-2025, 09-Jun-2025
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
PEP 508은 패키지 의존성을 선언하기 위한 미니 언어를 규정합니다. 이 언어의 기능 중 하나는 엑스트라를 지정할 수 있다는 것입니다. 엑스트라는 배포 패키지의 선택적 구성 요소로, 사용하면 추가 의존성을 설치합니다. 이 PEP는 명시적으로 지정된 엑스트라가 없을 때 하나 이상의 엑스트라가 기본으로 설치되도록 하는 메커니즘을 제안합니다.
동기
기본 엑스트라의 다양한 사용 사례와 이 PEP에서 고려한 가능한 해결책은 이 DPO 스레드에서 폭넓게 논의되었습니다. 이러한 사례는 크게 두 가지로 나뉘며, 이 두 가지가 이 PEP의 동기가 됩니다.
필수는 아니지만 권장되는 의존성
패키지 유지 관리자는 패키지의 기능이나 성능을 확장하는 선택적 의존성을 선언할 때 엑스트라를 자주 사용합니다. 어떤 의존성을 필수로 두고 어떤 의존성을 엑스트라로 분류해야 할지 판단하기 어려운 경우가 있습니다. 대부분의 기능을 기본으로 사용할 수 있기를 바라는 일반 사용자의 요구와, 크기가 큰 선택적 의존성 없이 최소한으로 설치하기를 원하는 사용자의 요구 사이에서 균형을 잡아야 합니다. 기존 Python 패키징 인프라에서 쓸 수 있는 해결책 하나는 패키지 유지 관리자가 예를 들어 recommended라는 엑스트라를 정의하고, 필수는 아니지만 권장되는 모든 의존성을 여기에 포함하는 것입니다. 그런 다음 사용자에게는 package[recommended]로 패키지를 설치하도록 안내하고, 더 세밀하게 제어하기를 원하는 사용자는 package를 사용하면 됩니다. 하지만 실제로는 [recommended] 문법을 모르는 사용자가 많으며, 일반적인 설치를 하려면 사용자가 이를 알고 있어야 한다는 부담을 지게 됩니다. 권장 의존성을 기본으로 설치하면서도 사용자가 더 최소한의 설치를 요청할 수 있는 방법이 있다면 이 사용 사례를 충족할 수 있으며, 이 PEP는 이에 대한 해결책을 설명합니다.
사용자에게 추가 의존성을 기본으로 포함하도록 권장하여 이 패턴을 보여 주는 패키지의 예는 다음과 같습니다:
여러 백엔드나 프런트엔드를 지원하는 패키지
엑스트라의 또 다른 흔한 사용 사례는 서로 다른 백엔드나 프런트엔드를 정의하고, 각 백엔드나 프런트엔드마다 설치해야 하는 의존성을 정의하는 것입니다. 패키지가 동작하려면 적어도 하나의 백엔드나 프런트엔드가 설치되어 있어야 할 수 있지만, 그것이 어떤 백엔드나 프런트엔드인지는 유연하게 허용할 수 있습니다. 이러한 프런트엔드나 백엔드의 구체적인 예는 다음과 같습니다:
- PyQt5, PyQt6, PySide2, PySide6 중 하나로 제공될 수 있는 Qt 프런트엔드 라이브러리
- MySQL, PostgreSQL, SQLite 등의 백엔드 데이터베이스
현재의 패키징 표준에서는 유지 관리자가 백엔드나 프런트엔드 중 하나를 필수로 지정하거나, 사용자가 항상 package[backend]처럼 엑스트라를 지정하도록 요구해야 합니다. 따라서 사용자가 package만 설치하면 사용할 수 없는 설치 상태가 될 위험이 있습니다. 하나 이상의 기본 백엔드나 프런트엔드를 지정하고 이 기본값을 재정의할 수 있는 방법이 있다면 사용자 경험이 훨씬 나아질 것이며, 이 PEP에서 설명하는 방식으로 이것이 가능해집니다.
이 PEP는 충돌하거나 호환되지 않는 엑스트라를 금지하는 문제, 예를 들어 패키지가 프런트엔드나 백엔드 패키지를 정확히 하나만 요구하는 경우를 해결하려는 것이 아니라는 점에 유의하십시오. 현재 Python 패키징 인프라에는 충돌하거나 호환되지 않는 엑스트라의 설치를 금지하는 메커니즘이 없으며, 이 PEP도 이를 바꾸지 않습니다.
동작하려면 적어도 하나의 백엔드나 프런트엔드가 필요하고, 백엔드나 프런트엔드를 설치하기 위한 기본 엑스트라를 권장하는 패키지의 예는 다음과 같습니다:
세 경우 모두 엑스트라 없이 패키지를 설치하면 설치가 제대로 동작하지 않으며, 이는 이 패키지들 중 일부에서 흔히 보고되는 지원 문의 사례입니다.
근거
커뮤니티는 여러 해 동안 이 DPO 스레드를 비롯하여 수많은 이슈와 풀 리퀘스트에서 가능한 여러 해법을 폭넓게 논의해 왔습니다. 아래에 제시하는 해법은 다음과 같습니다:
- 옵트인 방식의 해법이므로 패키지 유지 관리자가 사용 여부를 선택할 수 있습니다
- Motivation에서 설명한 두 가지 주요 사용 사례를 모두 수용할 수 있을 만큼 유연합니다
- PEP 508의 문법을 재사용합니다
논의된 모든 해법 가운데 세 가지 기준을 모두 충족하는 것은 이 해법뿐입니다.
명세
Default-Extra 메타데이터 필드
여러 번 사용할 수 있는 새 메타데이터 필드인 Default-Extra가 핵심 패키지 메타데이터에 추가됩니다. 이 필드의 각 항목은 엑스트라를 명시적으로 지정하지 않고 패키지를 설치할 때 자동으로 포함될 엑스트라를 지정하는 문자열이어야 합니다.
Default-Extra 항목에는 Provides-Extra 항목에 이미 지정된 것만 사용할 수 있습니다.
예시:
Default-Extra: recommended
Default-Extra: backend1
Default-Extra: backend2
Default-Extra: backend3
이 제안은 핵심 패키지 메타데이터에 새 필드를 도입하므로 Metadata-Version을 다음 마이너 버전(이 글을 쓰는 시점 기준 2.5)으로 올려야 합니다.
[project] 메타데이터 테이블의 새 키
원래 PEP 621에서 정의되었고 현재는 PyPA 명세에서 정의하는 프로젝트 메타데이터의 [project] 테이블에 새 키가 추가됩니다. 이 키의 이름은 default-optional-dependency-keys이며 설명은 다음과 같습니다:
- TOML 타입: 문자열 배열
- 대응하는 코어 메타데이터 필드:
Default-Extra
default-optional-dependency-keys의 각 문자열은 optional-dependencies에 정의된 엑스트라의 이름이어야 하며, 이 배열의 각 엑스트라는 핵심 패키지 메타데이터에서 그에 대응하는 Default-Extra 항목으로 변환됩니다. 앞 절에서 제시한 예시 Default-Extra 항목을 생성하는 올바른 사용 예는 다음과 같습니다:
[project]
default-optional-dependency-keys = [
"recommended",
]
그리고 다음과 같습니다:
[project]
default-optional-dependency-keys = [
"backend1",
"backend2",
"backend3"
]
기본 엑스트라 재정의하기
의존성 명세에 엑스트라가 명시적으로 주어지면 기본 엑스트라는 무시됩니다. 그렇지 않으면 기본 엑스트라가 설치됩니다.
예를 들어 어떤 패키지가 기본 엑스트라인 extra1과 기본이 아닌 엑스트라인 extra2를 정의한다고 할 때, 사용자가 다음과 같이 패키지를 설치하면:
$ pip install package
기본 extra1 의존성이 포함됩니다. 반면 사용자가 다음과 같이 패키지를 설치하면:
$ pip install package[extra2]
extra2 엑스트라는 설치되지만 기본 extra1 엑스트라는 무시됩니다.
설치 명령이나 의존성 트리에서 같은 패키지가 여러 번 지정된 경우, 그 패키지 중 하나라도 엑스트라 없이 지정되었다면 기본 엑스트라를 설치해야 합니다. 예를 들어, package가 의존성 트리에 여러 번 나타나는 spam 패키지를 설치하는 경우:
spam
├── tomato
│ ├── package[extra2]
└── egg
└── package
package가 엑스트라를 지정하지 않은 채로 적어도 한 번 나타나므로 기본 엑스트라를 설치해야 합니다.
package[]와 같은 빈 엑스트라 집합은 패키지를 기본 엑스트라 없이 설치해야 한다는 의미로 해석해야 합니다(단, package가 의존성 트리의 다른 곳에 나타나는 경우는 예외이며, 이때는 위에서 언급한 대로 기본 엑스트라가 설치됩니다). 이는 패키지를 최소 구성으로 설치하는 보편적인 방법을 제공합니다.
또한 pip 같은 일부 도구는 현재 인식되지 않는 엑스트라를 무시하고, 해당 엑스트라가 인식되지 않았음을 알리는 경고를 사용자에게 출력한다는 점도 짚어 둡니다. 예:
$ pip install package[non-existent-extra]
WARNING: package 3.0.0 does not provide the extra 'non-existent-extra'
...
이처럼 (오류를 발생시키는 대신) 동작하는 도구의 경우, 의존성 명세에서 어떤 엑스트라가 유효하지 않은 것으로 확인되면 그 엑스트라는 무시해야 하며, 지정된 엑스트라가 모두 유효하지 않다면 이를 (package가 아니라) package[]와 동등한 것으로 간주하여 기본 엑스트라를 설치하지 않아야 합니다.
마지막으로, (Relying on tooling to deselect any default extras에서도 논의했듯이) 패키지 설치 프로그램은 위 동작을 제어하는 자체 옵션을 구현할 수 있습니다. 예를 들어 패키지가 의존성 트리의 어디에 나타나는지와 관계없이 일부 또는 모든 패키지에 대해 기본 엑스트라를 비활성화하는 옵션을 구현할 수 있습니다. 이러한 도구별 옵션을 구현하는 경우, 도구 개발자는 이를 옵트인 방식으로 만들어야 하며, 사용자는 기본적으로 위에서 설명한 PEP 771 동작을 경험해야 합니다.
예시
이 절에서는 Motivation 절에서 설명한 사용 사례를 살펴보고, 위에서 설명한 명세를 사용하여 이제 이 사례들을 어떻게 해결할 수 있는지 알아봅니다.
권장 의존성과 최소 설치
먼저, 반드시 필요하지는 않지만 권장되는 의존성을 기본으로 설치하면서도 필수 의존성만 설치하는 방법을 함께 제공하려는 패키지의 경우를 살펴봅니다.
이를 위해 패키지 유지 관리자는 필수는 아니지만 권장되는 의존성을 담은 recommended라는 엑스트라를 정의하고, 이것이 기본 엑스트라로 포함되도록 선택할 것입니다:
[project]
default-optional-dependency-keys = [
"recommended"
]
[project.optional-dependencies]
recommended = [
"package1",
"package2"
]
이 패키지의 이름이 package라면, package를 설치하는 사용자는 package[recommended]와 동등한 결과를 얻게 됩니다. 사용자는 대신 package[]를 설치할 수도 있으며, 이 경우 기본 엑스트라 없이 패키지가 설치됩니다.
Motivation 절에 나온 구체적인 패키지 예시 중 하나를 들면, astropy 패키지는 recommended 엑스트라를 정의하고 있으며, 현재 기본 설치 안내에서는 사용자에게 이 엑스트라를 설치하도록 안내하고 있습니다. 이 PEP에 따르면 recommended 엑스트라를 기본 엑스트라로 선언할 수 있습니다:
[project]
default-optional-dependency-keys = [
"recommended"
]
[project.optional-dependencies]
recommended = [
"scipy",
"..."
]
즉, 다음과 같이 설치하면:
$ pip install astropy
scipy 같은 선택적이지만 권장되는 의존성이 함께 설치됩니다. 최소 설치를 원하는 고급 사용자는 다음을 사용할 수 있습니다:
$ pip install astropy[]
적어도 하나의 백엔드 또는 프런트엔드가 필요한 패키지
Motivation에서 설명했듯이, 일부 패키지는 여러 백엔드 및/또는 프런트엔드를 지원할 수 있으며, 경우에 따라서는 백엔드나 프런트엔드 패키지가 항상 적어도 하나 설치되어 있도록 보장하는 것이 바람직할 수 있습니다. 그렇지 않으면 패키지를 사용할 수 없기 때문입니다. 구체적인 예로는 사용하려면 GUI 라이브러리가 있어야 하지만 여러 GUI 라이브러리를 지원할 수 있는 GUI 애플리케이션이나, 여러 계산 백엔드를 사용할 수 있지만 그중 적어도 하나는 설치되어 있어야 하는 패키지를 들 수 있습니다.
이 경우 패키지 유지 관리자는 각 백엔드나 프런트엔드마다 엑스트라를 정의하고 기본값을 제공하는 방식을 선택할 수 있습니다. 예:
[project]
default-optional-dependency-keys = [
"backend1"
]
[project.optional-dependencies]
backend1 = [
"package1",
"package2"
]
backend2 = [
"package3"
]
패키지가 예를 들어 여러 백엔드를 동시에 지원할 수 있고 그중 일부 백엔드는 항상 설치되어야 한다면, 해당 백엔드의 의존성은 기본 엑스트라 메커니즘을 사용하는 대신 필수 의존성으로 지정해야 합니다.
Motivation에서 언급한 구체적인 예시 중 하나를 들면, napari 패키지는 PyQt5, PyQt6, PySide2, PySide6 중 하나를 사용할 수 있으며, 현재 사용자는 이 중 하나가 설치되도록 napari[all]을 명시적으로 지정하거나, 프런트엔드 패키지 중 하나를 명시적으로 지정하기 위해 예를 들어 napari[pyqt5]를 지정해야 합니다. 엑스트라 없이 napari를 설치하면 제대로 동작하지 않는 패키지가 됩니다. 이 PEP에 따르면 napari는 다음과 같은 설정을 정의할 수 있습니다:
[project]
default-optional-dependency-keys = [
"pyqt5"
]
[project.optional-dependencies]
pyqt5 = [
"PyQt5",
"..."
]
pyside2 = [
"PySide2",
"..."
]
pyqt6 = [
"PyQt6",
"..."
]
pyside6 = [
"PySide6",
"..."
]
즉, 다음과 같이 하면:
$ pip install napari
별도 설정 없이 바로 동작하지만, 사용자가 프런트엔드를 명시적으로 지정할 수 있는 메커니즘도 여전히 존재합니다. 예:
$ pip install napari[pyside6]
기본 엑스트라를 제거하지 않아야 하는 엑스트라 지원
여기서 추가로 살펴볼 경우는 패키지 유지 관리자가 기본 엑스트라를 제거하지 않으면서도 사용자가 기본이 아닌 엑스트라를 선택할 수 있게 하려는 경우입니다. 즉, 유지 관리자는 다음과 같은 동작을 원할 수 있습니다:
package[]는 엑스트라 없이 설치합니다package는 권장 의존성(recommended엑스트라에 정의됨)을 설치합니다package[alternative]는 기본 엑스트라를 설치하지 않고, 대신 다른 선택적 의존성 집합(alternative엑스트라에 정의됨)을 설치합니다package[additional]는 권장 의존성과 추가 의존성(additional엑스트라에 정의됨)을 모두 설치합니다
이는 예를 들어 다음과 같이 구현할 수 있습니다:
[project]
default-optional-dependency-keys = [
"recommended"
]
[project.optional-dependencies]
recommended = [
"package1",
"package2"
]
alternative = [
"package3"
]
additional = [
"package[recommended]",
"package4"
]
기존 Python 패키징 도구는 패키지가 엑스트라에서 자기 자신을 참조하는 기능을 지원합니다.
다시 구체적인 예를 들면, 이 PEP가 도입되면 astropy는 (Recommended dependencies and minimal installations에서 설명한 대로) recommended 엑스트라를 정의할 수 있습니다. 하지만 astropy는 다른 엑스트라도 정의합니다. 그중 하나인 jupyter 엑스트라는 Jupyter 기반 환경에서 사용자 경험을 개선하는 패키지를 추가합니다. 이 엑스트라를 선택한 사용자도 권장 의존성은 여전히 설치되기를 원할 수 있습니다. 이 경우에는 다음 구성으로 문제를 해결할 수 있습니다:
[project]
default-optional-dependency-keys = [
"recommended"
]
[project.optional-dependencies]
recommended = [
"scipy",
"..."
]
jupyter = [
"astropy[recommended]",
"ipywidgets",
"..."
]
다음과 같이 설치하는 사용자는:
$ pip install astropy[jupyter]
다음과 같이 설치한 것과 같은 결과를 얻게 됩니다:
$ pip install astropy[recommended, jupyter]
여러 종류의 기본값이 있는 패키지
경우에 따라서는 패키지에 여러 종류의 기본값이 필요할 수 있습니다. 예를 들어 Packages requiring at least one backend or frontend에서는 백엔드 또는 프런트엔드 중 하나만 있는 패키지를 살펴보았습니다. 하지만 경우에 따라서는 패키지가 백엔드와 프런트엔드를 모두 지원해야 하고, 하나 이상의 기본 프런트엔드와 하나 이상의 기본 백엔드를 지정하고 싶을 수 있습니다.
이상적으로는 다음과 같은 동작을 원할 수 있습니다:
$ pip install package # installs default backend and frontend
$ pip install package[] # installs no backends or frontends
$ pip install package[backend1] # installs backend1 and default frontend
$ pip install package[frontend2] # installs frontend2 and default backend
$ pip install package[backend1, frontend2] # installs backend1 and frontend2
하지만 이 PEP는 복잡성이 늘어나므로 예를 들어 backend1을 지정하면 기본 백엔드는 비활성화하고 기본 프런트엔드는 활성화하는 식의 메커니즘을 제공하지 않습니다.
대신 유지 관리자는 당분간 백엔드나 프런트엔드를 명시적으로 지정하는 경우 백엔드와 프런트엔드를 모두 지정해야 한다고 문서화해야 합니다. 그렇더라도 이렇게 하려는 사용자가 이 방법을 찾지 못하는 문제는 없을 것입니다. 사용자는 어떤 백엔드나 프런트엔드를 사용할 수 있는지 알아보기 위해 어차피 문서를 읽어야 하므로, 그때 백엔드와 프런트엔드용 엑스트라를 올바르게 사용하는 방법도 함께 안내받을 수 있기 때문입니다.
사용자 편의성을 높이는 한 가지 방법으로, 유지 관리자는 기본 백엔드와 기본 프런트엔드를 설치하는 defaultbackend, defaultfrontend 같은 이름의 엑스트라를 만들 수 있습니다. 그런 다음 사용자에게 다음과 같이 설치하도록 권장할 수 있습니다:
$ pip install package # installs default backend and frontend
$ pip install package[] # installs no backends or frontends
$ pip install package[backend1, defaultfrontend] # installs backend1 and default frontend
$ pip install package[defaultbackend, frontend2] # installs frontend2 and default backend
$ pip install package[backend1, frontend2] # installs backend1 and frontend2
이렇게 하면 (원하는 경우) 시간이 지나 기본값이 바뀌더라도 사용자는 그때그때 권장되는 백엔드를 설치할 수 있습니다.
앞으로 더 나은 해결책을 구현하려는 요구가 생긴다면, 이 PEP가 그것을 가로막아서는 안 된다고 생각합니다. 예를 들어 앞으로 엑스트라가 어떤 기본 엑스트라를 비활성화할지 지정하는 기능을 추가하고, 이를 지정하지 않으면 (현재 PEP와 마찬가지로) 명시적으로 지정한 엑스트라가 모든 기본 엑스트라를 비활성화하도록 하는 방안을 생각해 볼 수 있습니다.
하위 호환성
기본 엑스트라를 사용하지 않는 패키지
패키징 생태계의 도구에 이 PEP 지원이 추가되더라도, 기본 엑스트라를 사용하지 않는 패키지는 지금처럼 계속 동작하며 호환성이 깨지지 않을 것입니다.
기본 엑스트라를 사용하는 패키지
패키지가 기본 엑스트라를 정의하기 시작하면 그 기본값은 이 PEP를 구현한 최신 버전의 패키징 도구에서만 적용됩니다. 하지만 이런 패키지도 이전 패키징 도구로 계속 설치할 수 있으며, 가장 큰 차이는 이전 패키징 도구를 사용할 때 기본 엑스트라가 자동으로 설치되지 않는다는 점입니다.
이 기능을 가르치는 방법에서 설명했듯이, 패키지 작성자는 사용자층에 따라 기본 엑스트라 기능을 언제, 어떻게 도입할지 신중하게 평가해야 합니다. 사용자 중 상당수가 아직 기본 엑스트라를 지원하지 않는 이전 패키지 설치 프로그램을 사용하고 있다면, 일부 조치(예: 필수 의존성을 기본 엑스트라로 옮기는 것)는 사용자 환경을 망가뜨릴 가능성이 높기 때문입니다. 이런 의미에서 패키지 작성자는 이 기능을 특정 방식으로 사용하면 사용자에게 하위 호환성 문제를 일으킬 수 있다는 점을 인지해야 합니다. 따라서 사용자에게 미치는 영향을 최소화할 책임은 패키지 작성자에게 있습니다.
패키징 관련 도구
하위 호환성 측면에서 가장 중요한 부분은 패키징 도구가 엑스트라에 대해 갖는 가정과 관련이 있습니다. 구체적으로, 이 PEP는 이 가정을 바꿉니다. 엑스트라는 더 이상 의존성 트리에 의존성을 추가하기만 하는 것이 아니며, 일부 엑스트라를 지정하면 오히려 더 적은 의존성이 설치될 수 있습니다.
동작 변화의 구체적인 예는 pip에서 볼 수 있습니다. numpy를 필수 의존성으로 가지며, scipy를 포함하는 recommended라는 기본 엑스트라를 가진 package라는 패키지를 생각해 보십시오. 사용자가 package[]를 설치하면 package와 numpy만 설치됩니다. 그런 다음 사용자가 다음을 실행하면:
$ pip freeze > requirements.txt
requirements.txt에는 예를 들어 다음과 같은 내용이 담깁니다.:
package==1.0.2
numpy==2.1.0
그러나 사용자가 이어서 다음 명령으로 이 파일의 요구 사항을 설치하면:
$ pip install -r requirements.txt
pip는 numpy와 함께 package(기본 엑스트라 포함)를 설치하므로, 최종 환경에는 scipy가 포함됩니다. 이 경우에는 사용자가 pip install에 --no-deps를 전달하여 의존성 트리를 해결하지 않도록 하면 문제를 해결할 수 있습니다. 하지만 여기서 요점은 엑스트라가 미칠 수 있는 영향에 대한 가정이 바뀌면서 패키징 도구의 동작이 달라질 수 있다는 것입니다.
최근 승인된 PEP 751은 앞으로 pip freeze 출력이나 기타 도구 같은 대안을 대체하기 위한 새로운 파일 형식을 정의한다는 점에 주목할 만합니다. 이 새로운 파일 형식은 파일에 있는 패키지가 의존성 해결 없이 설치되도록 설계되었습니다. 따라서 이 PEP에서 명시한 기본 엑스트라와 완전히 호환되며, 앞서 언급한 pip freeze/pip install -r 문제도 피할 수 있습니다.
보안 영향
이 PEP에 대해 알려진 보안 영향은 없습니다.
교육 방법
이 절에서는 이 PEP의 구현과 관련하여 커뮤니티 내 여러 집단의 사람들에게 제공되어야 할 정보를 개괄합니다. 아래에서 설명하는 일부 측면은 PEP가 패키징 도구에 완전히 구현되기 전부터 해당됩니다. 이후에 있을 수 있는 전환을 수월하게 하기 위해 구현에 앞서 미리 해 둘 수 있는 준비가 있기 때문입니다. 아래에서 다루는 집단은 다음과 같습니다.
패키지 최종 사용자
패키지 사용자에게는 패키지에서 어떤 엑스트라를 사용할 수 있고 각 엑스트라가 어떻게 동작하는지 보여 주는 명확한 설치 안내를 제공해야 합니다. 예를 들어 일부 권장 의존성이나 특정 프런트엔드 또는 백엔드가 기본적으로 설치된다는 점을 설명해야 합니다. 또한 제공되는 방식에 따라 이를 선택 해제하거나 기본값을 재정의하는 방법도 설명해야 합니다.
패키지 작성자
엑스트라를 정의하는 메커니즘과 이를 언제 사용할지에 관한 규칙은 명확합니다. 하지만 패키지 작성자는 의도치 않게 하위 호환성을 깨뜨리지 않도록 이 기능을 패키지에 도입하기 전에 여러 가지 사항을 신중하게 고려해야 합니다.
이전 버전의 패키지 설치 프로그램 지원하기
pip나 uv 같은 패키지 설치 프로그램이 반드시 동시에 기본 엑스트라 지원을 구현하지는 않을 것이며, 구현한 뒤에도 패키지 작성자는 최신 버전의 패키지 설치 프로그램을 사용하지 않는 사용자를 계속 지원하고 싶어 할 가능성이 높습니다. 이 경우 다음 권장 사항이 적용됩니다.
- 패키지를 필수 의존성에서 기본 엑스트라로 옮기는 것은 호환성을 깨뜨리는 변경입니다. 이전 버전의 패키지 설치 프로그램은 기본 엑스트라라는 개념을 인식하지 못하므로 더 적은 의존성으로 패키지를 설치하게 되고, 이는 그 의존성에 기대고 있던 사용자에게 영향을 줄 수 있기 때문입니다. 따라서 이미 자리 잡은 패키지에서 의존성을 필수에서 기본 엑스트라로 바꾸는 것은, 향후 개발자가 이 PEP를 구현한 설치 프로그램을 사용하는 사용자만 지원하고자 할 때에만 해야 합니다.
- astropy의
recommended를 기본 엑스트라로 만드는 것처럼 기존 엑스트라를 기본으로 만드는 것은 더 안전할 것입니다. 하지만 이전 버전의 패키지 설치 프로그램을 사용하는 사용자를 지원하려면, (대부분 또는 모든 사용자가 이 PEP를 구현한 패키지 설치 프로그램을 사용한다는 것이 분명해질 때까지) 가능한 한 오랫동안 문서에서 해당 엑스트라를 계속 명시적으로 언급해야 합니다. extra를 계속 명시적으로 언급해도 단점은 없으며, 기본 extra로 만들면 문서를 읽지 않는 최신 도구 사용자(사용자 커뮤니티에서 무시할 수 없는 비율일 수 있습니다)도 권장 의존성을 기본으로 받게 됩니다. - 이 PEP 이전에는
package[]가package와 동등했으므로, 작성자는package[]를 최소 설치를 위한, 하위 호환성을 갖춘 범용 방법으로 문서화할 수 있습니다. 기본 엑스트라를 정의한 패키지의 경우,package[]를 설치하면 pip 같은 이전 버전의 패키징 도구에서도 항상 최소 설치가 이루어지며, 특정 패키지에 기본 엑스트라가 도입되기 전에 나온 해당 패키지의 릴리스도package[]로 설치할 수 있습니다(다만 이 경우에는package와 동등합니다). 기본 엑스트라를 정의하지 않은 패키지의 경우,package[]는 계속package와 동등합니다.
기본 의존성을 많이 추가하지 않기
작성자는 사용자가 기본 의존성을 제외할 수 있는 방법을 제공할 수 있으므로, 많은 의존성을 기본으로 포함하고 싶어질 수 있습니다. 그러나 설치를 불필요하게 비대하게 만들고 의존성 트리를 복잡하게 만들지 않도록, 작성자는 기본으로 포함할 항목을 신중하게 검토할 것을 권장합니다. 기본 엑스트라를 사용한다고 해서 모든 엑스트라가 기본이어야 한다는 뜻은 아니며, 사용자가 기본이 아닌 엑스트라를 명시적으로 선택할 여지는 여전히 있습니다.
기본 엑스트라는 일반적으로 필수 의존성과 같은 “무게”로 다루어야 합니다. 패키지가 널리 사용되는 경우, 기본 엑스트라를 도입하면 그 엑스트라의 의존성이 전이적으로 포함됩니다. 단, 모든 다운스트림 패키지가 최소 설치 명세를 사용해 명시적으로 이를 제외하도록 갱신된 경우는 예외입니다.
예를 들어, pytest 패키지에는 현재 이 패키지에 의존하는 플러그인이 1,500개 가까이 있습니다. pytest가 기본 엑스트라를 추가했는데 그 플러그인들이 그에 맞게 갱신되지 않는다면, 플러그인을 설치할 때 기본 엑스트라의 의존성도 함께 포함됩니다. 그렇다고 기본 엑스트라를 사용하지 말라는 것은 아니지만, 기본 엑스트라를 추가할 때에는 다운스트림에 미치는 영향을 신중하게 평가해야 합니다.
기본 엑스트라 상속하기
패키지 작성자가 어떤 extra를 기본으로 설치되게 하기로 했다면, Supporting extras that should not remove default extras에서 설명하는 방식을 사용하지 않는 한, 사용자가 다른 extra를 명시적으로 지정할 경우 기본 extra가 설치되지 않을 수 있다는 점을 알아 두는 것이 중요합니다.
서로 교체 가능한 백엔드처럼, extra가 명시적으로 지정되면 기본값을 무시하는 것이 옳은 경우도 있습니다. 하지만 최소 설치 방법을 제공하면서도 기본 엑스트라로 권장 의존성을 포함하는 경우처럼 다른 경우에는, 다른 많은 엑스트라가 기본 엑스트라를 명시적으로 반드시 ‘상속’해야 할 수도 있으므로, 패키지 작성자는 어떤 경우에 기본 엑스트라가 설치되기를 원하는지 신중하게 고려해야 합니다.
호환되지 않는 extra
경우에 따라 패키지에 서로 호환되지 않는 extra가 있을 수 있습니다. 이 경우, 다른 의존성과 호환되지 않을 수 있는 의존성을 담은 엑스트라에는 기본 엑스트라 기능을 사용하지 않기를 권장합니다.
package[A]와 package[B]라는 extra를 가진 패키지를 생각해 봅시다. 지금도 사용자가 package[A]와 package[B], 또는 package[A,B]를 설치하려고 하면 설치가 깨질 수 있습니다. 하지만 적어도 두 extra를 모두 설치한다는 것은 명시적으로 드러납니다. 하지만 A를 기본 엑스트라로 만들면 직관적이지 않은 문제가 생길 수 있습니다. 사용자가 다음과 같이 실행할 수 있습니다:
$ pip install package # this installs package[A]
$ pip install package[B]
그러면 A와 B를 둘 다 명시적으로 설치한 적이 없는데도 설치가 깨질 수 있습니다. 이러한 이유로, 이런 문제가 생길 가능성이 있는 의존성에는 기본 엑스트라를 사용하지 않기를 권장합니다.
순환 의존성
순환 의존성이 있을 때는 작성자가 특별히 주의해야 합니다. 예를 들어, 다음과 같은 의존성 트리를 생각해 봅시다:
package1
└── package2
└── package1
package1에 recommended라는 이름의 기본 엑스트라가 있다면:
$ pip install package1[]
package2가 (extra를 지정하지 않은 채) package1에 계속 의존한다면 여전히 recommended extra가 설치됩니다. 이 문제는 의존성 트리를 다음과 같이 바꾸어 해결할 수 있습니다.:
package1
└── package2
└── package1[]
단, 이는 package2가 실제로 package1의 extra 의존성이 제공하는 기능에 전혀 의존하지 않는다고 가정한 것입니다. 따라서 작성자는 package2의 작성자와 협의하면서 마이그레이션 계획을 신중하게 검토해야 합니다.
기본 엑스트라가 있는 패키지 문서화하기
기본 엑스트라를 어떻게 사용하든, 패키지 작성자는 패키지 문서에서 엑스트라를 어떻게 사용해야 하는지 분명히 밝히도록 노력해야 합니다. ‘모범 사례’ 문서에서는 다음을 언급해야 합니다:
package를 설치하는 것은package[<default extras>]를 설치하는 것과 같다는 점package[]를 설치하면 최소/필수 의존성만 포함되지만, 의존성 트리의 다른 곳에package가 나타나면 선택적 의존성이 설치되지 않는다고 보장할 수 없다는 점- 그 밖에 어떤 선택적 엑스트라를 사용할 수 있는지, 그리고 그 엑스트라가 기본 엑스트라를 비활성화하는지 여부(Supporting extras that should not remove default extras에서 설명한 대로 제어할 수 있으므로)
- 예를 들어 기본 백엔드와 프런트엔드를 함께 가질 수 있는 패키지에 특화된 안내(Packages with multiple kinds of defaults에 설명된 것과 같은 경우)
패키징 저장소 유지 관리자
conda, Homebrew, Linux 패키지 설치 프로그램(apt와 yum 등) 같은 여러 배포판용으로 Python 라이브러리를 다시 패키징하는 사람들에게 미치는 영향도 고려해야 합니다. 모든 패키지 배포판에 여기서 설명한 방식과 맞아떨어지는 메커니즘이 있는 것은 아닙니다. 실제로 conda 같은 일부 배포판에는 extra라는 개념조차 없습니다.
여기서 고려해야 할 경우는 두 가지입니다:
- 여러 conda-forge 레시피처럼 다시 패키징을 수작업으로 하는 경우, 특히 엑스트라에 해당하는 개념이 없는 경우에는, 어떤 의존성을 포함할지 이미 수동으로 결정해야 하므로 기본 엑스트라 도입이 큰 영향을 주지 않을 것입니다(예를 들어 Motivation에서 언급한 astropy 패키지의 conda-forge 레시피는 사용자가 달리 명시적으로 요청할 방법이 없으므로
recommended의존성을 모두 기본으로 포함합니다). - 다시 패키징을 자동화된 방식으로 하는 경우, 배포판 유지 관리자는 기본 엑스트라를 어떻게 다룰지 신중하게 고려해야 하며, 이는 무시할 수 없는 양의 작업과 논의를 수반할 수 있습니다.
이와 같은 PEP가 서로 다른 패키지 배포판을 하나하나 빠짐없이 검토하는 것은 불가능합니다. 하지만 궁극적으로 기본 엑스트라는 패키지 작성자가 대다수 사용자에게 자신의 패키지가 어떻게 설치되기를 바라는지를 나타내는 것으로 이해해야 하며, 수동이든 자동이든 기본 엑스트라를 어떻게 처리할지 결정할 때 이를 근거로 삼아야 합니다.
참조 구현
다음 저장소에는 기본 엑스트라를 사용하는, 완전히 동작하는 데모 패키지가 있습니다:
https://github.com/wheel-next/pep_771
이 데모는 여러 패키지의 수정된 브랜치를 사용하며, 해당 브랜치의 링크는 다음과 같습니다:
또한 이 브랜치에는 Flit 패키지의 수정된 버전이 있습니다.
위의 구현은 현재 개념 증명 단계이며, 기존 변경 사항은 아직 관련 유지 관리자의 검토를 받지 않았습니다. 그럼에도 불구하고 관심 있는 유지 관리자가 직접 시험해 볼 수 있을 만큼은 충분히 동작합니다.
기각된 아이디어
권장 설치를 위해 메타 패키지 사용하기
기존 패키징 도구와 인프라를 사용하더라도, 일부 사용자에게는 최소 설치를 제공하고 일반 사용자에게는 최소가 아닌 기본 설치(예: 권장 의존성이나 기본 백엔드 포함)를 제공하려는 패키지 유지 관리자는 패키지 하나 대신 두 개를 배포할 의향이 있다면 기술적으로 이미 이를 달성할 수 있습니다. 예를 들어 최소 의존성을 가진 주 패키지인 package-core와, 선택적 의존성이 활성화된 상태로 package-core에 의존하는 메타패키지인 package를 배포하는 방식입니다.
Motivation 섹션의 구체적인 예를 다시 한번 들면, astropy 패키지는 recommended extra를 정의하고 있으며, 현재 기본 설치 안내는 사용자에게 이 extra를 설치하도록 안내합니다. 원칙적으로는 기존 astropy 패키지의 이름을 예컨대 astropy-core로 바꾼 다음, 다음과 같은 의존성 섹션을 포함하는 메타패키지로서 새 astropy 패키지를 만들 수 있습니다:
dependencies = [
"astropy-core[recommended]"
]
사용자가 astropy 메타패키지의 버전을 고정하거나 버전 제약을 걸고 싶어 할 수 있으므로(예: astropy>5.0), 메타패키지는 코어 패키지와 같은 버전을 따라야 하며, 의존성 섹션에서 엄격한 버전 고정을 사용해야 합니다. 예:
version = "7.1.0"
dependencies = [
"astropy-core[recommended]==7.1.0"
]
이 아이디어는 기술적으로 이미 실현 가능하다는 점에서 매력적으로 보일 수 있습니다. 하지만 실제로는 여러 가지 이유로 많은 프로젝트가 이 방식을 택하지 않았으며, 이제 그 이유를 살펴보겠습니다. 이 중 일부는 앞으로 새로 만들어질 프로젝트에는 해당하지 않을 수 있지만, 일부는 기존 프로젝트와 새 프로젝트를 가리지 않고 모든 프로젝트에 해당합니다.
패키지 이름과 모듈 이름의 불일치
이름 측면에서, 메타패키지 방식을 사용하려는 패키지에는 크게 두 가지 선택지가 있습니다:
- 첫 번째 선택지는 기존 패키지를 그대로 유지하는 것으로, 이 경우
package는 최소 설치를 제공하게 되며, 그다음에package-all같은 다른 이름으로 새 메타패키지를 만듭니다. 하지만 이 방식은 애초에 이 PEP를 작성하게 된 문제 중 하나를 그대로 안고 있습니다. 사용자는 예컨대package[recommended]와 같이 설치할 수 있다는 사실을 모르는 경우가 많으며, 마찬가지로package-all이 존재한다는 사실도 모를 수 있습니다. 이 방식은 부담의 일부를 더 숙련된 사용자에게 옮기는 대신, 이를 알아내야 하는 부담을 다시 한번 일반 사용자에게 지웁니다. - 두 번째 선택지는 기존 패키지의 이름을 예컨대
package-core로 바꾸고, 새 메타패키지의 이름을package로 정하는 것입니다. 이는 첫 번째 선택지보다는 낫지만 이상적이지는 않습니다.package-core가package모듈을 제공하고package는 아무 모듈도 제공하지 않게 되어, 패키지 이름과 모듈 이름 사이에 직관적이지 않은 불일치가 생기기 때문입니다. 이것이 혼란을 일으키는 예를 들자면, 일반 사용자는package모듈을 제거하려면 예컨대 다음과 같이 하면 된다고 생각할 수 있습니다:$ pip uninstall package
하지만 실제로는 그렇지 않으며(
package모듈은 여전히 동작합니다), 이 사용자는package-core패키지가 존재한다는 사실조차 쉽게 알아차리지 못할 수 있습니다.
여러 저장소 또는 모노레포
이 방식을 사용하려면 저장소를 하나가 아닌 두 개로 유지하거나, 두 패키지를 모두 담는 모노레포로 전환해야 합니다. 어느 선택지도 이상적이지 않습니다:
- 두 개의 저장소로 분리하면 유지 관리자에게 장기적으로 추가 부담이 생깁니다. 유지 관리자는 두 저장소가 동기화된 상태를 유지하도록 해야 하는데, 이는 버전뿐만 아니라 엑스트라와 같은 다른 측면에서도 마찬가지입니다(Synchronizing metadata에서 논의합니다). 또한 Mismatch between package and module name에서 언급한 이름 문제가 여기서는 더 복잡해집니다. 저장소 이름을 패키지 이름과 일치시키는 경우, 기존
package저장소를 체크아웃해 둔 사용자는 모두 원격 URL이나 git clone URL을package-core저장소를 가리키도록 수정해야 합니다. 다른 방법은package저장소를 그대로 두고 여기에package-core패키지를 담은 뒤 메타패키지에 다른 이름을 붙이는 것이지만, 이는 혼란을 일으킬 수 있습니다. - 모노레포로 전환하는 것은 일부 프로젝트에게 상당한 변화일 수 있으며, 도구가 기본적으로 하나의 저장소가 하나의 패키지에 대응한다고 가정하는 경우도 드물지 않습니다. 이러한 도구는 대개 모노레포에서 동작하도록 설정할 수 있지만, 이는 유지 관리자에게 추가 부담이 됩니다. 또한 메인 패키지를 모노레포의 하위 디렉터리로 옮기면, 예컨대 저장소 URL로 패키지를 pip 설치하던 사용자는 모두 하위 디렉터리에서 설치하도록 이를 수정해야 하며(저장소 URL에
subdirectory=를 추가), 저장소를 클론하고 이전 구조를 가정하는 기존 워크플로는 모두 깨지게 됩니다.
최소 패키지에 대한 의존
분리가 이루어진 첫 버전보다 오래된 패키지 버전에 의존해야 하는 패키지는 최소 패키지에 쉽게 의존할 수 없습니다. 이 PEP의 주 제안을 따르면 다운스트림 사용자는 version이 기본 엑스트라 도입 이전인 경우에도 예를 들어 package[]>version에 의존할 수 있지만, 분리 방식에서는 package-core가 이전에 존재하지 않았으므로 다운스트림 사용자가 예를 들어 package-core>version에 의존할 수 없습니다.
이에 대한 가능한 해결책은 개발자가 패키지의 모든 이전 버전에 대해 아무 동작도 하지 않는 메타데이터 패키지를 릴리스하는 것이지만, 이는 유지 관리자에게 상당한 추가 부담이 됩니다.
제거
Mismatch between package and module name에서 이름 문제를 이야기하며 암시했듯이, 패키지 제거가 더 이상 사용자가 기대하는 방식으로 동작하지 않게 됩니다. 다음과 같이 실행하는 사용자는:
$ pip uninstall package
여전히 package-core가 남아 있게 되지만, 이를 알아차리지 못할 수 있습니다. 이는 단지 혼란스러운 데 그치지 않고, 사실상 기존의 여러 워크플로에 영향을 줄 수 있는 호환성을 깨뜨리는 변경입니다.
패키지 배포
패키지가 하나가 아니라 둘이 되면 하나 대신 두 패키지를 릴리스해야 하므로 그것만으로도 패키지 배포의 장기적인 유지 관리 비용이 늘어나며, 경우에 따라서는 릴리스할 때마다 수작업이 추가로 생깁니다.
메타데이터 동기화
메인 패키지와 메타패키지 사이에서 동기화 상태를 유지하는 것이 중요한 주요 메타데이터는 버전입니다. 코어 패키지의 새 버전을 릴리스할 때마다 메타패키지의 버전을 올려야 하고, 의존성에 고정된 코어 패키지 버전도 함께 갱신해야 합니다.
또한 코어 패키지에 정의된 모든 엑스트라를 메타패키지에 다시 정의하고 동기화 상태로 유지해야 합니다. 예를 들어 package가 additional 엑스트라를 정의한다면 사용자는 여전히 package[additional]을 설치할 수 있어야 하지만, package-core 패키지를 설치하는 사용자도 package-core[additional]을 설치할 수 있어야 합니다.
동기화 상태로 유지해야 하는 다른 메타데이터로는 저자 정보와 프로젝트 URL 등이 있습니다.
요약
전반적으로 이 해결책은 유지 관리 부담을 크게 늘립니다. 초기 설정과 전환(규모가 크고 자리 잡은 프로젝트에는 이것만으로도 감당하기 어려울 수 있습니다) 측면뿐 아니라 장기적인 유지 관리 측면에서도 마찬가지입니다. 또한 사용자 워크플로가 깨질 가능성도 있습니다(특히 저장소 문제나 제거 등에서 그렇습니다). 이러한 모든 이유로, 우리는 이 방식이 이 PEP를 대체할 만한 설득력 있는 대안이라고 보지 않습니다.
엑스트라 선택 해제 문법
경쟁 관계에 있던 주요 접근 방식 중 하나는 다음과 같았습니다. 엑스트라를 하나라도 명시적으로 지정하면 기본값의 선택이 해제되는 방식이 아니라, 기본 엑스트라를 명시적으로 선택 해제해야 하는 방식입니다.
이 구상에서는 PEP 508에 정의된 미니 언어를 확장하여 엑스트라의 선택을 해제하는 새 문법을 도입하게 됩니다. 패키지가 기본 엑스트라를 정의한 경우, 사용자는 엑스트라 이름 앞에 마이너스 기호(-)를 붙여 이러한 기본값을 사용하지 않도록 선택할 수 있습니다. 제안된 문법 변경은 다음과 같았을 것입니다:
extras_list = (-)?identifier (wsp* ',' wsp* (-)?identifier)*
이 새 문법의 올바른 예로는 다음과 같은 것들이 있었을 것입니다.
package[-recommended]package[-backend1, backend2]package[pdf, -svg]
하지만 이 접근 방식에는 두 가지 주요 문제가 있습니다.
- 같은 의존성 명세에 엑스트라와 그 부정 형태가 함께 들어 있는 경우(예:
package[pdf, -pdf])나 의존성 트리에package[pdf]와package[-pdf]가 모두 들어 있는 경우와 같은 경계 사례를 어떻게 해석할지에 대한 여러 규칙을 정의해야 하며, 이러한 규칙은 사용자에게 직관적이지 않을 것입니다. - 더 심각한 문제는 의존성 명세에 새 문법을 도입하게 된다는 점입니다. 즉 어떤 패키지가 새 문법으로 의존성을 정의하면, 그 패키지와 그 패키지에 의존하는 다른 모든 패키지를 기존 패키징 도구로 더는 설치할 수 없게 되므로, 하위 호환성이 크게 깨집니다.
이러한 이유로 이 대안은 최종 제안에 포함되지 않았습니다.
extras_require에 특별한 항목 추가하기
새 Default-Extra 메타데이터 필드를 도입하는 것의 대안으로 검토된 해결책 중 하나는 ‘특별한’ 이름을 가진 엑스트라를 활용하는 것입니다.
한 가지 예는 빈 문자열을 사용하는 것입니다:
Provides-Extra:
Requires-Dist: numpy ; extra == ''
‘빈’ 엑스트라의 일부로 설치되는 의존성은 다른 엑스트라가 지정되지 않은 경우에만 설치된다는 아이디어입니다. 이 방식의 구현이 https://github.com/pypa/setuptools/pull/1503 에서 제안되었지만, 기존 사용 방식과의 호환성을 깨지 않고는 이를 동작하게 할 방법이 없다는 사실이 밝혀졌습니다. 예를 들어 setup.py 파일을 통해 Setuptools를 사용하는 패키지는 다음과 같이 할 수 있습니다:
setup(
...
extras_require={'': ['package_a']},
)
이는 올바른 코드이며 package_a를 install_requires에 정의한 것과 같으므로, 빈 문자열의 의미를 바꾸면 호환성이 깨집니다.
또한 하위 호환성을 유지하는 유효한 extras 이름이 될 수 있는 모든 문자열은 기존 패키지에서 이미 사용되고 있을 수 있으므로, 다른 어떤 문자열(예: 'default')도 특수 문자열로 사용할 수 없습니다.
특수한 Python 변수인 None을 사용하자는 제안도 있었지만, 이 역시 불가능합니다. setup.py 파일에서는 None을 사용할 수 있더라도 setup.cfg나 pyproject.toml 같은 선언적 파일에서는 사용할 수 없으며, 게다가 결국 extras 이름은 패키지 메타데이터에서 문자열로 변환되어야 하기 때문입니다. 다음과 같이 지정하면:
Provides-Extra: None
Python 패키지에서 이미 extra 이름으로 사용되고 있을 수 있는 문자열 ‘None’과 구별할 수 없습니다. 문자열이 아닌 ‘특수’ extras 이름을 허용하도록 코어 메타데이터 문법을 수정한다면, 결국 다시 코어 메타데이터 명세를 수정하는 셈이 되며, 이는 Default-Extra를 도입하는 것보다 나을 것이 없습니다.
도구에 의존하여 기본 엑스트라 선택 해제하기
extras 선택을 해제하는 또 다른 방법은 이를 패키징 도구 수준에서 구현하는 것입니다. 예를 들어, pip에 다음과 같은 옵션을 추가할 수 있습니다:
$ pip install package --no-default-extras
이 옵션은 --no-binary 옵션과 유사하게 모든 패키지 또는 특정 패키지에 적용할 수 있습니다. 예:
$ pip install package --no-default-extras :all:
이 접근 방식의 장점은 기본 엑스트라를 지원하는 도구가 그 선택 해제도 지원할 수 있다는 것입니다. 이 방식은 apt 도구의 --no-install-recommends 옵션과 유사합니다.
그러나 이 해결책은 그 자체만으로는 이상적이지 않습니다. 패키지가 의존성의 기본 엑스트라 중 일부가 필요하지 않다는 것을 스스로 지정할 수 없기 때문입니다. 또한 큰 의존성 트리에서 모든 기본 엑스트라를 비활성화하는 사용자에게 위험을 초래할 수 있으며, 트리의 어느 지점에서든 기본 엑스트라에 의존하는 패키지가 망가질 가능성이 있습니다.
그럼에도 불구하고 이 PEP는 이 접근 방식을 금지하지 않으며, 이러한 옵션을 지원할지 여부는 각 패키징 도구의 유지 관리자가 결정할 일입니다. 이 플래그는 적어도 의존성 트리에서 기본 엑스트라에 의존하는 곳을 찾아내려는 패키지 유지 관리자에게는 유용할 수 있습니다. 다만 이 옵션을 지원한다면, 이 플래그를 사용한다고 해서 정상적으로 동작하는 환경이 보장되지는 않는다는 점을 분명히 밝혀야 합니다.
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.