부록: Python 및 기타 프로젝트의 라이선스 문서화
초록
라이선스를 문서화하는 데 사용되거나 권장되는 방법은 여러 가지입니다. 이 문서는 Python 및 기타 언어에서의 라이선스 문서화에 관한 포괄적인 조사 결과를 담고 있습니다.
PEP 639의 권고사항을 이끌어 낸 이 조사의 핵심 결론은 다음과 같습니다.
- 대부분의 패키지 형식은 단일
License필드를 사용합니다. - 많은 최신 패키지 시스템은 둘 이상의 license expression을 선택적으로 결합하기 위해 어떤 형태로든 license identifier를 사용합니다. SPDX 및 SPDX와 유사한 구문이 현재 가장 널리 사용됩니다.
- 전체 라이선스 표현식 구문을 사용하는지 여부와 관계없이, SPDX 라이선스 식별자는 어디서나 일반적인 라이선스를 참조하는 사실상의 방법이 되어 가고 있습니다.
- 여러 패키지 형식은 라이선스 표현식과 라이선스 텍스트가 들어 있는 해당 파일의 경로를 모두 문서화할 수 있도록 지원합니다. 대부분의 자유 및 오픈 소스 소프트웨어 라이선스는 패키지 작성자가 해당 라이선스의 전체 텍스트를 Distribution Package에 포함하도록 요구합니다.
Python의 라이선스 문서화
핵심 메타데이터
라이선스를 문서화하기 위한 핵심 메타데이터 필드는 서로 중복되는 두 가지가 있습니다. License ::가 앞에 붙은 라이선스 Classifier strings와 field을 자유 텍스트로 사용하는 License입니다.
현재 핵심 메타데이터 License 필드의 문서는 다음과 같습니다.
License
=======
.. versionadded:: 1.0
Text indicating the license covering the distribution where the license
is not a selection from the "License" Trove classifiers. See
:ref:`"Classifier" <metadata-classifier>` below.
This field may also be used to specify a
particular version of a license which is named via the ``Classifier``
field, or to indicate a variation or exception to such a license.
Examples::
License: This software may only be obtained by sending the
author a postcard, and then the user promises not
to redistribute it.
License: GPL version 3, excluding DRM provisions
필드가 두 개이기는 하지만, 더 단순한 라이선스 부여 외의 내용을 전달하기는 때때로 어렵습니다. 예를 들어 일부 분류자는 정밀도가 부족하며(버전이 없는 GPL), 여러 라이선스 분류자가 나열된 경우 두 라이선스가 모두 적용되어야 하는지 아니면 사용자가 둘 중 하나를 선택할 수 있는지가 명확하지 않습니다. 또한 사용 가능한 라이선스 분류자의 목록은 상당히 제한적이며 최신 상태가 아닙니다.
Setuptools 및 Wheel
라이선스 코드 또는 한정자 외에도 라이선스 텍스트 파일은 빌드된 패키지에 암묵적으로 또는 명시적으로 문서화되고 포함되며, 이 역시 혼동을 일으킬 수 있는 원천입니다.
- Setuptools 및 Wheel 프로젝트에서는 라이선스 파일 이름이 여러 일반적인 라이선스 파일 이름 패턴(
LICEN[CS]E*,COPYING*,NOTICE*및AUTHORS*) 중 하나와 일치하면 해당 파일이 배포판에 자동으로 추가됩니다(소스 배포판/sdist에서는 원본 위치에, 빌드된 wheel에서는.dist-info디렉터리에 추가됩니다). 또는 패키지 작성자는 프로젝트의setup.cfg에서[metadata]섹션의license_files키 아래에 빌드된 wheel에 포함할 라이선스 파일 경로 목록을 지정하거나,setuptools.setup()함수의 인자로 지정할 수 있습니다. 현재 Setuptools는 Wheel 프로젝트를 따라 수집된 라이선스 파일을 메타데이터 디렉터리로 평탄화하고 이름이 같은 파일을 덮어쓰며, 라이선스 파일을 최상위.dist-info디렉터리에 직접 저장합니다. 그러나 PEP 639가 승인되는 것을 전제로 두 문제를 모두 해결하려는 바람이 있습니다. - 두 도구 모두 배포판에 추가할 라이선스 파일을 하나만 지정할 수 있는 이전의 단수형
license_file매개변수도 지원합니다. 이 매개변수는 한동안 사용이 중단되었지만 여전히 일부 사용 사례가 있습니다. - 이전 PEP 639 초안이 공개된 후, Setuptools는 이 명세에 설명된 대로 배포 메타데이터에서
License-File에 대한 지원을 추가했습니다. 이에 따라 다른 도구가 결과 메타데이터를 사용하는 경우 특정 패키지에 해당하는 라이선스 파일을 모호함 없이 찾을 수 있습니다.
PyPA 패키징 가이드 및 샘플 프로젝트
PyPA 초급 패키징 튜토리얼과 더 포괄적인 패키징 가이드는 모든 패키지에 라이선스 파일을 포함하는 것이 중요하다고 설명합니다. 두 문서는 공식 PyPA 샘플 프로젝트의 LICENSE.txt를 예로 제시합니다. 이 파일은 PEP 639에서 공식적으로 명시된 기존 관행에 따라 해당 프로젝트의 setup.cfg에서 license_files 키 아래에 명시적으로 나열되어 있습니다.
초급 패키징 튜토리얼과 샘플 프로젝트는 모두 분류자만 사용하여 패키지의 라이선스를 선언하며, License 필드를 포함하거나 언급하지 않습니다. 전체 패키징 가이드는 이 필드를 언급하지만, 프로젝트가 비표준 라이선스를 사용하는 경우가 아니라면 작성자는 대신 라이선스 분류자를 사용해야 한다고 설명합니다(가이드에서는 비표준 라이선스 사용을 권장하지 않습니다).
Python 소스 코드 파일
참고: 소스 코드에서 라이선스를 문서화하는 것은 PEP 639의 범위에 포함되지 않습니다.
주석 및/또는 SPDX-License-Identifier 관례를 사용하는 것 외에도, 라이선스는 Python 코드 파일에서 일반적으로 __license__로 명명되는 “던더” 모듈 수준 상수를 사용하여 때때로 문서화됩니다.
이 관례는 다소 오래된 것일 수 있지만, 내장된 help()함수와 표준 pydoc 모듈에서 인식됩니다. 던더 변수는 모듈에 대한 help() DATA 섹션에 표시됩니다.
다른 프로젝트에서의 라이선스 문서화
Linux 배포 패키지
참고: 대부분의 경우 가장 일반적인 라이선스의 본문은 공유 문서 디렉터리(예: /usr/share/doc)에 전역적으로 포함됩니다.
- Debian은 기계 판독 가능 저작권 파일로 패키지 라이선스를 문서화합니다. Debian은 자체 라이선스 표현식 구문과 일반적인 라이선스의 식별자 목록을 정의하며, 이 둘은 모두 SPDX의 것과 밀접하게 관련되어 있습니다.
- Fedora 패키지는 License Texts를 포함하는 방법을 지정하며, 광범위한 “Good Licenses”목록에서 적절한 짧은 라이선스 식별자를 입력해야 하는 License field를 사용합니다. Fedora는 SPDX 라이선스 표현식 구문을 사용합니다.
- OpenSUSE 패키지는 SPDX 라이선스 ID가 포함된 SPDX 라이선스 표현식과 추가 라이선스 식별자 목록을 사용합니다.
- Gentoo ebuild는
LICENSE변수를 사용합니다. 이 필드는 GLEP-0023및 Gentoo 개발 매뉴얼에 지정되어 있습니다. Gentoo는 허용되는 라이선스 목록과 라이선스 표현식 구문도 정의하며, 이는 SPDX와 상당히 다릅니다. - FreeBSD 패키지 Makefile은 사용자 지정 라이선스 기호 목록이 포함된
LICENSE및LICENSE_FILE필드를 제공합니다. 비표준 라이선스의 경우 FreeBSD는LICENSE=UNKNOWN을 사용하고LICENSE_NAME및LICENSE_TEXT필드를 추가하며, 라이선스 권한을 명시하기 위한 정교한LICENSE_PERMS와 라이선스 그룹을 문서화하기 위한LICENSE_GROUPS도 추가할 것을 권장합니다.LICENSE_COMB를 사용하면 둘 이상의 라이선스와 해당 라이선스가 함께 적용되는 방식을 문서화하여 사용자 지정 라이선스 표현식 구문을 구성할 수 있습니다. FreeBSD는 소스 코드 파일에서SPDX-License-Identifier를 사용하는 것도 권장합니다. - Arch Linux PKGBUILD는 자체 라이선스 식별자를 정의합니다. 라이선스가 정의되지 않은 경우
'unknown'값을 사용할 수 있습니다. - OpenWRT ipk 패키지는
PKG_LICENSE및PKG_LICENSE_FILES변수를 사용하며 SPDX 라이선스 식별자 사용을 권장합니다. - NixOS는 SPDX 식별자와 일부 추가 라이선스 ID를 라이선스 필드에서 사용합니다.
- GNU Guix(NixOS 기반)는 하나의 License 필드를 가지며, 자체 라이선스 기호 목록을 사용하고 하나의 라이선스 또는 라이선스 목록을 사용하는 방법을 지정합니다.
- Alpine Linux 패키지는 라이선스 필드에서 SPDX 식별자를 사용할 것을 권장합니다.
언어 및 애플리케이션 패키지
- Java에서 Maven POM은 각 라이선스의 이름, URL, 주석 및 “distribution” 유형이 포함된 라이선스 목록을
licensesXML 태그로 정의합니다. 이는 필수가 아니며 각 필드의 내용도 지정되어 있지 않습니다. - JavaScript NPM package.json은 SPDX 라이선스 표현식이 포함된 단일 라이선스 필드 또는 지정된 라이선스가 없는 경우
UNLICENSEDID를 사용합니다. 단일license필드에서SEE LICENSE IN <filename>을 사용하여 라이선스 파일을 대안으로 참조할 수 있습니다. - Rubygems gemspec은 단일 라이선스 문자열 또는 라이선스 문자열 목록을 지정합니다. 목록의 여러 라이선스 간 관계는 지정되지 않습니다. SPDX 라이선스 식별자를 사용할 것을 권장합니다.
- CPAN Perl modules은 단일 라이선스 필드를 사용하며, 이 필드는 단일 문자열이거나 문자열 목록입니다. 목록의 라이선스 간 관계는 지정되지 않습니다. 사용자 지정 라이선스 식별자 목록과 함께 다음과 같은 일반 식별자가 있습니다:
open_source,restricted,unrestricted,unknown. - Rust Cargo는
license필드에서 SPDX 라이선스 표현식(v2.1)을 사용하도록 지정합니다. 또한 슬래시로 구분된 SPDX 라이선스 식별자를 사용하는 대체 표현식 구문을 지원하며,license_file필드도 있습니다. crates.io package registry는 패키지를 업로드할 때license또는license_file필드 중 하나가 설정되어 있어야 한다고 요구합니다. - PHP composer.json은 SPDX 라이선스 ID 또는
proprietary가 지정된license필드를 사용합니다.license필드는and및or키워드를 사용하는 SPDX 라이선스 표현식 구문과 유사한 단일 문자열이거나, 라이선스를 (논리합으로) 선택할 수 있는 경우 문자열 목록입니다. - NuGet packages는 이전에는 단순한 라이선스 URL만 사용했지만, 이제 SPDX 라이선스 표현식 및/또는 패키지 내 라이선스 파일의 경로를 지정합니다. NuGet.org 저장소는 “Open Source Initiative 또는 Free Software Foundation에서 승인한” 라이선스 표현식만 허용한다고 명시합니다.
- Go 언어 모듈
go.mod에는 종속성 이외의 메타데이터를 위한 규정이 없습니다. 라이선스 정보는 코드 작성자와 기타 커뮤니티 패키지 관리자에게 문서화하도록 맡깁니다. - Dart/Flutter spec은 모든 라이선스 본문을 포함하고, 각 본문을 하이픈 80개로 이루어진 줄로 구분하는 단일
LICENSE파일을 사용할 것을 권장합니다. - JavaScript Bower의
license필드는 SPDX 라이선스 식별자를 사용하는 단일 문자열 또는 문자열 목록이거나, 라이선스 파일의 경로/URL입니다. - Cocoapods podspec의
license필드는 단일 문자열이거나type,file,text키를 포함하는 매핑입니다.LICENSE/LICENCE파일이 제공되지 않는 한 이는 필수입니다. - Haskell Cabal은 버전 2.2부터 SPDX 라이선스 표현식을 허용합니다. 사용되는 SPDX 라이선스 목록의 버전은 Cabal 버전에 따라 결정됩니다. 이 사양은 레거시(SPDX 이전) 라이선스 식별자와 SPDX 라이선스 식별자 간 매핑도 제공합니다. Cabal은 패키지와 함께 설치할 라이선스 파일을 나열하는
license-file(s)필드도 지정합니다. - Erlang/Elixir mix/hex package는 라이선스 문자열의 필수 목록인
licenses필드를 지정하며, SPDX 라이선스 식별자를 사용할 것을 권장합니다. - D Langanguage dub packages는 SPDX 표준과 유사한 자체 라이선스 식별자 목록과 라이선스 표현식 구문을 정의합니다.
- R Package DESCRIPTION은 자체적인 정교한 라이선스 표현식 구문과 라이선스 식별자 목록을 정의합니다. R은 라이선스 표현식 구문에서 라이선스 버전에 대한 지정자(예:
LGPL (>= 2.0, < 3))를 지원하는 독특한 방식을 제공합니다.
기타 생태계
SPDX-License-Identifierheader는 파일 내부에 라이선스를 문서화하기 위한 간단한 규칙입니다.- Free Software Foundation (FSF)는 GPL 및 기타 버전이 지정된 자유 소프트웨어 라이선스를 명확하게 표시하기 위해 SPDX 라이선스 식별자를 사용할 것을 장려합니다.
- Free Software Foundation Europe (FSFE)의 REUSE project는
SPDX-License-Identifier사용을 장려합니다. - Linux kernel은 라이선스를 문서화하기 위해
SPDX-License-Identifier와 FSFE REUSE 규칙의 일부를 사용합니다. - U-Boot는 코드에서
SPDX-License-Identifier를 사용하는 것을 선도했고, 현재는 Linux 방식을 따르고 있습니다. - Apache Software Foundation 프로젝트들은 SPDX 라이선스 식별자를 가리키는 단일 라이선스 필드와 함께 RDF DOAP를 사용합니다.
- Eclipse Foundation은
SPDX-license-Identifiers를 사용할 것을 권장합니다. - ClearlyDefined project는 라이선스 명확성을 개선하기 위해 SPDX 라이선스 식별자와 표현식을 사용할 것을 권장합니다.
- Android Open Source Project는
MODULE_LICENSE_XXX빈 태그 파일을 사용하며, 여기서XXX는BSD,APACHE,GPL등의 라이선스 코드입니다. 또한 라이선스 및 고지 텍스트를 담은NOTICE파일도 사용합니다.