부록: 기각된 아이디어
초록
이 문서는 PEP 639에서 제안된 아이디어의 대안 목록과 각 대안이 기각된 이유를 자세히 설명합니다.
코어 메타데이터 필드
PEP 639에서 명세된 코어 메타데이터 필드의 구조, 내용, 폐지에 대한 잠재적 대안입니다.
License 필드 재사용
초기 논의에 따라, PEP 639의 이전 버전은 기존 License 필드를 재사용하자고 제안했으며, 도구는 이 필드를 SPDX 라이선스 표현식으로 파싱하려고 시도하고 실패하면 자유 텍스트로 대체하게 됩니다. 처음에는 이 경우 경고가 발생하고, 나중에는 오류로 처리될 예정이었습니다.
이 방식은 하위 호환성이 더 높고, 커뮤니티가 SPDX 라이선스 표현식을 원활하게 도입할 수 있게 하며, 라이선스 관련 필드를 또 하나 추가하지 않아도 된다는 장점이 있었습니다.
결국 전용 License-Expression 필드가 더 나은 접근 방식이라는 합의에 도달했습니다. 이 필드가 있다는 사실만으로 복잡한 휴리스틱 없이도 SPDX 식별자를 지원한다는 점이 명확히 드러나며, 도구가 잘못된 내용을 쉽게 감지할 수 있습니다.
또한 기존 License 필드와 라이선스 분류자를 모두 쉽게 폐기할 수 있으며, 도구는 PEP 639를 준수하는 패키지와 그렇지 않은 패키지를 구별하여 그에 맞게 동작을 조정할 수 있습니다.
마지막으로, 기존 메타데이터 필드의 동작을 변경하지 않아도 되며, 도구가 필드의 존재 여부만이 아니라 그 값을 바탕으로 Metadata-Version과 필드 동작을 추측해야 하는 상황도 피할 수 있습니다.
License 필드에 이미 유효한 SPDX 라이선스 표현식을 담고 있는 배포물은 자동으로 SPDX 라이선스 표현식으로 인식되지 않습니다. 하지만 마이그레이션은 간단하며, PEP 639는 도구로 이를 자동 처리하는 방법에 대한 지침을 제공합니다.
값 접두사를 붙여 License 필드 재사용
앞의 방식에 대한 대안으로, License 필드를 재사용할 때 생기는 모호함을 줄이기 위해 SPDX 라이선스 표현식 앞에 spdx: 같은 접두사를 붙이자는 제안이 있었습니다. 그러나 이는 사실상 필드 안에 필드를 만드는 것과 다름없으며, License 필드를 유지하는 데 따르는 단점을 해결하지 못합니다. 즉, 이 방식은 여전히 기존 메타데이터 필드의 동작을 바꾸고, 도구가 그 내용을 어떻게 처리할지 결정하려면 값을 파싱해야 하며, 명세 및 폐지 과정을 더 복잡하고 덜 깔끔하게 만듭니다.
현재 License 필드에 유효한 SPDX 식별자를 사용하고 있는 프로젝트는 자동으로 인식되지 않으며, 이를 수정하려면 새 필드를 도입하는 경우와 거의 같은 수준의 노력, 즉 프로젝트 소스 메타데이터의 한 줄을 변경하는 작업이 필요합니다. 따라서 이 방식은 기각되고 새 필드가 채택되었습니다.
License-Expression을 상호 배타적으로 만들지 않기
하위 호환성을 위해 License 필드와 라이선스 분류자 중 하나 또는 둘 모두를 새로운 License-Expression 필드와 함께 계속 허용하고, 아마도 경고를 표시하는 방식도 가능했을 것입니다. 그러나 이는 무려 세 개나 되는 서로 다른 필드에 일관되지 않은 라이선스 메타데이터가 존재하는 상황으로 쉽게 이어질 수 있으며, 이는 라이선스 관련 사항을 모호하지 않게 만든다는 PEP 639의 목표에 어긋납니다. 따라서 커뮤니티의 합의에 따라 이 아이디어는 기각되었습니다.
기존 License 필드와 분류자를 폐기하지 않기
여러 커뮤니티 구성원은 기존 License 필드와 분류자를 폐기하면 패키지 작성자에게 큰 변경 부담을 주고 새 작성자의 진입 장벽을 높일 것이라고 우려했습니다. 특히 법적 세부 사항에 크게 신경 쓰지 않고 개인 프로젝트를 패키징하려는 개발자가 영향을 받을 것이라는 우려였습니다. 실제로 모든 폐지는 장기적인 순이익에 비추어 신중하게 검토해야 합니다. 최소한 이 변경 때문에 Python 개발자가 자신이 선택한 라이선스로 작업물을 공유하기가 더 어려워져서는 안 되며, 이상적으로는 상황이 개선되어야 합니다.
여러 차례의 논의 끝에, 라이선스를 지정하는 레거시 방식을 폐기하고 “명백한 한 가지 방법”을 지향하자는 쪽으로 전반적인 합의가 이루어졌습니다. 그렇게 하지 않으면 패키지의 라이선스를 지정하는 방법 가운데 폐기되지 않은 방법이 세 가지나 남게 됩니다. 그중 두 가지는 모호하고, 문서화가 일관되지 않으며, 시대에 뒤떨어져 있습니다. 도구가 이 방법들을 계속 지원하려면 더 복잡해지므로 유지 관리 비용이 상당히 듭니다.
마지막으로, 유지 관리되지 않는 패키지, 이전 메타데이터 버전을 지원하는 도구를 사용하는 패키지, 라이선스 메타데이터를 제공하지 않기로 선택한 패키지는 폐지와 관계없이 아무것도 변경할 필요가 없습니다.
PyPI에서 새 필드 검증을 의무화하지 않기
이전에 PEP 639는 PyPI(또는 다른 패키지 색인)에 대한 구체적인 지침을 두지 않았습니다. 곧 PyPI가 License-Expression 또는 License-File 필드를 검증해야 하는지, 검증한다면 어떻게 해야 하는지, 그리고 이 필드들을 지원 중단된 License 필드나 라이선스 분류자와 함께 사용하는 경우를 어떻게 처리해야 하는지를 정하지 않았습니다. 이렇게 하면 명세가 단순해지고, 패키지 작성자가 겪을 혼란을 최소화하기 위해 PyPI에서의 구현을 이후의 PEP로 미룰 수 있습니다.
이는 License-Expression을 License 필드와 분리하지 않았던 PEP 639의 이전 초안에 있던 내용입니다. 그러한 검증은 어려웠을 뿐 아니라 하위 호환성을 깨뜨려 기존 패키지를 망가뜨렸을 것입니다. 현재 제안에서는 새 필드를 처음부터 검증해야 한다는 명확한 합의가 있었으며, 이를 통해 코어 메타데이터 버전 2.4 이상을 선언하고 License-Expression 필드를 가진 채 PyPI에 업로드된 모든 배포가 유효한 표현식을 갖도록 보장하므로, PyPI와 그 패키지 및 메타데이터의 소비자는 이 표현식이 여기의 명세를 따른다고 신뢰할 수 있습니다.
같은 방식을 새 License-File 필드에도 확장하여, 그 필드가 유효하고 법적으로 필요한 라이선스 파일이 존재함을 보장할 수 있습니다. 분명히 하자면, 이는 업로드되는 모든 배포 패키지에 그러한 메타데이터를 요구하는 것이 아닙니다. PEP 639의 명세에 따라 이를 선언하기로 선택한 경우에만 그것이 유효함을 보장합니다.
소스 메타데이터 license 키
pyproject.toml 프로젝트 소스 메타데이터의 license 키와 관련하여 고려한 대안입니다.
테이블에 새 하위 키 추가
테이블에 다양한 하위 키를 추가하자는 제안이 있었습니다. 서로 다른 처리가 필요한 여러 유형의 메타데이터를 결합하고, 하위 키들의 상호 배타성과 그중 일부를 동적으로 정의할 수 있는 가능성에 관한 새로운 지침을 추가하면 전환이 더 어려워지고, 사용자에게 명확성보다는 더 큰 혼란을 초래할 것입니다. 이 접근 방식은 더 평탄한 pyproject.toml 설계, pyproject.toml 키와 코어 메타데이터 필드 간의 명확한 매핑, 그리고 분리된 키의 향상된 가독성을 위해 거부되었습니다.
거부된 제안:
- 테이블에
expression및files하위 키 추가 - 문자열 값 대신
expression하위 키 추가 text를 표현식으로 취급하기 위한type키 추가
새 최상위 license-expression 키 정의
PEP 639의 이전 버전은 license 키의 문자열 값을 사용하는 대신 [project] 테이블 아래에 새로운 최상위 license-expression을 정의했습니다. 이는 PEP 639의 목표에 부합하게, 읽는 사람과 작성하는 사람 모두에게 더 명확한 것으로 여겨졌습니다.
기존 도구 형식(및 코어 메타데이터 필드 이름)과의 차이는 PEP 621에 선례가 있지만, 기존 키를 별개의 호환되지 않는 문법으로 다른 의미를 갖도록(그리고 다른 코어 메타데이터 필드에 매핑되도록) 용도 변경하는 것은 선례가 없으며, 독자와 작성자에게 모호함을 일으킬 수 있습니다.
또한 프로젝트 소스 메타데이터 명세에 따르면, 이렇게 하면 License 및 License-Expression 메타데이터 필드에 대응하는 [project] 키를 각각 별도로 dynamic으로 표시할 수 있습니다. 따라서 현재 PEP 639는 license를 dynamic으로 표시하지 않고도 License-Expression 필드로부터 License 필드를 역으로 채우는 것을 허용하는데, 이 방식에 대한 잠재적 우려를 피할 수 있습니다(두 필드가 모두 같은 최상위 키에 매핑되므로 그렇게 표시하는 것은 불가능합니다).
그러나 커뮤니티의 합의는 PEP 621이 이 목적을 위해 예약해 둔 대로, 기존 license 키의 최상위 문자열 값을 사용하는 쪽을 선호했습니다:
license 키에 대한 실용적인 문자열 값은 향후 PEP가 SPDX 표현식 지원을 명시할 수 있도록 의도적으로 제외되었습니다(파일이나 텍스트가 어떤 라이선스를 나타내는지 지정하는 모든 종류의 “type” 필드에도 같은 논리가 적용됩니다).
이 방식은 사용자가 기억하고 입력하기 더 쉽고, 기존 키를 활용하므로 새 최상위 키를 추가하지 않아도 됩니다. 또한 사용자가 라이선스 표현식을 기본으로 사용하도록 유도하고, 원래 PEP 621에서 구상한 바를 따릅니다.
또한 이 방식을 쓰면 키 자체를 지원 중단하지 않고도 테이블 값을 깔끔하게 지원 중단할 수 있습니다. 그리고 사용자가 기억하거나 도구가 강제할 필요 없이 둘을 상호 배타적으로 만들 수 있습니다.
마지막으로, 다른 도구 형식 및 기반이 되는 코어 메타데이터와의 일관성은 기존 키를 사용하는 이점을 뒤집을 만큼 높은 우선순위가 아니었으며, dynamic 관련 우려는 빌드 시점에 레거시 라이선스를 라이선스 표현식으로 변환하는 것을 명세하지 않고, dynamic이 아닐 때 License 필드를 보충하도록 명시적으로 규정하며, 두 필드가 상호 배타적이라는 사실을 통해 대부분 완화되었으므로 어느 쪽이 동적인지 구분할 실질적인 필요는 거의 없습니다.
따라서 이전 작업 초안에서 임시로 명시했던 것처럼, PEP 639에서는 license에 대한 최상위 문자열 값을 채택했습니다.
소스 메타데이터 license-files 키
pyproject.toml [project] 테이블의 license-files 키에 대해 검토한 대안으로, 주로 경로/glob 유형 처리와 관련된 것입니다.
license-files에 상호 배타적인 paths와 globs 하위 키 정의
이 PEP의 이전 초안은 license-files [project] 테이블 키의 하위 키로 상호 배타적인 paths와 globs를 명시했습니다. 이는 사용자와 도구 모두에게 정의된 값의 명확성을 최대한 높이기 위해 제안되었습니다. 라이선스 파일을 리터럴 경로로 지정할 수 있게 하면 glob 문자를 포함하는 경우(또는 PEP 672에서 설명하듯 그와 혼동될 만큼 비슷한 문자를 포함하는 경우)와 같은 엣지 케이스를 피할 수 있습니다.
그러나 이 방식은 중첩 단계를 하나 더 추가하는데, 이는 PEP 639가 license 키에서 제거하는 것과 정확히 같은 방식의 중첩입니다. 이로 인해 라이선스 파일 위치를 지정할 때 두 방식을 구분하여 하나를 선택해야 하는 프로젝트 작성자의 부담이 커집니다. 경로에서도 글롭이 지원된다고 잘못 가정하기 쉽다는 점이 지적되었습니다.
따라서 이 방식을 채택하지 않고, 대신 명세와 구현을 단순화하며 기존 도구의 설정 형식과도 더 가깝게 일치하는 평평한 배열 값을 채택하기로 결정했습니다. 이 PEP는 글롭 패턴을 해석할 때 혼동이 생기지 않도록 파일 이름에 영숫자와 점(.) 이외의 문자를 사용하지 않을 것을 권장합니다.
문자 그대로의 경로만 허용
pyproject.toml의 license-files 키 값으로 글롭을 허용하지 않고 문자 그대로의 경로만 허용할 수도 있습니다. 이렇게 하면 모든 라이선스 파일이 명시적으로 지정되고, 발견되고, 포함되는 것이 보장됩니다. 또한 어떤 라이선스 파일이 포함될지와 License-File 값이 무엇이 될지를 정확히 결정하기 위해 도구가 프로젝트의 나머지 소스 파일을 검사할 필요가 없으므로, 소스 메타데이터가 가장 엄격한 의미에서 완전히 정적이게 됩니다. 또한 명세와 도구 구현도 단순해집니다.
그러나 여기서는 실용성이 순수성보다 우선합니다. 글롭은 이미 많은 기존 도구에서 지원되고 있으며, 벤더링된 의존성이 있는 복잡한 프로젝트에서는 모든 라이선스 파일의 전체 경로를 명시적으로 지정하는 것이 불필요하게 번거로운 일입니다. 더 심각한 문제는 필요한 법적 파일을 실수로 누락하기가 훨씬 쉬워져, 패키지를 배포하는 것이 불법이 될 수 있다는 점입니다.
도구는 패키지를 설치하거나 코드를 실행하지 않고, 심지어 파일을 검사하지 않고도 사용자가 지정한 글롭 패턴과 패키지 내의 파일 이름만으로 포함될 파일을 여전히 결정할 수 있습니다. 그리고 물론 sdist, 휠 등에는 배포 메타데이터에 지정된 파일의 완전한 정적 목록이 들어 있습니다.
지정되지 않은 경우 license-files에 기본값 사용
이 PEP의 이전 초안은 사용자가 라이선스 파일을 하나도 선언하지 않았고 키를 dynamic으로 표시하지도 않은 경우에 라이선스 파일을 감지하기 위한 기본값을 제안했습니다. 그 값은 다음과 같은 글롭 배열로 정의되었습니다: ["LICEN[CS]E*", "COPYING*", "NOTICE*", "AUTHORS*"]
그러나 다른 어떤 키에도 암묵적 기본값이 정의되어 있지 않으므로, 이는 기존 메타데이터 가운데 예외를 만들게 됩니다. pyproject.toml 키의 암묵적 값은 계산되는 것으로 명시된 dynamic 필드에 위임됩니다. 또한 그 값들은 왜 표준이 되어야 하는지에 대한 강력한 근거 없이 임의로 선택되었습니다.
기본값을 사용하려면 dynamic으로 표시해야 함
PEP 621의 dynamic 목록 설명을 제한적으로 해석하면, 기본 글롭 패턴을 사용하려면, 또는 애초에 라이선스 파일이 매칭되고 포함되게 하려면 license-files 키를 dynamic으로 표시하도록 요구하는 것이 합리적으로 보일 수 있습니다.
그러나 이는 사용자가 직접 지정할 수 있는 다른 글롭 패턴 집합과 마찬가지로, 모든 준수 도구가 정확히 그대로 사용해야 하는 정적이고 엄격하게 명시된 기본값을 선언하는 것에 불과합니다. 그 결과로 생기는 License-File 코어 메타데이터 값은 코드를 실행하거나 파일 내용을 검사하지 않고도 소스의 파일 목록을 살펴보는 것만으로 결정할 수 있습니다.
게다가 설령 그렇지 않다 하더라도, 이 해석은 기존 형식과 하위 호환되지 않으며 기존 도구의 동작과도 일관되지 않습니다. 더 나아가, 이는 많은 프로젝트가 자신도 모르는 사이에 법적으로 필수인 라이선스 파일을 더 이상 포함하지 않게 될 심각한 위험을 초래하므로 합리적인 기본값이 아닙니다.
마지막으로, 기본값을 dynamic으로 정의하지 않으면 작성자는 빌드/패키징 도구가 라이선스 파일 포함을 직접 처리하게 되는 경우를 모호함 없이 나타낼 수 있습니다. 그렇게 하지 않으면 dynamic 목록의 목적이 무색해집니다.
라이선스 파일 경로
소스 배포판과 빌드된 배포판에서 라이선스 파일의 경로 및 위치와 관련된 대안입니다.
하위 디렉터리의 라이선스 파일 평탄화하기
PEP 639의 이전 초안들은 하위 디렉터리에 있는 라이선스 파일을 어떻게 처리할지 명시하지 않았습니다. 현재 Wheel과 Setuptools 프로젝트는 소스의 하위 디렉터리 계층 구조를 보존하지 않고 모든 라이선스 파일을 .dist-info 디렉터리 안으로 평탄화합니다.
이 방식은 기존의 임시방편적 관행과 일치하지만, 이름 충돌이 발생하고 라이선스 파일이 다른 파일을 덮어쓸 수 있으며, 이를 해결하는 방법에 대해 정의된 동작도 없습니다. 또한 지정된 라이선스 파일이 포함되지 않았다는 명확한 표시도 없이 패키지를 법적으로 배포할 수 없는 상태로 남겨 둘 수 있습니다.
더 나아가, 이로 인해 루트가 아닌 위치에 있는 라이선스 파일의 상대 파일 경로가 소스, sdist, 휠 사이에서 일관되지 않게 되며, “정적인” [project] 테이블 메타데이터에 주어진 경로가 진정으로 정적일 수 없게 됩니다. 마지막으로, 소스 디렉터리 구조에는 라이선스가 무엇에 적용되는지에 대한 귀중한 정보가 담겨 있는 경우가 많은데, 이 정보는 평탄화할 때 사라지며 재구성하기도 결코 간단하지 않습니다.
이를 해결하기 위해, 이 PEP는 이제 원래 라이선스 파일의 소스 디렉터리 구조를 .dist-info 디렉터리 안에 그대로 재현할 것을 제안합니다. 이 방식의 유일한 단점은 .dist-info 디렉터리가 더 깊이 중첩된다는 것입니다. 뒤이어 설명하는 제안처럼 라이선스 파일을 licenses 하위 디렉터리 아래에 두면 이름 충돌과 난잡함 문제가 모두 완전히 해소됩니다.
이름 충돌을 다른 방식으로 해결하기
.dist-info 디렉터리 안에서 라이선스 파일의 소스 디렉터리 구조를 보존하는 대신, 지나치게 중첩된 디렉터리를 피하기 위해 이름이 고유해질 때까지 트리를 거슬러 올라가며 라이선스 파일 이름 앞이나 뒤에 상위 디렉터리 이름을 붙이는 것과 같은 다른 충돌 해결 메커니즘을 명시할 수도 있습니다.
그러나 이 방식은 경로 일관성 문제를 해결하지 못하고, 훨씬 더 많은 논의가 필요하며, 명세를 더욱 복잡하게 만듭니다. 따라서 이 방식은 기각되었고, 많은 이해관계자가 지지해 온 대로 소스 하위 디렉터리 배치를 그대로 보존하는 더 명백한 해결책이 채택되었습니다.
.dist-info에 직접 넣기
이전에는 포함된 라이선스 파일이 빌드된 휠과 설치된 프로젝트의 최상위 .dist-info 디렉터리에 직접 저장되었습니다.
그러나 이렇게 하면 라이선스를 별도의 네임스페이스로 분리하는 것에 비해 .dist-info 디렉터리가 더 난잡해집니다. 또한 .dist-info 디렉터리 안에서 사용자 지정 라이선스 파일 이름(예: RECORD, METADATA)과 충돌할 위험이 여전히 있으며, 이를 피하려면 사용할 수 있는 파일 이름을 제한해야 합니다. 마지막으로, 라이선스를 별도로 지정된 하위 디렉터리에 두면 사람과 도구가 코어 메타데이터에서 각 파일의 경로를 일일이 참조하지 않고도 (배포판 패키징, 법적 검토 등에서) 모든 라이선스 파일을 한꺼번에 올바르게 다룰 수 있습니다.
따라서 Wheel과 Setuptools 구현 이슈에서 여러 사람이 제안했듯이, 가장 간단하고 명백한 해결책은 라이선스 파일을 .dist-info의 licenses 하위 디렉터리를 기준으로 배치하는 것입니다. 이 방식은 구현하기 간단하며, 더 복잡한 다른 선택지들에 비해 이렇다 할 단점 없이 여기서 언급한 모든 문제를 해결합니다.
명세가 조금 더 복잡해지기는 하지만, 구현은 여전히 똑같이 간단할 것입니다. 이 변경을 따라 만들어진 휠은 이전 휠과 라이선스 위치가 달라지게 되지만, 하위 디렉터리에 있던 라이선스는 이미 그러했고 PEP 639 이전에는 이러한 파일에 프로그래밍 방식으로 접근할 방법이 없었으므로, 실제로 큰 문제가 되지는 않을 것입니다.
휠에 새 licenses 카테고리 추가하기
휠의 코어 메타데이터 디렉터리(.dist-info) 안에 루트 라이선스 디렉터리(licenses)를 정의하는 대신, 현재 휠 아카이브의 .data 아래에 포함되는 다른 카테고리들과 유사하게, 라이선스 파일 전용의 새 카테고리(그리고 아마도 그에 대응하는 설치 스킴)를 예컨대 licenses라는 이름으로 정의할 수도 있습니다. 이는 wheel 제작자가 언급한 것으로, site 경로의 .dist-info 디렉터리보다 플랫폼에 더 적합하고 유연한 위치에 라이선스를 설치할 수 있게 해 줍니다.
그러나 현재 PEP 639는 이 아이디어를 구현하지 않으며, 이는 향후의 PEP로 미뤄졌습니다. PEP 639는 주로 기존 관행을 표준화하고 코어 메타데이터 명세를 갱신하는 데 초점을 두고 있으므로, 이 아이디어는 PEP 639에 상당한 복잡성과 마찰을 더하게 됩니다. 또한 이를 위해서는 Wheel, 설치 프로그램 및 기타 도구와 함께 sysconfig와 그 안에 명시된 설치 스킴을 수정해야 할 수도 있으며, 이는 결코 간단한 작업이 아닙니다. 재패키징하는 사람에게는 다소 더 복잡할 수 있지만, 현재 제안은 여전히 모든 라이선스 파일이 하나의 전용 디렉터리에 포함되도록 보장하므로, 이 점에서 현 상황을 크게 개선할 것입니다.
또한 이 방식은 (휠을 단순히 압축 해제하는 도구에게 투명하지 않으므로) 완전한 하위 호환성을 갖지 못하고, 기존 관행에서 더 크게 벗어나며, 버전이 다른 휠 간에 라이선스 설치 위치가 더 일관되지 않게 됩니다. 마지막으로, 이 방식을 따르면 라이선스가 관련 코드 가까이에 설치되지 않고, 플랫폼 간 그리고 빌드된 배포판과 설치된 프로젝트 간에 라이선스 루트 경로의 편차가 더 커지며, 설치된 라이선스에 프로그래밍 방식으로 접근하기가 더 어려워지고, 이름 충돌을 피할 수 있는 적절한 설치 위치와 방법을 새로 만들어야 합니다.
따라서 PEP 639의 범위를 적절히 유지하기 위해 현재 방식을 그대로 두었습니다.
하위 디렉터리 이름을 license_files로 지정
휠과 설치된 프로젝트의 .dist-info 안에 두는 루트 라이선스 디렉터리의 이름 후보로 licenses와 license_files가 모두 제안되었습니다. PEP의 초기 초안은 약간 더 명확하고 코어 메타데이터 필드 이름(License-File) 및 [project] 테이블 키(license-files)와 일관된다는 이유로 전자를 명세했습니다. 그러나 현재 버전의 PEP는 길이가 더 짧고 구분자 문자가 없다는 점에 대한 커뮤니티의 전반적인 선호에 따라 licenses 이름을 채택합니다.
기타 아이디어
최종적으로 채택되지 않은 여러 제안, 가능성 및 논의 사항입니다.
식별자를 라이선스 파일에 매핑
이렇게 하려면 매핑을 사용해야 하며, 이는 라이선스를 문서화하는 방식을 더 복잡하게 만들고 중첩 수준을 하나 더 추가합니다.
모든 표현식(키)에 연결된 라이선스 파일이 하나뿐이라고 보장할 수 없고(예: 예외가 있는 GPL은 하나의 파일에 들어 있을 수 있습니다), 어떤 표현식에도 둘 이상의 파일이 연결되지 않는다고 보장할 수도 없으므로 매핑이 필요합니다. (예를 들어 Apache 라이선스 LICENSE와 그 NOTICE 파일은 서로 다른 두 파일입니다). 가장 일반적인 경우에는 하나의 라이선스 표현식과 하나 이상의 라이선스 파일로 충분합니다. 많은 라이선스가 관련된 더 드물고 복잡한 경우에도 작성자는 여기서 지정한 필드를 안전하게 사용할 수 있습니다. 어떤 텍스트 파일이 어떤 라이선스 식별자에 대응하는지 지정하지 않으므로 명확성이 약간 떨어질 뿐이며(각 라이선스 식별자에는 SPDX에 등록된 전체 라이선스 텍스트가 있기는 합니다), 이를 필요로 하지 않거나 원하지 않는 대다수 사용자에게 더 복잡한 매핑을 강요하지 않습니다.
물론 여러 가지 타입의 값을 가질 수 있는 데이터 필드를 둘 수도 있지만, 이는 혼란의 원인이 될 수 있습니다. 예를 들어 npm(과거)과 Rubygems(현재까지)에서 이렇게 했으며, 그 결과 도구는 코드에서 메타데이터 필드를 사용하기 전에 그 타입을 검사해야 하고, 사용자는 언제 리스트를 쓰고 언제 문자열을 써야 하는지 혼란스러워합니다. 따라서 이 방식은 기각되었습니다.
식별자를 소스 파일에 매핑
앞서 논의한 바와 같이 파일 수준 고지는 PEP 639의 범위를 벗어나며, 필요한 경우 여기서 별도로 명세하지 않아도 기존 SPDX-License-Identifier 관례를 이미 사용할 수 있습니다.
특정 SPDX 버전과의 호환성을 고정하지 않기
PEP 639에서 특정 SPDX 명세 버전이나 유효한 라이선스 식별자 목록의 버전을 지정하지 않을 수도 있었으며, 그러면 명세가 발전함에 따라 더 유연하게 갱신할 수 있습니다.
그러나 향후 SPDX 갱신이 기존 표현식 및 식별자와의 호환성을 깨뜨려, 현재 패키지들이 PEP 639의 정의에 따르면 유효하지 않은 메타데이터를 갖게 될 수 있다는 심각한 우려가 제기되었습니다. 여기서 이러한 명세의 특정 버전과의 호환성을 요구하고, 이를 갱신하려면 PEP 또는 이와 유사한 절차를 거치도록 하면 이러한 사태를 피할 수 있으며, 다른 패키징 생태계의 관행도 따르게 됩니다.
따라서 최소 버전을 지정하고 도구가 이 버전과 호환되도록 요구하되, 하위 호환성을 깨뜨리지 않는 한 갱신은 계속 허용하기로 결정했습니다. 이렇게 하면 도구가 개선 사항을 즉시 활용하고 새 라이선스를 받아들일 수 있어, 유연성과 호환성 사이의 균형을 맞출 수 있습니다.
사용자 정의 라이선스 식별자를 허용하지 않기
이 PEP의 이전 초안은 프로젝트에 라이선스가 있지만 그에 해당하는 인정된 SPDX 라이선스 식별자가 없는 경우를 처리하기 위해 LicenseRef-Public-Domain과 LicenseRef-Proprietary 두 가지 사용자 정의 식별자만 사용할 수 있도록 지정했습니다. 사용자 정의 식별자는 올바른지 검사할 수 없으며, 사용자는 식별자 앞에 항상 LicenseRef를 붙여야 한다고 생각할 수 있습니다. 이는 도구가 유효하지 않은 메타데이터를 생성하는 결과로 이어질 것입니다.
그러나 Python 패키지는 다양한 개방형 및 폐쇄형 환경에서 만들어지며, 그러한 환경에서는 허용된 소수의 사용자 정의 식별자만으로 라이선스를 선언하는 것이 불가능할 수 있고, 여러 이유로 해당 라이선스를 SPDX 라이선스 목록에 추가하는 것도 불가능할 수 있습니다.
사용자 정의 라이선스 식별자는 공식 SPDX 명세에서 명시적으로 허용되고 설명되어 있으며, 대소문자 정규화는 되지 않지만 구문적으로 검증할 수 있습니다.
따라서 사용자 정의 식별자는 완전히 검증될 수 없고 오류를 포함할 수 있다는 점을 인정하며(감사의 글), 공식 SPDX 명세에 따라 이를 허용하기로 결정했습니다.
소스 배포와 바이너리 배포에 서로 다른 라이선스 적용
추가 사용 사례로, 바이너리 배포(wheel)의 라이선스 표현식이 소스 배포판(sdist)의 라이선스 표현식과 다른 경우를 PEP 639에서 다루는 것이 범위에 포함되는지에 대한 질문이 있었습니다. 예를 들어 프로젝트 자체와는 다른 라이선스로 바이너리를 컴파일하고 번들링하는 순수 Python이 아닌 Python 패키지의 경우가 이에 해당합니다. 예로 언급된 것은 PyTorch로, 여기에는 자유롭게 배포할 수 있지만 오픈 소스는 아닌 Nvidia의 CUDA가 포함되어 있습니다.
그러나 여기에 내재된 복잡성과 이를 처리할 명확한 메커니즘이 없다는 점, 각 wheel마다 고유한 라이선스 정보가 필요하다는 사실, PyPI가 배포 아카이브별로 라이선스 정보를 노출하는 기능을 지원하지 않는다는 점, 그리고 비교적 특수한 사용 사례라는 점을 고려하여 이는 PEP 639의 범위를 벗어나는 것으로 결정되었으며, 충분한 필요성과 관심이 있고 적절한 메커니즘을 찾을 수 있다면 향후 PEP에서 해결하도록 남겨 두었습니다.