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

Python 개선 제안 한국어 번역

PEP 808 – 동적 메타데이터에 정적 값 포함하기

Author:
Henry Schreiner <henryschreineriii at gmail.com>, Cristian Le <python at lecris.dev>
Sponsor:
Filipe Laíns <lains at python.org>
PEP-Delegate:
Paul Moore <p.f.moore at gmail.com>
Discussions-To:
Discourse thread
Status:
Accepted
Type:
Standards Track
Topic:
Packaging
Created:
19-Sep-2025
Post-History:
17-Apr-2025, 14-Nov-2025
Resolution:
19-May-2026

Table of Contents

번역·라이선스 안내

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

초록

이 PEP는 pyproject.toml[project] 섹션에 나열된 동적 메타데이터에 대한 제약을 완화합니다. 이제 해당 필드가 테이블 또는 배열인 경우 [project] 테이블에서 동적 메타데이터 필드의 정적 부분을 정의할 수 있습니다. 마찬가지로 METADATA 2.6에서는 소스 배포 메타데이터에 정적 메타데이터와 동적 메타데이터를 혼합하여 지정할 수 있습니다.

이를 통해 사용자는 백엔드가 메타데이터를 확장하도록 허용하면서도 메타데이터의 정적 부분을 pyproject.toml의 표준 위치에 정의된 상태로 유지할 수 있으며, 검사 도구가 메타데이터의 정적 부분을 계속 처리할 수 있습니다.

동기

원래 PEP 621에서 제시된 핵심 메타데이터 사양에서는 메타데이터를 세 가지 방식으로 지정할 수 있습니다. 첫째, [project] 테이블에 나열할 수 있습니다. 이렇게 하면 정적으로 추론할 수 있으므로 빌드 백엔드뿐만 아니라 모든 도구가 값을 안정적으로 계산할 수 있습니다. 둘째, 필드를 project.dynamic 목록에 나열할 수 있으며, 이렇게 하면 빌드 백엔드가 값을 계산할 수 있습니다. 마지막으로, project 테이블과 project.dynamic 목록 모두에서 값이 누락될 수 있으며, 이 경우 해당 메타데이터는 비어 있음이 보장됩니다.

이 시스템은 Python 패키징에 두 가지 중요한 이점을 제공했습니다. 이제 모든 주요 백엔드가 채택한 표준 명세 덕분에 교육이 훨씬 쉬워졌으며, 이제 하나의 튜토리얼만으로도 모든 백엔드 구성에서 메타데이터 부분을 다룰 수 있습니다. 이제 사용자는 정적 메타데이터를 변경하지 않고 범용 백엔드에서 특수 목적 백엔드로 전환할 수 있습니다. 스키마 검증 도구와 같은 도구를 사용하면 구성 오류를 검증하고 찾아낼 수 있습니다.

두 번째 이점은 메타데이터를 찾기 위해 소스 파일을 읽는 정적 도구에 대한 지원이 향상된 것입니다. 이는 “used by” 및 “uses” 그래프 생성과 같은 의존성 체인 분석에 유용합니다. 이는 Python에서 지원되는 최소 버전을 감지하는 코드 품질 도구에 사용됩니다. 이는 cibuildwheel를 사용하여 지원되지 않는 휠을 자동으로 빌드하지 않도록 하는 데 사용됩니다. 그러나 SDist를 사용할 수 있을 때 휠 빌드를 피하는 데에는 사용되지 않습니다. 이 문제는 METADATA 2.2에서 SDist 메타데이터에 Dynamic 필드를 추가하여 해결되었으며, 이 필드를 통해 도구는 휠을 만들 때 메타데이터가 변경될 수 있는지 알 수 있습니다. 이름이 비슷하기 때문에 쉽게 저지르는 실수입니다.

프로젝트 테이블의 인기가 빠르게 높아지고 모든 주요 백엔드가 이를 지원하며 복잡한 컴파일된 확장을 지원하는 백엔드가 증가함에 따라, PEP 621에 적용된 제한 사항의 문제가 더욱 분명해지고 있습니다. PEP 621에서는 메타데이터 선택이 양자택일입니다. 메타데이터는 완전히 정적이거나, 동적 필드에 나열되고 정적 정의에는 완전히 없어야 합니다. 가장 일반적인 사용 사례에서는 이것이 문제가 되지 않습니다. 동적으로 재정의할 예정이라면 version을 정적으로 설정할 이점이 거의 없습니다. 적절하게 표시하기 위해 README를 필터링하거나 수정하는 사용자 지정 README 프로세서를 사용하는 경우, 사용자 지정 [tool.*] 섹션에 구성을 지정해야 하더라도 큰 문제가 되지 않습니다. 그러나 양자택일 방식이 문제가 되는 특정 사례가 있습니다. 백엔드가 항목을 추가해야 하는 항목 목록은 현재 완전히 동적으로 지정하도록 강제됩니다(즉, 백엔드별 구성 위치에서 지정해야 합니다). 이로 인해 원래의 두 가지 이점(표준 위치와 정적 도구 지원)이 모두 사라집니다.

근거

PEP 621에는 다음과 같은 문장이 포함되어 있습니다.

이 PEP의 이전 버전에서는 도구가 필드의 데이터를 확장할 수 있었습니다. 예를 들어 빌드 백엔드는 휠을 빌드할 때 사용할 로컬 버전을 추가하기 위해 버전 번호를 가져올 수 있었습니다. 도구는 라이선스나 지원되는 Python 버전과 같은 항목에 대해 trove 분류자를 더 추가할 수도 있었습니다.

결국에는 더 엄격하게 시작한 다음, 실제 사용 사례를 바탕으로 데이터를 얼마나 정적인 것으로 간주할 수 있는지에 대한 기준을 완화하는 방안을 검토하는 편이 낫다고 판단했습니다.

이 PEP에서는 [project] 테이블과 project.dynamic 목록에 대한 제한을 제한적이고 명시적으로 완화할 것을 제안합니다.

이제 임의의 키를 가진 모든 목록과 모든 테이블을 [project] 테이블과 project.dynamic 목록 양쪽에서 정적으로 지정할 수 있습니다. 양쪽에 모두 존재하는 경우 빌드 백엔드는 목록 항목을 확장하고 새 키를 추가할 수 있지만, 기존 항목은 수정할 수 없습니다.

사용 사례

고급 사용 사례가 이 규칙의 완화로 큰 혜택을 받을 수 있는 메타데이터 필드의 유형이 전체적으로 존재합니다. 지금까지 제기된 몇 가지 사용 사례는 다음과 같습니다.

  • 휠을 빌드할 때 의존성 요구 사항 고정하기. 예를 들어 PyTorch 확장 기능을 빌드할 때는 빌드에 사용하는 버전이 생성하는 휠에 제약 조건을 추가하며, 이 제약 조건은 SDist에는 존재하지 않습니다.
  • 빌드 시스템에서 추가 스크립트 생성하기(현재 scikit-build-core_에서 제안되고 있습니다).
  • 엔트리 포인트를 동적으로 추가하기(validate-pyproject-schema-store_에서는 패키지에 존재하는 각 스키마에 대한 엔트리 포인트를 생성하는 데 이를 사용할 수 있었을 것입니다).
  • 구성에 따라 의존성 또는 선택적 의존성 추가하기(예를 들어 모든 의존성을 만들거나 dependency-groups에서 의존성을 읽는 경우). 제약 조건을 추가하는 것도 유용할 수 있습니다. pybind11_은 두 패키지가 동일한 저장소에 있고 함께 릴리스되므로 global 추가 항목을 사용해 pybind11-global==<version>을 고정합니다. toga_는 현재 동일한 종류의 고정 문제로 인해 정적 의존성을 설정할 수 없는 패키지 모음입니다.
  • 분류자 추가하기. 일부 백엔드는 다른 위치에서 분류자를 계산하여 주입할 수 있습니다(가장 잘 알려진 예는 Poetry_입니다).
  • 어떤 라이브러리가 링크되어 있는지를 바탕으로 휠에 라이선스 파일 추가하기(이는 PEP 639의 후속 논의에서 현재 활발히 논의되고 있습니다).
  • 빌드할 때 SBOM 추가하기 - 빌드 도구가 이것들을 추가하기를 원하므로 PEP 770에서는 pyproject.toml 필드를 특별히 제거해야 했습니다. 따라서 [project] 테이블 설정은 쓸모없게 되며, 이를 사용할 수 있는 경우는 거의 없었을 것입니다.
  • 생성된 모듈을 import-names 또는 import-namespaces에 추가하는 것도 또 다른 예입니다.

이러한 모든 사용 사례에는 유사한 특징이 있습니다. 즉, 고정된 목록에 무언가를 동적으로 추가합니다(의존성 사례에서는 더 좁은 고정일 수도 있습니다).

현재도 이를 구현할 수 있지만, 확장되지 않는 부분을 위한 완전히 별도의 구성 위치를 제공해야 하며, 정적 분석 도구는 어떤 것도 탐지할 수 없게 됩니다. 현재 해결책은 모든 메타데이터를 표준 필드 밖으로 옮기는 것이므로, 이 제안은 정적 도구에서 메타데이터를 이용할 수 있는 범위를 넓힐 것입니다.

예: 고정

예를 들어 가상의 빌드 백엔드(my-build-backend)가 지원되는 PyTorch 빌드로 고정하도록 허용하려 한다고 가정해 보십시오. 이 PEP 이전에는 다음과 같이 할 수 있었습니다.

[project]
dynamic = ["dependencies"]

[tool.my-build-backend]
original-dependencies = ["torch", "packaging"]
pin-to-build-versions = ["torch=={exact}"]

그러면 결과적으로 다음과 같은 SDist 메타데이터로 확장됩니다.

Dynamic: Requires-Dist
Requires-Dist: packaging
Requires-Dist: torch

그런 다음 다음과 같은 휠을 만들 수 있습니다.

Requires-Dist: packaging
Requires-Dist: torch
Requires-Dist: torch==2.8.0

정적 도구는 이제 torchpackaging이 런타임 의존성이라는 사실을 알 수 없으며, 빌드 백엔드는 의존성 테이블을 중복해서 정의해야 하므로 사용자가 이를 파악하고 읽기가 더 어려워집니다. PEP 621에서 제안되고 모든 주요 빌드 백엔드가 채택한 표준화된 위치가 사라집니다.

이 PEP를 사용하면 이제 다음과 같이 지정할 수 있습니다.

[project]
dependencies = ["torch", "packaging"]
dynamic = ["dependencies"]

[tool.my-build-backend]
pin-to-build-versions = ["torch=={exact}"]

이제 정적 도구가 정적 의존성을 탐지할 수 있으며, 빌드 백엔드는 표준 project.dependencies 필드를 위한 새 위치(예를 들어 위의 original-dependencies 필드)를 만들고 문서화할 필요가 없습니다.

향후 업데이트

순수하게 추가만 가능한 메타데이터를 허용하도록 이 규칙을 완화하면 실제 사용에서 확인된 많은 사용 사례를 해결할 수 있습니다. 추가 변경이 필요하다면 향후 PEP에서 이를 다시 검토할 수 있습니다. 이 PEP는 이와 같은 향후 업데이트를 권장하지도 배제하지도 않습니다.

용어

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

명세

임의의 항목으로 구성된 리스트 또는 테이블인 모든 필드는 이제 [project] 테이블과 project.dynamic 리스트 양쪽에 존재할 수 있습니다. 필드가 두 위치 모두에 존재하는 경우, 빌드 백엔드는 리스트 또는 테이블에 항목을 삽입할 수 있지만, 항목을 제거하거나 순서를 변경하거나 수정할 수는 없습니다. 배열 테이블에서는 위 규칙에 따라 새 테이블 항목을 추가하거나 기존 배열을 확장할 수 있습니다.

임의의 항목을 포함하는 배열 또는 테이블인 필드는 다음과 같습니다.

  • authors, maintainers: 새 작성자 테이블을 리스트에 추가할 수 있습니다. 기존 작성자는 수정할 수 없습니다(미리 정의된 키를 사용하는 테이블 리스트).
  • classifiers: 분류자를 리스트에 추가할 수 있습니다.
  • dependencies: 기존 의존성을 더 엄격하게 제한하는 것을 포함하여 새 의존성을 추가할 수 있습니다.
  • entry-points: 새 그룹 또는 기존 그룹에 진입점을 추가할 수 있습니다. 기존 진입점은 변경하거나 제거할 수 없습니다.
  • scripts, gui-scripts: 새 스크립트를 추가할 수 있습니다. 기존 스크립트는 변경하거나 제거할 수 없습니다.
  • keywords: 키워드를 리스트에 추가할 수 있습니다.
  • license-files: 파일을 리스트에 추가할 수 있습니다.
  • optional-dependencies: 새 추가 항목을 만들거나 기존 추가 항목에 새 항목을 추가할 수 있습니다.
  • urls: 새 URL을 추가할 수 있습니다. 기존 URL은 변경하거나 제거할 수 없습니다.
  • import-names, import-namespaces: 새 임포트 이름 또는 네임스페이스를 추가할 수 있습니다. 기존 임포트 이름 또는 네임스페이스는 수정하거나 제거할 수 없습니다.

항목을 추가하려면 사용자는 해당 필드를 dynamic에 나열하여 명시적으로 활성화해야 합니다. 그렇게 하지 않으면 메타데이터는 계속 완전히 정적으로 유지됩니다.

필드가 지정되었지만 백엔드가 해당 필드의 확장을 지원하지 않는 경우, 사용자 오류를 방지하기 위해 백엔드는 SHOULD 오류를 발생시켜야 합니다. dynamic 리스트에 불필요한 항목이 포함되지 않도록 가능한 한 엄격하게 처리할 것을 권장합니다.

정적 분석 도구는 필드가 지정되어 있으면서 project.dynamic 배열에도 포함되어 있음을 감지하면, 해당 필드가 불완전하다고 간주하여 패키지를 빌드할 때 새 항목이 존재할 수 있도록 SHOULD 해야 합니다.

Dynamic 필드는 PEP 643에 명시된 대로 이 PEP의 영향을 받지 않으며, 백엔드는 계속해서 원하는 방식으로 이 필드를 채울 수 있습니다. 그러나 백엔드는 SDist와 휠 메타데이터 모두에 프로젝트 테이블의 정적 메타데이터 부분이 포함되도록 MUST 보장해야 합니다.

METADATA 2.2부터 2.5까지는 Dynamic에 나열된 항목에 대한 제약이 없습니다(즉, 해당 필드에 대해 휠이 SDist와 다른 메타데이터를 포함할 수 있습니다). 이제 SDist에 지정된 메타데이터 필드는 Dynamic이 있어도 휠에도 포함되는 것이 보장됩니다. METADATA 버전은 2.6으로 증가합니다. 다음 예를 살펴보겠습니다.:

Dynamic: Requires-Dist
Requires-Dist: packaging

METADATA 2.6 이전에는 필드가 Dynamic에 나타나는 경우 해당 필드에 제약이 없었으므로 휠에는 무엇이든 포함될 수 있었습니다. 이제 2.6에서는 여기의 모든 값이 휠에도 포함되는 것이 보장되므로, 휠에는 Requires-Dist: packaging이 포함됩니다. 더 많은 Requires-Dist를 포함할 수 있지만, 최소한 해당 항목 하나는 포함됩니다.

이 새로운 항목이 지침에 추가됩니다:

  • 소스 배포판에 다중 사용 필드가 존재하고 Dynamic으로도 표시된 경우, 휠은 값을 추가할 수 있지만 SDist에 있는 값은 반드시 포함해야 합니다. Keywords, Author-Email, Maintainer-Email은 쉼표로 구분된 목록이며, 존재하는 경우 마찬가지로 확장할 수 있습니다.

참조 구현

각 필드에 동적 메타데이터를 지원할지는 이미 백엔드에 맡겨져 있으며, 이 PEP는 백엔드가 동적 메타데이터로 수행할 수 있는 작업에 대한 제한을 단순히 완화합니다.

여러 빌드 백엔드에서 사용하는 pyproject-metadata 프로젝트는 가능한 확장을 고려하도록 정확성 검사를 수정해야 하며, 이는 a draft PR에서 다루고 있습니다.

백엔드가 동적 메타데이터 플러그인을 공유하는 데 사용할 수 있는 플러그인 시스템을 제공하는 dynamic-metadata 프로젝트는 이러한 가능성을 허용하도록 설계되었으며, 위의 PR과 유사한 PR을 통해 메타데이터를 추가할 수 있게 됩니다.

하위 호환성

이 PEP 이전에는 엄격히 허용되지 않았으므로 기존의 pyproject.toml 파일에는 영향을 주지 않습니다.

사용자가 이를 pyproject.toml에 적용하면 백엔드가 이를 지원해야 합니다. 지원하지 않는 경우 이전 표준에 따라 오류가 올바르게 생성됩니다. 프런트엔드에는 오류를 발생시킬 의무가 없었지만, 일부 프런트엔드는 부분적으로 정적인 메타데이터를 활용할 수 있도록 업데이트해야 할 수 있습니다. 다른 pyproject.toml PEP와 마찬가지로 스키마 검사기와 같은 일부 프런트엔드 및 기타 도구를 업데이트해야 할 수 있습니다.

정적 분석 도구는 이 변경 사항을 처리하도록 업데이트해야 할 수 있습니다. 도구는 다음과 같이 동적 테이블을 먼저 확인해야 합니다.

match pyproject["project"]:
    # New in PEP 808
    case {my.key: value, "dynamic": dyn} if my.key in dyn:
        print(f"Partial {my.key}: {value}")
    case {"dynamic": dyn} if my.key in dyn:
        print(f"Fully dynamic {my.key}")
    case {my.key: value}:
        print(f"Fully static {my.key}: {value}")
    case _:
        print(f"No metadata for {my.key}")

이 PEP 이전에는 도구가 동적 블록과 정적 블록의 순서를 뒤집어, 프로젝트 테이블의 항목은 동적일 수 없다고 가정할 수 있었습니다. 이렇게 하면 실제로는 필드 메타데이터의 일부만 가지고 있는데도 이제 해당 필드의 메타데이터를 모두 가지고 있다고 잘못 가정하게 됩니다.

보안 관련 사항

이는 기존 동적 메타데이터 지원에 정적 구성 요소를 추가할 뿐이므로, 이미 존재하지 않는 새로운 보안 우려는 없습니다.

이 내용을 가르치는 방법

현재 동적 메타데이터를 사용하지만 일부 목록 또는 테이블 항목을 정적으로 알고 있는 경우, 이제 [project] 테이블에 정적 항목을 추가하여 이를 명시적으로 지정할 수 있습니다. 동시에 project.dynamic 목록에도 해당 항목을 유지하여 빌드 백엔드가 동적 부분을 추가하도록 할 수 있습니다.

메타데이터를 [project]project.dynamic에 모두 나열해서는 안 된다고 명시하는 현재 지침은, project.dynamic으로 표시된 목록과 테이블에도 정적 항목을 포함할 수 있다고 설명하도록 업데이트할 수 있습니다. 동적 메타데이터는 이미 고급 개념이므로, 입문 패키징을 대상으로 하는 기존 튜토리얼 자료 대부분에는 영향을 주지 않을 가능성이 높습니다.

pyproject.toml 명세는 필드가 지정되고 동시에 동적 필드에도 나열될 때의 동작을 포함하도록 업데이트됩니다.

또한 dynamic에 무언가를 지정하면, 전체 메타데이터가 필요한 모든 도구가 해당 메타데이터가 부분적으로 정적으로 지정되어 있더라도 백엔드를 호출해야 한다는 점에 유의해야 합니다. 따라서 다른 동적 메타데이터와 마찬가지로 필요한 경우에만 사용해야 합니다.

거부된 아이디어

동적 기능을 추가하지 않고 일부 필드를 특별 취급하기

이는 특히 빌드 의존성 고정 사용 사례와 관련하여 제기되었지만, 나열된 다른 사용 사례에도 적용할 수 있습니다. 그러나 이렇게 해서는 확인된 모든 사용 사례를 다룰 수 없으며, 정적 도구에는 명시적인 옵트인 방식이 더 적합합니다.

문자열 필드 포함하기

일부 문자열 필드도 확장할 수 있습니다. 특히 license필드는 확장 가능하게 만들면 유용하며, SPDX 표현식의 의미론에 따라 AND를 통해 확장을 정의할 수 있습니다. 그러나 이를 추가하면 개별 필드에 사용자 지정 의미론이 필요하므로 이 PEP에는 포함하지 않았습니다.

기타 문자열 필드인 versionrequires-python은 (동적으로 지정할 수 없는 name은 제외하고) 확장할 이유가 상대적으로 적습니다. 사용이 중단된 license.text/license.file 또는 readme.text/readme.file 같은 고정 키 테이블도 부분적으로 동적으로 만들 때 뚜렷한 이점이 없습니다.

백엔드에 대한 제한을 완전히 제거하십시오

또 다른 선택지는 필드가 정적으로 정의되어 있고 동적 배열에 포함된 경우 백엔드가 원하는 것은 무엇이든 단순히 허용하는 것입니다. 이는 정적 도구가 해당 필드에 관해 어떤 것도 추론할 수 있는 능력을 희생시키며, 백엔드가 사용자가 입력한 내용을 무시하거나 변경하도록 허용하여 사용자를 혼란스럽게 할 가능성도 있습니다. 이는 정적 도구와 동적 메타데이터에 관한 현재 상태보다 나쁘지는 않지만, 현재 제안은 정적 도구가 동적 필드에 관한 일부 사항을 추론할 수 있는 능력을 향상합니다. 예를 들어 대부분의 애플리케이션에서는 의존성을 전혀 모르는 것보다 일부 의존성을 아는 것이 더 낫습니다.

단순화를 허용하십시오

이 PEP의 이전 초안에는 백엔드가 일부 유형의 필드를 단순화하도록 허용하는 조항이 있었습니다. 특히 의존성 지정자는 예를 들어 torchtorch>=1.2로 대체하는 것과 같은 “tightening”을 허용했을 것입니다. 현재 사양 내에서 변형이 모든 리졸버에서 동일하게 해결되도록 보장하는 것이 불가능하고 백엔드와의 계약을 단순화하기 위해 이것은 제거되었습니다. 그 밖의 단순화는 순전히 외관상의 것이므로 제외되었습니다. 이제 현재 PEP의 순서는 원래의 정적 메타데이터와 일치해야 하며, 동적 부분에서는 삽입만 허용됩니다.

동적 메타데이터를 지정하는 일반 메커니즘을 추가하십시오

이 PEP에서는 동적 메타데이터를 지정하는 방법을 다루지 않으며, 이는 계속해서 전적으로 백엔드에 달려 있습니다. 이를 수행한 이전 초안 제안이 있었지만, 대신 이를 라이브러리(dynamic-metadata, 관심 있는 분들을 위한 라이브러리)로 개발하는 것이 더 낫다고 판단되었습니다. 이는 향후 다시 검토될 수 있습니다.

참조