[Accepted] PEP 714 - Rename dist-info-metadata in the Simple API
원문 링크: PEP 714 - Rename dist-info-metadata in the Simple API
상태: Accepted 유형: Standards Track 작성일: 06-Jun-2023
PEP 714 – Simple API에서 dist-info-metadata
이름 변경
- 작성자: Donald Stufft
- PEP 담당자: Paul Moore
- 상태: Accepted (수락됨)
- 유형: Standards Track
- 주제: Packaging
- 생성일: 2023년 6월 6일
- 해결일: 2023년 6월 27일
초록 (Abstract)
이 PEP는 Simple API의 HTML 및 JSON 형식 모두에서 PEP 658이 제공하는 메타데이터의 이름을 변경하고, 이름 변경을 처리하는 방법에 대한 지침을 클라이언트와 서버 양쪽에 제공합니다.
동기 (Motivation)
PEP 658은 Simple API를 통해 아티팩트(artifact)에서 코어 메타데이터(core metadata) 파일을 호스팅하는 메커니즘을 지정했습니다. 이를 통해 클라이언트는 전체 아티팩트를 다운로드하지 않고도 메타데이터를 가져와 사용할 수 있게 되었습니다. 이후 PEP 691이 작성되어 Simple API에서 HTML 대신 JSON을 사용할 수 있는 기능이 추가되었고, 여기에는 PEP 658 메타데이터 지원도 포함되었습니다.
안타깝게도 PyPI는 최근까지 PEP 658을 지원하지 않았는데, 지원이 시작될 때 JSON 표현에서 PEP 658의 dist-info-metadata
키가 data-dist-info-metadata
로 잘못 명명되는 버그와 함께 릴리스되었습니다. 그러나 이 버그를 수정하려고 시도했을 때, pip에도 버그가 있어 JSON 표현에서 dist-info-metadata
를 사용하면 pip이 예외(exception)와 함께 하드 실패(hard fail)하는 것이 발견되었습니다.
pip의 이 버그는 적어도 v22.3부터 존재했으며, 약 8개월 동안 릴리스되어 Python 릴리스, 다운스트림 Linux 릴리스, 컨테이너, 가상 환경 등에 포함될 만큼 충분히 오래되었습니다.
이로 인해 PyPI의 버그는 pip의 버그로 인해 pip을 깨뜨리지 않고는 수정할 수 없는 상황에 놓이게 되었으며, 해당 버전의 pip은 이미 광범위하게 배포되었습니다. 더 나쁜 점은, 이런 식으로 고장 난 버전의 pip은 PyPI가 버그를 수정하면 새로운, 수정된 버전의 pip을 설치하는 것을 포함하여 PyPI에서 아무것도 설치할 수 없다는 것입니다.
근거 (Rationale)
이러한 버그를 수정하기 위한 3가지 주요 옵션이 있었습니다.
- 사양(spec)을 변경하지 않고, pip의 버그를 수정하고, 일정 시간 기다린 다음 PyPI의 버그를 수정합니다. 이 경우, 수정되지 않은 pip을 사용하는 모든 사용자는 PyPI에서 새로운 pip조차 설치할 수 없게 됩니다.
- (1)과 동일하게 진행하되, PyPI를 특별히 처리하여 PEP 658 메타데이터가 사용 가능하더라도 pip에는 내보내지 않도록 합니다. 이는 고장 난 버전의 사용자가 pip을 업그레이드할 수는 있지만, 다른 것은 아무것도 할 수 없게 만듭니다.
- pip이 현재 처리할 수 없는 키를 피하기 위해 사양을 변경합니다. 이를 통해 PyPI는 해당 키를 내보낼 수 있고, 새로운 버전의 pip은 해당 키를 활용하기 위해 릴리스될 수 있습니다.
이 PEP는 세 번째 옵션을 선택했지만, 한 걸음 더 나아가 HTML 표현에서도 키의 이름을 변경합니다.
일반적으로 사양 자체에 문제가 있지 않는 한, 특정 구현에만 영향을 미치는 버그 때문에 사양을 변경하지 않습니다. 이 경우 사양은 문제가 없었고, pip과 PyPI의 실제 버그였습니다.
그러나 이 변경을 선택한 4가지 이유는 다음과 같습니다.
- pip과 PyPI에 함께 영향을 미치는 버그는 다른 클라이언트 또는 저장소(repository) 조합에 비해 엄청난 영향을 미칩니다.
- 고장 났을 때의 영향은 어떤 식으로든 점진적으로 저하되는 것이 아니라, 설치 자체가 전혀 작동하지 않는다는 것입니다.
- 이러한 버그로 인해 차단된 기능은 pip을 사용하여 PyPI에서 의존성을 빠르고 효율적으로 해결하는 데 매우 중요합니다. 고장 난 버전의 pip이 사용되지 않을 때까지 오랜 기간 지연해야 한다면 전체 생태계에 해가 될 것입니다.
- 사양 변경의 단점은 매우 제한적입니다. 이러한 지원이 광범위하게 이루어지고 있다고 생각하지 않으므로, 제한된 수의 프로젝트에만 영향을 미칩니다.
사양 (Specification)
이 문서의 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL” 키워드는 RFC 2119에 설명된 대로 해석됩니다.
서버 (Servers)
- Simple API의 HTML 표현에서 사용될 때, PEP 658 메타데이터는
data-core-metadata
속성 이름을 사용하여 내보내져야 합니다 (MUST). 지원되는 값은 동일하게 유지됩니다. - Simple API의 PEP 691 JSON 표현에서 사용될 때, PEP 658 메타데이터는
core-metadata
키를 사용하여 내보내져야 합니다 (MUST). 지원되는 값은 동일하게 유지됩니다. - 이전 키 이름을 사용했던 클라이언트를 지원하기 위해, HTML 표현은
data-dist-info-metadata
를 사용하여 내보내질 수도 있습니다 (MAY). 만약 그렇게 한다면data-core-metadata
의 값과 일치해야 합니다 (MUST).
클라이언트 (Clients)
- Simple API의 HTML 표현을 사용하는 클라이언트는
data-core-metadata
키가 존재하는 경우 해당 키에서 PEP 658 메타데이터를 읽어야 합니다 (MUST).data-core-metadata
가 없고legacy data-dist-info-metadata
가 존재하는 경우 선택적으로 사용할 수 있습니다 (MAY). - Simple API의 JSON 표현을 사용하는 클라이언트는
core-metadata
키가 존재하는 경우 해당 키에서 PEP 658 메타데이터를 읽어야 합니다 (MUST).core-metadata
가 없고legacy dist-info-metadata
키가 존재하는 경우 선택적으로 사용할 수 있습니다 (MAY).
하위 호환성 (Backwards Compatibility)
이 PEP에는 약간의 호환성 문제가 있습니다. 현재 기존 메타데이터 키를 올바르게 처리하는 클라이언트는 새로운 메타데이터 키를 자동으로 이해하지 못할 것이지만, 정상적으로 저하(degrade gracefully)되어 단순히 PEP 658 메타데이터가 존재하지 않는 것처럼 작동해야 합니다.
그 외에는 이 PEP로 인한 호환성 문제는 없을 것입니다.
거부된 아이디어 (Rejected Ideas)
사양을 변경하지 않고 PyPI 및/또는 pip의 버그 수정을 다루기 (Leave the spec unchanged, and cope with fixing in PyPI and/or pip)
PEP 658이 가져오는 개선 사항은 PyPI에서 의존성(dependencies)을 해결하는 성능을 향상시키는 데 매우 중요하며, 가능한 한 빨리 배포하고 싶습니다.
불행히도 이러한 버그의 특성상, 널리 배포되고 사용되는 pip 버전을 망가뜨리지 않고는 현재 상태로 배포할 수 없습니다. 이 경우의 고장은 영향을 받는 사용자가 pip 버전을 직접 업그레이드하여 수정할 수 없을 정도로 심각할 것이며, 먼저 다른 방법(예: get-pip.py
)으로 pip을 수동으로 가져와야 할 것입니다.
이것은 PyPI가 해당 사용자들을 위한 고장을 완화할 방법 없이 기꺼이 수행하지 않을 일입니다. 합리적인 완화 전략 없이는, 해당 버전의 pip이 PyPI에서 더 이상 사용되지 않을 때까지 기다려야 할 것이며, 이는 아마도 지금부터 5년 이상 걸릴 것입니다.
몇 가지 가능한 완화 전략이 있었지만, 이 역시 거부되었습니다.
완화: pip 특별 처리 (Mitigation: Special Case pip)
고장은 특히 심각하여 사용자가 고장 나지 않은 pip 버전을 얻기 위해 pip을 업그레이드하는 것조차 방해하므로, pip install --upgrade pip
와 같은 명령이 실패할 것입니다. PyPI가 pip 자체를 특별 처리하여 JSON 엔드포인트가 PEP 658 메타데이터를 절대 반환하지 않도록 함으로써 이를 완화할 수 있었습니다.
이 PEP는 이 아이디어를 거부합니다. pip만 업그레이드하는 간단한 명령은 작동하겠지만, 사용자가 해당 명령에 다른 것을 포함하여 업그레이드하면 명령이 다시 실패하게 되며, 이는 여전히 너무 큰 고장이라고 간주되기 때문입니다.
또한, 이 버그는 현재 PyPI와 함께 노출되고 있지만, 실제로는 PEP 658 메타데이터를 올바르게 노출하는 모든 PEP 691 저장소에서 발생할 수 있는 버그입니다. 이는 모든 저장소가 pip에 대한 이 특별한 경우를 처리해야 함을 의미합니다.
완화: 서버가 User-Agent
감지 사용 (Mitigation: Have the server use User-Agent Detection)
pip은 User-Agent
에 버전 번호를 포함하므로, 서버는 버전 번호를 감지하고 해당 버전 번호에 따라 다른 응답을 제공하여 고장 난 pip 버전에는 PEP 658 메타데이터를 제공하지 않을 수 있습니다.
이 PEP는 이 아이디어를 거부합니다. User-Agent
감지를 합리적인 방식으로 구현하는 것이 너무 어렵기 때문입니다.
- PyPI에서는 CDN에서 Simple API를 캐싱하는 데 크게 의존합니다.
User-Agent
에 따라 응답을 다르게 하면 CDN 캐시가 동일한 콘텐츠에 대해 캐시 키가 폭발적으로 증가하여 특정 요청이 캐시되지 않고 백엔드 서버로 다시 돌아갈 가능성이 높아져, 부하를 지원하기 위해 훨씬 더 높은 확장이 필요할 것입니다. - PyPI는 요청의
Accept
헤더를 변경하여User-Agent
감지 아이디어를 지원할 수 있습니다. 이는 해당 버전이 HTML 버전만 허용하는 것처럼 보이게 하여 CDN의 캐시 키를 유지할 수 있습니다. 그러나 이것은 PyPI의 다운스트림 캐시, 특히 pip의 HTTP 캐시에 영향을 미치지 않습니다. pip의 HTTP 캐시는 해당 요청에 대해 JSON 버전을 캐시했을 수 있으며, 우리는 캐시를 공유하는 것이 허용되지 않는다는 것을 알기 위해Vary
헤더를User-Agent
로 내보내지 않을 것입니다.Vary: User-Agent
를 다운스트림 캐시에 추가하는 것은 (1)과 동일한 문제를 가지지만, CDN 캐시 대신 다운스트림 캐시에 대한 것입니다. - pip 버그는 궁극적으로 PyPI에만 국한된 것이 아니라, PEP 691과 PEP 658을 함께 구현하는 모든 저장소에 영향을 미칩니다. 이는 구현별 수정에 의존하는 해결 방법이 두 가지를 모두 구현하는 각 저장소에 대해 복제되어야 함을 의미하며, 모든 경우에 쉽거나 가능하지 않을 수 있습니다(예: 정적 미러는
User-Agent
감지를 수행할 수 없습니다).
JSON 키만 변경 (Only change the JSON key)
pip의 버그는 Simple API의 JSON 표현에만 영향을 미치므로, 실제로는 JSON의 키만 변경하면 되고 기존 HTML 키는 그대로 둘 수 있었습니다.
이 PEP는 장기적으로 HTML과 JSON 키 이름이 달라지면 이러한 종류의 실수가 발생할 가능성이 높아지고 사양을 구현하고 이해하는 것이 더 혼란스러워질 것이라고 생각하여 이 아이디어를 거부합니다.
HTML 키를 변경하지 않으려는 주요 이유는 이미 지원하고 있을 수 있는 HTML 전용 클라이언트 또는 저장소에서 PEP 658 지원을 잃지 않기 위함입니다. 이 PEP는 클라이언트와 서버가 두 키를 계속 지원하도록 허용하고, 언제 어떻게 그렇게 해야 하는지에 대한 권장 사항을 제공함으로써 이러한 고장을 완화합니다.
권장 사항 (Recommendations)
이 섹션의 권장 사항(이 안내문 자체를 제외하고)은 규범적(non-normative)이 아니며, PEP 작성자들이 이 PEP를 구현하는 무언가를 위한 최선의 기본 구현 결정이라고 믿는 것을 나타내지만, 이러한 결정과 일치해야 하는 어떠한 요구 사항도 나타내지 않습니다.
서버 (Servers)
- 서버는 새로운 키만 내보내는 것을 권장합니다. 특히 버그 자체가 JSON에만 영향을 미쳤기 때문에 Simple API의 JSON 표현에 대해 더욱 그렇습니다.
- HTML을 사용하고 PEP 658이 구현된 클라이언트에서 PEP 658을 지원하고자 하는 서버는 HTML에서만 두 키를 안전하게 내보낼 수 있습니다.
- 서버는 고장 난 버전의 pip이 서버에 접근하지 않을 것이라는 것을 알지 못하는 한 JSON에서 오래된 키를 내보내서는 안 됩니다 (should not).
클라이언트 (Clients)
- 클라이언트는 이 PEP가 요구하는 대로 새로운 키를 선호하며, HTML과 JSON 모두에 대해 두 키를 모두 지원하는 것을 권장합니다. 이렇게 하면 클라이언트가 PEP 658 및 PEP 691을 이미 올바르게 구현했지만 이 PEP를 구현하지 않은 저장소를 지원할 수 있습니다.
저작권 (Copyright)
이 문서는 퍼블릭 도메인 또는 CC0-1.0-Universal 라이선스 중 더 관대한 조건으로 배포됩니다.
⚠️ 알림: 이 문서는 AI를 활용하여 번역되었으며, 기술적 정확성을 보장하지 않습니다. 정확한 내용은 반드시 원문을 확인하시기 바랍니다.
Comments