부록: Python 및 기타 프로젝트의 라이선스 문서화
초록
라이선스를 문서화하는 데 사용되거나 권장되는 방법은 여러 가지가 있습니다. 이 문서는 Python 및 기타 언어의 라이선스 문서화에 대한 포괄적인 조사 결과를 담고 있습니다.
PEP 639의 권고 사항을 이끌어 낸 이 조사의 핵심 요점은 다음과 같습니다:
- 대부분의 패키지 형식은 단일
License필드를 사용합니다. - 많은 현대 패키지 시스템은 둘 이상의 license identifier를 선택적으로 결합하기 위해 어떤 형태로든 license expression을 사용합니다. SPDX 및 SPDX와 유사한 문법이 가장 널리 사용됩니다.
- 완전한 라이선스 표현식 문법을 사용하는지 여부와 관계없이, SPDX 라이선스 식별자는 어디서나 일반적인 라이선스를 참조하는 사실상의 표준 방식이 되어 가고 있습니다.
- 여러 패키지 형식은 라이선스 표현식과 해당 라이선스 텍스트를 담은 파일의 경로를 모두 문서화하는 것을 지원합니다. 대부분의 자유 및 오픈 소스 소프트웨어 라이선스는 패키지 작성자가 Distribution Package에 라이선스 전문을 포함하도록 요구합니다.
Python의 라이선스 문서화
코어 메타데이터
라이선스를 문서화하는 코어 메타데이터 필드는 서로 겹치는 두 가지가 있습니다. 하나는 License ::로 시작하는 라이선스 Classifier 문자열이고, 다른 하나는 자유 텍스트 형식의 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에서는 원래 소스 위치에, 빌드된 휠에서는.dist-info디렉터리에 추가됩니다). 또는 패키지 작성자가 빌드된 wheel에 포함할 라이선스 파일 경로 목록을 프로젝트setup.cfg의[metadata]섹션에 있는license_files키 아래에 지정하거나,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__라는 이름의 “dunder” 모듈 수준 상수를 사용하여 라이선스를 기재하는 경우도 때때로 있습니다.
이 관례는 다소 구식일 수 있지만, 내장 help() 함수와 표준 pydoc 모듈이 인식합니다. 이 dunder 변수는 모듈의 help() DATA 섹션에 표시됩니다.
다른 프로젝트의 라이선스 기재 방식
Linux 배포판 패키지
참고: 대부분의 경우, 가장 널리 쓰이는 라이선스들의 본문은 공유 문서 디렉터리(예: /usr/share/doc)에 전역적으로 포함되어 있습니다.
- Debian은 기계 판독 가능한 저작권 파일로 패키지 라이선스를 문서화합니다. 데비안은 자체 라이선스 표현식 문법과 일반적인 라이선스의 식별자 목록을 정의하며, 둘 다 SPDX의 것과 밀접하게 관련되어 있습니다.
- Fedora 패키지는 라이선스 텍스트를 포함하는 방법을 규정하며, 방대한 “Good Licenses” 목록에서 고른 적절한 짧은 라이선스 식별자로 채워야 하는 License 필드를 사용합니다. 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이 라이선스 목록을 담는
licensesXML 태그를 정의하며, 각 라이선스에는 이름, URL, 주석, “distribution”(배포) 유형이 있습니다. 이는 필수가 아니며, 각 필드의 내용도 규정되어 있지 않습니다. - JavaScript NPM package.json은 SPDX 라이선스 표현식을 담는 단일 license 필드를 사용하며, 라이선스를 지정하지 않은 경우에는
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은 모든 라이선스 전문을 담은 단일
LICENSE파일을 사용할 것을 권장하며, 각 전문은 하이픈 80개로 이루어진 줄로 구분해야 합니다. - 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파일도 사용합니다.