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

Python 개선 제안 한국어 번역

PEP 714 – Simple API에서 dist-info-metadata 이름 변경

Author:
Donald Stufft <donald at stufft.io>
PEP-Delegate:
Paul Moore <p.f.moore at gmail.com>
Discussions-To:
Discourse thread
Status:
Accepted
Type:
Standards Track
Topic:
Packaging
Created:
06-Jun-2023
Post-History:
06-Jun-2023
Resolution:
27-Jun-2023

Table of Contents

번역·라이선스 안내

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

초록

이 PEP는 Simple API의 HTML 및 JSON 형식에서 PEP 658이 제공하는 메타데이터의 이름을 변경하고, 클라이언트와 서버가 이름 변경을 처리하는 방법에 대한 지침을 제공합니다.

동기

PEP 658은 클라이언트가 전체 아티팩트를 다운로드하지 않고도 메타데이터를 가져와 사용할 수 있도록, Simple API를 통해 제공되는 아티팩트의 핵심 메타데이터 파일을 호스팅하는 메커니즘을 명시했습니다. 이후 PEP 691은 Simple API에서 HTML 대신 JSON을 사용할 수 있는 기능을 추가하기 위해 작성되었으며, 여기에는 PEP 658메타데이터에 대한 지원도 포함되었습니다.

안타깝게도 PyPI는 아주 최근에야 recently PEP 658을 지원했으며, 이 지원은 PEP 658dist-info-metadata키가 JSON 표현에서 잘못 data-dist-info-metadata로 명명되는 bug 와 함께 배포되었습니다. 그러나 해당 버그를 수정하려고 시도하던 중, pip도 또한 bug가 있었으며, JSON 표현에서 dist-info-metadata를 어떤 방식으로든 사용하면 pip가 예외와 함께 치명적으로 실패한다는 사실이 발견되었습니다.

pip의 버그는 적어도 v22.3부터 존재했으며, 이는 해당 버전이 약 8개월 동안 배포되었다는 뜻입니다. 따라서 Python 릴리스, 하위 Linux 릴리스, 컨테이너, 가상 환경 등에 포함되기에 충분히 긴 기간이었습니다.

이로 인해 pip의 버그 때문에 PyPI의 버그를 수정하면 pip가 작동하지 않게 되어 수정할 수 없지만, 해당 pip 버전은 널리 배포되기에 충분히 오래된 상태라는 난처한 상황에 놓였습니다. 설상가상으로, 이러한 방식으로 손상된 pip 버전은 버그를 수정한 후에는 새로운 수정 버전의 pip를 설치하는 것까지 포함하여 PyPI에서 어떤 것도 설치할 수 없습니다.

근거

이러한 버그를 수정하기 위한 앞으로의 방안에는 세 가지 주요 선택지가 있습니다.

  1. 사양을 변경하지 않고 pip의 버그를 수정한 다음, 일정 기간 기다렸다가 PyPI의 버그를 수정하여 수정되지 않은 pip를 사용하는 사용자가 PyPI에서 새로운 pip조차 설치할 수 없게 만듭니다.
  2. (1)과 동일하게 수행하되, PyPI를 특수 처리하여 해당 메타데이터를 사용할 수 있더라도 pip에는 PEP 658메타데이터를 제공하지 않도록 합니다. 이렇게 하면 손상된 버전을 사용 중인 사람은 pip를 업그레이드할 수 있지만, 다른 작업은 할 수 없습니다.
  3. 현재 pip가 처리할 수 없는 키를 피하도록 사양을 변경하여 PyPI가 해당 키를 제공하고, 새로운 pip 버전이 출시되어 해당 키를 활용할 수 있도록 합니다.

이 PEP는 (3)을 선택하지만, 한 단계 더 나아가 HTML 표현의 키 이름도 변경합니다.

일반적으로 특정 구현 하나에만 영향을 미치는 버그 때문에 사양을 변경하지는 않습니다. 단, 이 경우처럼 사양 자체에 문제가 있는 경우는 예외입니다. 여기서는 사양이 올바르며, 단지 pip와 PyPI에 실제 버그가 있을 뿐입니다.

그러나 다음 네 가지 이유로 이렇게 하기로 선택했습니다.

  1. pip와 PyPI에 함께 영향을 미치는 버그는 다른 어떤 클라이언트와 저장소의 조합보다 불균형적으로 큰 영향을 미칩니다.
  2. 손상되었을 때의 영향은 어떤 방식으로든 점진적으로 성능이 저하되는 것이 아니라 설치가 전혀 작동하지 않는다는 것입니다.
  3. 이러한 버그로 차단된 기능은 pip를 사용하여 PyPI에서 종속성을 빠르고 효율적으로 해결하는 능력에 매우 중요합니다. 또한 손상된 pip 버전이 사용되지 않게 될 때까지 오랜 기간 기다리며 이 기능을 지연해야 한다면 전체 생태계에 해가 됩니다.
  4. 이 기능에 대한 지원이 널리 퍼져 있다고 생각하지 않으므로 사양 변경의 단점은 상당히 제한적이며, 따라서 제한된 수의 프로젝트에만 영향을 미칩니다.

사양

이 문서에서 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY” 및 “OPTIONAL”” 키워드는 RFC 2119에 설명된 대로 해석해야 합니다.

서버

Simple API의 HTML 표현에서 PEP 658메타데이터를 사용하는 경우, 지원되는 값은 그대로 유지하면서 data-core-metadata라는 속성 이름을 사용하여 제공해야 MUST 합니다.

Simple API의 PEP 691JSON 표현에서 PEP 658메타데이터를 사용하는 경우, 지원되는 값은 그대로 유지하면서 core-metadata라는 키를 사용하여 제공해야 MUST 합니다.

이전 키 이름을 사용한 클라이언트를 지원하기 위해 HTML 표현은 data-dist-info-metadata를 사용하여 제공할 수도 MAY 있으며, 그렇게 하는 경우 해당 값은 data-core-metadata의 값과 일치해야 MUST 합니다.

클라이언트

Simple API의 HTML 표현을 사용하는 클라이언트는 PEP 658 메타데이터가 존재하는 경우 키 data-core-metadata에서 해당 메타데이터를 반드시 읽어야 합니다. 해당 키가 존재하지만 data-core-metadata가 존재하지 않는 경우 레거시 data-dist-info-metadata선택적으로 사용할 수 있습니다.

Simple API의 JSON 표현을 사용하는 클라이언트는 PEP 658 메타데이터가 존재하는 경우 키 core-metadata에서 해당 메타데이터를 반드시 읽어야 합니다. 해당 키가 존재하지만 core-metadata가 존재하지 않는 경우 레거시 dist-info-metadata키를 선택적으로 사용할 수 있습니다.

하위 호환성

이 PEP에는 사소한 호환성 문제가 있습니다. 현재 기존 메타데이터 키를 올바르게 처리하는 클라이언트가 새로운 메타데이터 키를 자동으로 이해하지는 못하지만, 정상적으로 기능을 축소하고 PEP 658 메타데이터가 존재하지 않는 것처럼 동작해야 합니다.

그 외에는 이 PEP와 관련된 호환성 문제가 없어야 합니다.

거부된 아이디어

사양을 변경하지 않고 PyPI 및/또는 pip에서 수정하는 방법을 모색합니다.

우리는 PEP 658이 가져온 개선 사항이 PyPI에서 의존성을 해결하는 성능을 향상하는 데 매우 중요하다고 믿으며, 이를 가능한 한 신속하게 배포할 수 있기를 바랍니다.

안타깝게도 이러한 버그의 특성상, 널리 배포되어 사용되는 pip 버전을 손상하지 않고는 이를 현재 상태 그대로 배포할 수 없습니다. 이 경우의 손상은 영향을 받는 사용자가 문제를 해결하기 위해 pip 버전을 직접 업그레이드할 수도 없고, 먼저 다른 방법으로 pip를 수동으로 가져와야 할 정도로 심각합니다(예: get-pip.py).

PyPI는 해당 사용자들을 위한 이러한 손상을 완화할 방법 없이는 이 작업을 수행하지 않으려 할 것입니다. 합리적인 완화 전략이 없다면, PyPI에서 해당 pip 버전이 더 이상 사용되지 않을 때까지 기다려야 하며, 이는 아마도 지금으로부터 5년 이상 걸릴 것입니다.

사용할 수 있는 완화 전략은 몇 가지 있지만, 이들 역시 거부했습니다.

완화: pip를 특별히 처리하기

손상이 특히 심각한 이유는 사용자가 손상되지 않은 pip 버전을 얻기 위해 pip를 업그레이드하는 것조차 방지하기 때문이며, 따라서 pip install --upgrade pip와 같은 명령이 실패합니다. PyPI가 pip 자체를 특별히 처리하도록 하여 JSON 엔드포인트가 PEP 658 메타데이터를 절대 반환하지 않게 하면 위의 명령이 계속 작동하도록 완화할 수 있습니다.

이 PEP에서는 pip만 업그레이드하는 간단한 명령은 작동하더라도, 사용자가 해당 명령에 업그레이드할 다른 항목을 무엇이든 포함하면 명령이 다시 실패하게 되므로 이 아이디어를 거부합니다. 이는 여전히 손상이 너무 크다고 판단합니다.

또한 이 버그가 현재 PyPI에서 드러나고 있기는 하지만, 실제로는 PEP 658 메타데이터를 올바르게 노출하는 모든 PEP 691 저장소에서 발생할 수 있는 버그입니다. 이는 모든 저장소가 pip를 위한 이 특별한 처리를 포함해야 한다는 의미입니다.

완화: 서버가 User-Agent 감지를 사용하도록 하기

pip은 버전 번호를 User-Agent에 넣으므로, 서버는 버전 번호를 감지하고 해당 버전 번호에 따라 서로 다른 응답을 제공하여 손상된 pip 버전에는 PEP 658 메타데이터를 제공하지 않을 수 있습니다.

이 PEP에서는 User-Agent 감지를 합리적인 방식으로 구현하기가 너무 어렵기 때문에 이 아이디어를 거부합니다.

  1. PyPI에서는 CDN에 Simple API를 캐시하는 데 크게 의존합니다. User-Agent에 따라 응답을 달리하면 동일한 콘텐츠에 대한 캐시 키가 CDN 캐시에 폭발적으로 증가하여, 특정 요청이 캐시되지 않고 백엔드 서버에 도달할 가능성이 커집니다. 그러면 부하를 지원하기 위해 백엔드 서버를 훨씬 더 크게 확장해야 합니다.
  2. PyPI는 요청의 Accept 헤더를 변경하여 해당 버전들이 HTML 버전만 허용하는 것처럼 보이게 함으로써, CDN의 캐시 키를 유지하면서 User-Agent 감지 아이디어를 지원할 수도 있습니다. 그러나 이는 pip의 HTTP 캐시를 비롯한 PyPI의 모든 하위 캐시에는 영향을 주지 않습니다. 해당 요청에 대한 JSON 버전이 캐시되어 있을 수 있고, 이러한 캐시를 공유해도 허용되지 않는다는 사실을 하위 캐시가 알 수 있도록 User-Agent에 대한 Vary를 내보내지도 않기 때문입니다. 하위 캐시에 Vary: User-Agent를 추가하면 (1)과 동일한 문제가 발생하지만, 이는 CDN 캐시가 아닌 하위 캐시에 해당합니다.
  3. pip 버그는 궁극적으로 PyPI에만 해당하는 것이 아니라, PEP 691PEP 658을 함께 구현하는 모든 저장소에 영향을 줍니다. 이는 구현별 수정에 의존하는 우회 방법을 두 기능을 모두 구현하는 각 저장소에 복제해야 한다는 의미이며, 모든 경우에 쉽거나 가능한 것은 아닙니다(예를 들어 정적 미러는 이러한 User-Agent 감지를 수행하지 못할 수 있습니다).

JSON 키만 변경하기

pip의 버그는 Simple API의 JSON 표현에만 영향을 미치므로, 실제로 변경할 필요가 있는 것은 JSON의 키뿐이며 기존 HTML 키는 그대로 둘 수 있습니다.

이 PEP는 장기적으로 HTML과 JSON의 키 이름이 서로 달라지면 이와 같은 실수가 발생할 가능성이 커지고 사양을 구현하고 이해하는 일이 더 혼란스러워질 것이라고 판단하므로 그렇게 하는 것을 거부합니다.

HTML 키를 변경하지 않으려는 주된 이유는 이미 이를 지원하고 있을 수 있는 HTML 전용 클라이언트나 저장소에서 PEP 658 지원을 잃지 않기 위해서입니다. 이 PEP는 클라이언트와 서버 모두 두 키를 계속 지원할 수 있도록 허용하고, 언제 어떻게 그렇게 할지 권고함으로써 이러한 호환성 손상을 완화합니다.

권고 사항

이 고지 자체를 제외한 이 절의 권고 사항은 비규범적이며, 이 PEP를 구현하는 무언가에 가장 적합한 기본 구현 결정이라고 PEP 작성자들이 판단하는 내용을 나타내지만, 이러한 결정을 반드시 따를 것을 요구하는 것은 아닙니다.

서버

특히 버그 자체가 JSON에만 영향을 미쳤으므로, 서버는 더 새로운 키만 내보내도록 권장합니다.

HTML을 사용하고 이를 구현한 클라이언트에서 PEP 658을 지원하려는 서버는 두 키를 HTML에서만 안전하게 내보낼 수 있습니다.

서버에 액세스하는 데 문제가 있는 pip 버전이 사용되지 않을 것이라고 확신하는 경우가 아니라면, 서버는 JSON에서 이전 키를 내보내서는 안 됩니다.

클라이언트

클라이언트는 HTML과 JSON 모두에서 두 키를 지원하고, 이 PEP에서 요구하는 대로 더 새로운 키를 우선하도록 권고합니다. 이를 통해 클라이언트는 PEP 658PEP 691를 이미 올바르게 구현했지만 이 PEP는 구현하지 않은 저장소를 지원할 수 있습니다.