Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python 增强提案

附录:Python 及其他项目中的许可证文档

摘要

有多种用于或推荐的许可证文档方式。本文档包含了对 Python 和其他语言中许可证文档的全面调查结果。

调查的主要结论,指导了 PEP 639 的建议,如下所示

  • 大多数包格式使用单个 License 字段。
  • 许多现代包系统使用某种形式的 许可证表达式 来选择性地组合多个 许可证标识符。SPDX 和类似 SPDX 的语法是最常用的。
  • SPDX 许可证标识符正在成为事实上的参考常用许可证的方式,无论是否使用完整的许可证表达式语法。
  • 一些包格式支持同时记录许可证表达式和包含许可证文本的相应文件的路径。大多数自由和开源软件许可证要求包作者在其 发行版包 中包含其完整文本。

Python 中的许可证文档

核心元数据

有两个重叠的核心元数据字段用于记录许可证:许可证 Classifier 字符串,以 License :: 为前缀,以及 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

除了许可证代码或限定符之外,许可证文本文件在构建的包中被隐式或显式地记录和包含,这也是另一个可能造成混淆的来源

  • SetuptoolsWheel 项目中,如果许可证文件与许多常见许可证文件名模式之一匹配(LICEN[CS]E*COPYING*NOTICE*AUTHORS*),则会自动将其添加到发行版中(在源发行版/sdist 中的源位置,以及构建的 wheel 的 .dist-info 目录中)。或者,包作者可以指定要包含在构建的 wheel 中的许可证文件路径列表,方法是在项目的 setup.cfg 文件的 [metadata] 部分的 license_files 键下指定,或作为 setuptools.setup() 函数的参数。目前,遵循 Wheel 项目的领导,Setuptools 将收集到的许可证文件展平到元数据目录中,覆盖同名的文件,并将许可证文件直接转储到顶级 .dist-info 目录中,但有一个 希望解决这两个问题,这取决于 PEP 639 是否被接受。
  • 这两个工具还支持一个较旧的、单一的 license_file 参数,该参数允许仅指定一个要添加到发行版的许可证文件,该参数已弃用一段时间,但仍然 有一些用途
  • 在发布 PEP 639 的早期草案后,Setuptools 添加了对 License-File 的支持,该字段在发行版元数据中进行了描述,如本规范所述。这允许其他使用结果元数据的工具明确地找到给定包的许可证文件。

PyPA 打包指南和示例项目

PyPA 的 打包初学者教程 及其更全面的 打包指南 都指出,每个包都包含许可证文件非常重要。它们将 PyPA 官方示例项目中的 LICENSE.txt 作为示例,该文件在 setup.cfg 文件中的 license_files 键下 明确列出,遵循 PEP 639 正式指定的现有实践。

打包初学者教程和 示例项目 都只使用分类器来声明包的许可证,并且不包含或提及 License 字段。完整的 打包指南 确实提到了此字段,但指出作者应该使用许可证分类器,除非项目使用非标准许可证(指南不鼓励这样做)。

Python 源代码文件

注意:PEP 639 不在记录源代码中的许可证范围内。

除了使用注释和/或 SPDX-License-Identifier 约定之外,许可证有时还使用 Python 代码文件中的“dunder”模块级常量(通常命名为 __license__)进行记录 有时

此约定虽然可能有些过时,但被内置的 help() 函数和标准的 pydoc 模块识别。dunder 变量将显示在模块的 help() DATA 部分中。

其他项目中的许可证文档

Linux 发行版包

注意:在大多数情况下,最常见许可证的文本在共享文档目录(例如 /usr/share/doc)中全局包含。

  • Debian 使用 机器可读版权文件 记录包许可证。它定义了自己的许可证表达式语法和常用许可证的标识符列表,这两者都与 SPDX 密切相关。
  • Fedora 包 指定如何包含 许可证文本,并使用 许可证字段,该字段必须填写来自广泛的 “良好许可证” 列表的适当的简短许可证标识符。Fedora 使用 SPDX 许可证表达式语法。
  • OpenSUSE 包 使用带有 SPDX 许可证 ID 的 SPDX 许可证表达式和 其他许可证标识符列表
  • Gentoo ebuild 使用 LICENSE 变量。此字段在 GLEP-0023Gentoo 开发手册 中指定。Gentoo 还定义了允许的许可证列表和许可证表达式语法,该语法与 SPDX 差异很大。
  • FreeBSD 包 Makefile 提供了 LICENSELICENSE_FILE 字段,其中包含自定义许可证符号列表。对于非标准许可证,FreeBSD 建议使用 LICENSE=UNKNOWN 并添加 LICENSE_NAMELICENSE_TEXT 字段,以及复杂的 LICENSE_PERMS 来限定许可证权限和 LICENSE_GROUPS 来记录许可证分组。 LICENSE_COMB 允许记录多个许可证以及它们如何一起应用,从而形成自定义许可证表达式语法。FreeBSD 还建议在源代码文件中使用 SPDX-License-Identifier
  • Arch Linux PKGBUILD 定义了自己的 许可证标识符。如果未定义许可证,可以使用值 'unknown'
  • OpenWRT ipk 包 使用 PKG_LICENSEPKG_LICENSE_FILES 变量,并建议使用 SPDX 许可证标识符。
  • NixOS 使用 SPDX 标识符 及其许可证字段中的一些额外许可证 ID。
  • GNU Guix(基于 NixOS)具有单个许可证字段,使用其自己的 许可证符号列表 并指定如何使用一个许可证或 它们的列表
  • Alpine Linux 包 建议在许可证字段中使用 SPDX 标识符。

语言和应用程序包

  • 在 Java 中,Maven POM 定义了一个 licenses XML 标签,其中包含许可证列表,每个许可证都有名称、URL、注释和“分发”类型。这不是强制性的,并且每个字段的内容未指定。
  • JavaScript NPM package.json 使用单个许可证字段,其中包含 SPDX 许可证表达式,或者如果未指定任何许可证,则使用 UNLICENSED ID。可以使用 SEE LICENSE IN <filename> 在单个 license 字段中引用许可证文件作为替代。
  • Rubygems gemspec 指定单个或许可证字符串列表。列表中多个许可证之间的关系未指定。他们建议使用 SPDX 许可证标识符。
  • CPAN Perl 模块 使用单个 license 字段,该字段可以是单个字符串或字符串列表。列表中许可证之间的关系未指定。除了以下通用标识符外,还提供了一系列自定义许可证标识符:open_sourcerestrictedunrestrictedunknown
  • Rust Cargo 指定在 license 字段中使用 SPDX 许可证表达式 (v2.1)。它还支持使用斜杠分隔的 SPDX 许可证标识符的替代表达式语法,并且还有一个 license_file 字段。 crates.io 包注册表 要求在上传包时设置 licenselicense_file 字段。
  • PHP composer.json 使用 license 字段,该字段包含 SPDX 许可证 ID 或 proprietarylicense 字段可以是单个字符串,类似于 SPDX 许可证表达式语法,使用 andor 关键字;或者如果有多个(析取)许可证选择,则为字符串列表。
  • NuGet 包 以前仅使用简单的许可证 URL,但现在指定使用 SPDX 许可证表达式和/或包中许可证文件的路径。NuGet.org 存储库声明它们仅接受“开源计划或自由软件基金会批准”的许可证表达式。
  • Go 语言模块 go.mod 没有为除依赖项之外的任何元数据提供规定。许可证信息留给代码作者和其他社区包管理器来记录。
  • Dart/Flutter 规范 建议使用单个 LICENSE 文件,该文件应包含所有许可证文本,每个文本之间用 80 个连字符分隔的行分隔。
  • JavaScript Bower license 字段可以是单个字符串或字符串列表,使用 SPDX 许可证标识符或指向许可证文件的路径/URL。
  • Cocoapods podspec license 字段可以是单个字符串,也可以是包含 typefiletext 键的映射。除非提供了 LICENSE/LICENCE 文件,否则此字段是必需的。
  • Haskell Cabal 从 2.2 版开始接受 SPDX 许可证表达式。使用的 SPDX 许可证列表的版本是 Cabal 版本的函数。规范还提供了传统(SPDX 之前)和 SPDX 许可证标识符之间的映射。Cabal 还指定了一个 license-file(s) 字段,该字段列出要与包一起安装的许可证文件。
  • Erlang/Elixir mix/hex 包licenses 字段指定为许可证字符串的必需列表,并建议使用 SPDX 许可证标识符。
  • D 语言 dub 包 定义了自己的许可证标识符列表和许可证表达式语法,类似于 SPDX 标准。
  • R 包 DESCRIPTION 定义了自己的复杂许可证表达式语法和许可证标识符列表。R 有一种独特的方式来支持其许可证表达式语法中的许可证版本说明符(例如 LGPL (>= 2.0, < 3))。

其他生态系统

  • SPDX-License-Identifier 标头 是一种简单的约定,用于记录文件内的许可证。
  • 自由软件基金会 (FSF) 推广使用 SPDX 许可证标识符,以提高 GPL 和其他版本化的自由软件许可证的清晰度。
  • 欧洲自由软件基金会 (FSFE) REUSE 项目 推广使用 SPDX-License-Identifier
  • Linux 内核 使用 SPDX-License-Identifier 和 FSFE REUSE 约定的部分内容来记录其许可证。
  • U-Boot 带头在代码中使用 SPDX-License-Identifier,现在遵循 Linux 的方法。
  • Apache 软件基金会的项目使用 RDF DOAP,其中单个 license 字段指向 SPDX 许可证标识符。
  • Eclipse 基金会 推广使用 SPDX-license-Identifiers
  • ClearlyDefined 项目 推广使用 SPDX 许可证标识符和表达式,以提高许可证的清晰度。
  • Android 开源项目 使用 MODULE_LICENSE_XXX 空标签文件,其中 XXX 是许可证代码,例如 BSDAPACHEGPL 等。它还使用 NOTICE 文件,其中包含许可证和通知文本。