diff --git a/pep-0639.rst b/pep-0639.rst index d229cd3e9c0..32fe94696e4 100644 --- a/pep-0639.rst +++ b/pep-0639.rst @@ -19,8 +19,9 @@ Abstract ======== This PEP defines a specification for how licenses are documented in the -core metadata via a new ``License-Expression`` field, with license expression -strings using SPDX identifiers [#spdxlist]_. +`core metadata <#coremetadataspec_>`_ via a new ``License-Expression`` field, +with `license expression strings `_ using +`SPDX identifiers <#spdxid_>`_. This will make license declarations simpler and less ambiguous for: @@ -30,21 +31,35 @@ This will make license declarations simpler and less ambiguous for: The PEP also: -- Formally specifies a new ``License-File`` field and how license files - should be included in distributions, as already used by Wheel and Setuptools. +- `Formally specifies `_ a new ``License-File`` field + and how license files should be + `included in distributions `_, + as already used by Wheel and Setuptools. -- Deprecates the legacy ``License`` field and ``license ::`` classifiers. +- `Deprecates `_ the legacy ``License`` field + and ``license ::`` classifiers. -- Provides clear guidance for authors and tools converting legacy license - metadata, adding license files and validating license expressions. +- `Adds and deprecates `_ corresponding keys in the + PEP 621 project source metadata format. -- Adds and deprecates corresponding keys in the PEP 621 - project source metadata format. +- `Provides clear guidance `_ for authors and + tools converting legacy license metadata, adding license files and + validating license expressions. -The changes in this PEP will update the core metadata to version 2.3, -modify the PEP 621 project metadata specification, and make minor additions to -the source distribution (sdist), built distribution (wheel) and installed -project standards. +- Discusses `user scenarios `_, + describes a `reference implementation `_, + analyzes numerous `potential alternatives `_, + includes `detailed examples `_ and + surveys license documentation + `in Python packaging `_ and + `other ecosystems `_. + +The changes in this PEP will update the +`core metadata <#coremetadataspec_>`_ to version 2.3, modify the +`PEP 621 project metadata specification <#pep621spec_>`_, +and make minor additions to the `source distribution (sdist) <#sdistspec_>`_, +`built distribution (wheel) <#wheelspec_>`_ and +`installed project <#installedspec_>`_ standards. Goals @@ -60,26 +75,15 @@ The changes to the core metadata specification that this PEP requires have been designed to minimize impact and maximize backward compatibility. This specification builds off of existing ways to document licenses that are already in use in popular tools (e.g. adding support to core metadata for -the ``License-File`` field already used in Wheel and Setuptools) -and by some package authors (e.g. storing an SPDX license expression -in the existing ``License`` field). - -In addition to these proposed changes, this PEP contains: - -- Recommendations for publishing tools on how to validate the new - ``License-Expression`` field, add license files to distributions, and and - warn on and convert legacy metadata - (the ``License`` field and license classifiers). - -- Simplified guidance for package authors on how to handle license files - and expressions for various common situations. +the ``License-File`` field `already used `_ in +Wheel and Setuptools) and by some package authors (e.g. storing an +SPDX license expression in the existing ``License`` field). -- A detailed summary of related proposed ideas and alternate approaches, and - why they were or were not incorporated into the current version of this PEP - -- Informational appendices that contain surveys of how we document licenses - today in Python packages and elsewhere, and a reference Python library to - parse, validate and build correct license expressions. +In addition to these proposed changes, this PEP contains guidance for tools +handling and converting these metadata, a tutorial for package authors +covering various common use cases, detailed examples of them in use, +and a comprehensive survey of license documentation in Python and other +languages. It is the intent of the PEP authors to work closely with tool maintainers to implement the recommendations for validation and warnings specified here. @@ -106,9 +110,10 @@ to use a new formally-specified and supported mechanism, and provide guidance for packaging tools on how to hand the transition and inform users accordingly. This PEP is not about license documentation in files inside projects, -though this is a surveyed topic in the appendix, and nor does it currently -intend to cover cases where the source and binary distribution packages -have different licenses. +though this is a `surveyed topic `_ in the appendix, +and nor does it intend to cover cases where the source and +binary distribution packages don't have +`the same licenses `_ Possible future PEPs @@ -118,7 +123,7 @@ It is the intention of the authors of this PEP to consider the submission of related but separate PEPs in the future, which may include: - Removing the deprecated ``License`` field and license classifiers - from the Core Metadata specification. + from the core metadata specification. - Making the ``License-Expression`` and ``License-File`` fields mandatory for publishing tools and PyPI packages. @@ -139,28 +144,31 @@ for package authors and users. Several package authors have expressed difficulty and/or frustrations due to the limited capabilities to express licensing in project metadata. This also applies to Linux and BSD distribution packagers. This has triggered several -license-related discussions and issues, in particular: - -- https://github.com/pypa/trove-classifiers/issues/17 -- https://github.com/pypa/interoperability-peps/issues/46 -- https://github.com/pypa/packaging-problems/issues/41 -- https://github.com/pypa/wheel/issues/138 -- https://github.com/pombredanne/spdx-pypi-pep/issues/1 +license-related discussions and issues, including on +`outdated and ambiguous PyPI classifiers <#classifierissue_>`_, +`license interoperability with other ecosystems <#interopissue_>`_, +`too many confusing/limited license metadata options <#packagingissue_>`_, +`limited Wheel support for license files <#wheelfiles_>`_, and +`the lack of clear, precise and standardized license metadata <#pepissue_>`_. On average, Python packages tend to have more ambiguous, or missing, license information than other common application package formats (such as npm, Maven or -Gem) as can be seen in the statistics [#cdstats]_ page of the ClearlyDefined -[#cd]_ project that cover all packages from PyPI, Maven, npm and Rubygems. -ClearlyDefined is an open source project to help improve clarity of other open -source projects that is incubating at the OSI (Open Source Initiative) [#osi]_. +Gem) as can be seen in the `statistics page <#cdstats_>`_ of the +`ClearlyDefined project <#clearlydefined_>`_ that cover all packages from +PyPI, Maven, npm and Rubygems. ClearlyDefined is an open source project +to help improve clarity of other open source projects that is incubating at +the `Open Source Initiative <#osi_>`_. Rationale ========= -A mini-survey of existing license metadata definitions in use in the Python -ecosystem today and documented in several other system/distro and application -package formats is provided in Appendix 2 of this PEP. +A survey of existing license metadata definitions in use in the Python +ecosystem today is provided in +`Appendix 2 `_ of this PEP, +and license documentation in a variety of other packaging systems, +Linux distros, languages ecosystems and applications is surveyed in +`Appendix 3 `_. There are a few takeaways from the survey: @@ -236,11 +244,11 @@ This PEP seeks to clearly define the terms it uses, specifically those that: - Are new concepts introduced here (license expression/identifier). -Whenever available, definitions are excepted from the PyPA PyPUG Glossary -[#pypugglossary]_ and SPDX [#spdx]_. Terms are listed here in their full -versions; related words (``Rel:``) are in parenthesis, including short forms -(``Short:``), sub-terms (``Sub:``) and common synonyms for the purposes of -this PEP (``Syn:``). +Whenever available, definitions are excepted from the +`PyPA PyPUG Glossary <#pypugglossary_>`_ and `SPDX <#spdx_>`_. Terms are listed +here in their full versions; related words (``Rel:``) are in parenthesis, +including short forms (``Short:``), sub-terms (``Sub:``) and common synonyms +for the purposes of this PEP (``Syn:``). **Built Distribution** *(Syn: Binary Distribution/Wheel)* A Distribution format containing files and metadata that only need to be @@ -254,12 +262,12 @@ this PEP (``Syn:``). and **wheel** (the format). **Core Metadata** *(Syn: Package Metadata, Sub: Distribution Metadata)* - The PyPA specification [#cms]_ and the set of metadata fields it defines that - describe key static attributes of distribution packages and installed - projects. + The `PyPA specification <#coremetadataspec_>`_ and the set of metadata fields + it defines that describe key static attributes of distribution packages + and installed projects. **Distribution metadata** refers to, more specifically, the concrete form - core metadata takes when included inside a distribution package + core metadata takes when included inside a distribution archive (``PKG-INFO`` in a sdist and ``METADATA`` in a wheel) or installed project (``METADATA``). @@ -278,18 +286,18 @@ this PEP (``Syn:``). specifically references the physical **distribution archive**. **License Classifier** - A PyPI Trove classifier [#classif]_ as originally defined in PEP 301 which - begins with ``License ::``, currently used to indicate a project's + A `PyPI Trove classifier <#classifiers_>`_ (as originally defined in PEP 301) + which begins with ``License ::``, currently used to indicate a project's license status by including it as a ``Classifer`` in the core metadata. **License Expression** *(Syn: SPDX Expression)* - A string with valid SPDX license expression syntax [#spdxpression]_ + A string with valid `SPDX license expression syntax <#spdxpression_>`_ including any SPDX license identifiers as defined here, which describes a project's license(s) and how they related to one another. Examples: ``GPL-3.0-or-later``, ``MIT AND (Apache-2.0 OR BSD-2-clause)`` **License Identifier** *(Syn: License ID/SPDX Identifier)* - A valid SPDX short-form license identifier [#spdxid]_, as described in the + A valid `SPDX short-form license identifier <#spdxid_>`_, as described in the `Add License-Expression field`_ section of this PEP; briefly, this includes all valid SPDX identifiers and the ``LicenseRef-Public-Domain`` and ``LicenseRef-Proprietary`` strings. Examples: ``MIT``, ``GPL-3.0-only`` @@ -304,8 +312,8 @@ this PEP (``Syn:``). Here, a **project source tree** refers to the on-disk format of a project used for development, while an **installed project** is the form a - project takes once installed from a distribution, as specified by PyPA - [#installedspec]_. + project takes once installed from a distribution, as + `specified by PyPA <#installedspec_>`_. **Project Source Metadata** *(Sub: PEP 621 Metadata, Key, Subkey)* Core metadata defined by the package author in the project source tree, @@ -314,15 +322,15 @@ this PEP (``Syn:``). build tools. **PEP 621 metadata** refers specifically to the former, as defined by the - PyPA Declaring Project Metadata specification [#projectspec]_. + `PyPA Declaring Project Metadata specification <#pep621spec_>`_. A **PEP 621 metadata key**, or an unqualified *key* refers specifically to a top-level ``[project]`` key (notably, *not* a core metadata *field*), while a **subkey** refers to a second-level key in a table-valued PEP 621 key. **Source Distribution** *(Short: sdist)* - Here, specifically refers to a source distribution (**sdist**) as specified - by PyPA [#sdistspec]_. + Here, specifically refers to a source distribution (**sdist**) as + `specified by PyPA <#sdistspec_>`_. **Tool** *(Sub: Packaging Tool, Build Tool, Install Tool, Publishing Tool)* A program, script or service executed by the user or automatically that @@ -346,34 +354,42 @@ this PEP (``Syn:``). **Wheel Format** *(Short: wheel, Rel: Wheel project)* Here, **wheel**, the standard built distribution format introduced in PEP 427 - and specified by PyPA [#wheelspec]_, will be referred to in lowercase, - while the **Wheel project** [#wheelproject]_, its reference implementation, - which will be referred to as "Wheel" in Title Case. + and `specified by PyPA <#wheelspec_>`_, will be referred to in lowercase, + while the `Wheel project <#wheelproject_>`_, its reference implementation, + which will be referred to as **Wheel** in Title Case. Specification ============= The changes necessary to implement the improved license handling outlined in -this PEP include those in both author-provided project source metadata, as -specified in PEP 621, and distribution package metadata, as defined in the core -metadata specification [#cms]_. Furthermore, requirements are needed for -tools handling and converting legacy license metadata to license expressions, -to ensure the results are consistent, correct and unambiguous. Finally, minor -additions to the source distribution (sdist), built distribution (wheel) -and installed project specifications will help document and clarify the -already allowed, now formally standardized behavior in these respects. +this PEP include those in both +`distribution package metadata `_, as defined in the +`core metadata specification <#coremetadataspec_>`_, and +`author-provided project source metadata `_, as +originally defined in PEP 621. + +Further, `minor additions `_ to the +source distribution (sdist), built distribution (wheel) and installed project +specifications will help document and clarify the already allowed, +now formally standardized behavior in these respects. +Finally, `guidance is established `_ +for tools handling and converting legacy license metadata to license +expressions, to ensure the results are consistent, correct and unambiguous. Core metadata ------------- -The PyPA Core Metadata specification [#cms]_ defines the names and -semantics of each of the supported fields in the distribution metadata of +The `PyPA Core Metadata specification <#coremetadataspec_>`_ defines the names +and semantics of each of the supported fields in the distribution metadata of Python distribution packages and installed projects. -This PEP adds the ``License-Expression`` and ``License-File`` fields, -deprecates the ``License`` field, and deprecates the license classifiers +This PEP `adds `_ the +``License-Expression`` field, +`adds `_ the ``License-File`` field, +`deprecates `_ the ``License`` field, +and `deprecates `_ the license classifiers in the ``Classifier`` field. The error and warning guidance in this section applies to build and @@ -388,24 +404,24 @@ Add ``License-Expression`` field '''''''''''''''''''''''''''''''' The ``License-Expression`` optional field is specified to contain a text string -that is a valid SPDX license expression, defined below. +that is a valid SPDX license expression, as defined herein. Publishing tools SHOULD issue an informational warning if this field is missing, and MAY raise an error. Build tools MAY issue a similar warning, but MUST NOT raise an error. A license expression is a string using the SPDX license expression syntax as -documented in the SPDX specification [#spdxpression]_ using either Version 2.2 -or a later compatible version. +documented in the `SPDX specification <#spdxpression_>`_ using either +Version 2.2 or a later compatible version. When used in the ``License-Expression`` field and as a specialization of the SPDX license expression definition, a license expression can use the following license identifiers: -- Any SPDX-listed license short-form identifiers that are published in the SPDX - License List [#spdxlist]_, version 3.15 or any later compatible version. - Note that the SPDX working group never removes any license identifiers; - instead, they may choose to mark an identifier as "deprecated". +- Any SPDX-listed license short-form identifiers that are published in the + `SPDX License List <#spdxlist_>`_, version 3.15 or any later compatible + version. Note that the SPDX working group never removes any license + identifiers; instead, they may choose to mark an identifier as "deprecated". - The ``LicenseRef-Public-Domain`` and ``LicenseRef-Proprietary`` strings to identify licenses that are not included in the SPDX license list. @@ -421,7 +437,7 @@ a valid license expression, build and publishing tools: - SHOULD report an informational warning, and publishing tools MAY raise an error if one or more license identifiers have been marked as deprecated in - the SPDX License List [#spdxlist]_. + the `SPDX License List <#spdxlist_>`_. - MUST store a case-normalized version of the ``License-Expression`` field using the reference case for each SPDX license identifier and @@ -432,11 +448,12 @@ a valid license expression, build and publishing tools: ``License-Expression`` field contents. For all newly-upload distributions that include a -``License-Expression`` field, the Python Package Index (PyPI) [#pypi]_ MUST +``License-Expression`` field, the `Python Package Index (PyPI) <#pypi_>`_ MUST validate that it contains a valid, case-normalized license expression with -valid identifiers (as defined above) and MUST reject uploads that do not +valid identifiers (as defined here) and MUST reject uploads that do not validate. PyPI MAY reject an upload for using a deprecated license identifier, -so long as it was deprecated as of the above SPDX License List version. +so long as it was deprecated as of the above-mentioned SPDX License List +version. Add ``License-File`` field @@ -455,7 +472,7 @@ metadata, that file MUST be included in the distribution at the specified path relative to the root license directory, and MUST be installed with the distribution at that same relative path. -The root license directory is defined to be the project root directory +The **root license directory** is defined to be the project root directory for source trees and source distributions, and the ``license_files`` subdirectory of the directory containing the core metadata (i.e. the ``.dist-info`` directory containing the ``METADATA`` file), for built @@ -496,9 +513,10 @@ informing users it is deprecated and recommending ``License-Expression`` instead. For all newly-uploaded distributions that include a -``License-Expression`` field, the Python Package Index (PyPI) [#pypi]_ MUST +``License-Expression`` field, the `Python Package Index (PyPI) <#pypi_>`_ MUST reject any that specify a ``License`` field and the text of which is not -identical to that of ``License-Expression``, as defined above. +identical to that of ``License-Expression``, as +`defined above `_. Along with license classifiers, the ``License`` field may be removed from a new version of the specification in a future PEP. @@ -507,13 +525,13 @@ new version of the specification in a future PEP. Deprecate license classifiers ''''''''''''''''''''''''''''' -Including license classifiers [#classif]_ in the ``Classifier`` field +Including license `classifiers <#classifiers_>`_ in the ``Classifier`` field (described in PEP 301) is deprecated and replaced by the more precise ``License-Expression`` field. If the ``License-Expression`` field is present, build tools SHOULD and publishing tools MUST raise an error if one or more license classifiers -(as defined above) is included in a ``Classifier`` field, and MUST NOT add +is included in a ``Classifier`` field, and MUST NOT add such classifiers themselves. Otherwise, if this field contains a license classifier, build tools MAY @@ -524,10 +542,10 @@ the presence of license classifiers SHOULD NOT raise an error unless ``License-Expression`` is also provided. For all newly-uploaded distributions that include a -``License-Expression`` field, the Python Package Index (PyPI) [#pypi]_ MUST +``License-Expression`` field, the `Python Package Index (PyPI) <#pypi_>`_ MUST reject any that also specify any license classifiers. -New license classifiers MUST NOT be added to PyPI [#classifersrepo]_; +New license classifiers MUST NOT be `added to PyPI <#classifiersrepo_>`_; users needing them SHOULD use the ``License-Expression`` field instead. Along with the ``License`` field, license classifiers may be removed from a new version of the specification in a future PEP. @@ -536,13 +554,15 @@ new version of the specification in a future PEP. Project source metadata ----------------------- -As originally introduced in PEP 621, the PyPA Declaring Project Metadata -specification [#projectspec]_ defines how to declare a project's source +As originally introduced in PEP 621, the +`PyPA Declaring Project Metadata specification <#pep621spec_>`_ +defines how to declare a project's source metadata in a ``[project]`` table in the ``pyproject.toml`` file for build tools to consume and output distribution core metadata. -This PEP adds the ``license-expression`` and ``license-files`` keys and -deprecates the ``license`` key. +This PEP `adds `_ the ``license-expression``, +`adds `_ the ``license-files`` key and +`deprecates `_ the ``license`` key. Add ``license-expression`` key @@ -552,7 +572,8 @@ A new ``license-expression`` key is added to the ``project`` table, which has a string value that is a valid SPDX license expression, as defined previously. Its value maps to the ``License-Expression`` field in the core metadata. -Build tools SHOULD validate the expression as described above, outputting +Build tools SHOULD validate the expression as described +`above `_, outputting an error or warning as specified. When generating the core metadata, tools MUST perform case normalization. @@ -579,12 +600,13 @@ Its value is a table, which if present MUST contain one of two optional, mutually exclusive subkeys, ``paths`` and ``globs``; both arrays of strings. If both are specified, tools MUST raise an error. The ``paths`` subkey contains verbatim file paths, and the ``globs`` subkey -valid glob patterns, parsable by the ``glob`` module [#globmodule]_ in the +valid glob patterns, parsable by the ``glob`` `module <#globmodule_>`_ in the Python standard library. **Note**: To avoid ambiguity, confusion and (per PEP 20, the Zen of Python) "more than one (obvious) way to do it", a flat array of strings value for the -``license-files`` key has been left out for now. +``license-files`` key has been +`left out for now `_. Path separators, if used, MUST be the forward slash character (``/``), and parent directory indicators (``..``) MUST NOT be used. @@ -683,24 +705,25 @@ A few minor additions will be made to the relevant existing specifications to document, standardize and clarify what is already currently supported, allowed and implemented behavior, as well as explicitly mention the directory location the license file tree is rooted in for each format, per the -specification above. +`specification above `_. **Project source trees** - As described above, the project source metadata specification [#projectspec]_ + As `described above `_, the + `Declaring Project Metadata specification <#pep621spec_>`_ will be updated to reflect that license file paths MUST be relative to the project root directory; i.e. the directory containing the ``pyproject.toml`` (or equivalently, other legacy project configuration, e.g. ``setup.py``, ``setup.cfg``, etc). **Source distributions** *(sdists)* - The sdist specification [#sdistspec]_ will be updated to reflect that for + The `sdist specification <#sdistspec_>`_ will be updated to reflect that for ``Metadata-Version`` is ``2.3`` or greater, the sdist MUST contain any license files specified by ``License-File`` in the ``PKG-INFO`` at their respective paths relative to the top-level directory of the sdist (containing the ``pyproject.toml`` and the ``PKG-INFO`` core metadata). **Built distributions** *(wheels)* - The wheel specification [#wheelspec]_ will be updated to reflect that if + The `wheel specification <#wheelspec_>`_ will be updated to reflect that if the ``Metadata-Version`` is ``2.3`` or greater and one or more ``License-File`` fields is specified, the ``.dist-info`` directory MUST contain a ``license_files`` subdirectory which MUST contain the files listed @@ -708,7 +731,7 @@ specification above. paths relative to the ``license_files`` directory. **Installed projects** - The Recording Installed Projects specification [#installedspec]_ will be + The `Recording Installed Projects specification <#installedspec_>`_ will be updated to reflect that if the ``Metadata-Version`` is ``2.3`` or greater and one or more ``License-File`` fields is specified, the ``.dist-info`` directory MUST contain a ``license_files`` subdirectory which MUST contain @@ -736,7 +759,7 @@ license identifier mapped to the license classifier to be considered unambiguous for the purposes of automatically filling the ``License-Expression`` field. -If tools have filled the ``License-Expression`` field as described above, +If tools have filled the ``License-Expression`` field as described here, they MUST output a prominent, user-visible warning informing package authors of that fact, including the ``License-Expression`` string they have output, and recommending that the source metadata be updated accordingly @@ -753,14 +776,16 @@ Mapping license classifiers to SPDX identifiers Most single license classifiers (namely, all those not mentioned below) map to a single valid SPDX license identifier, allowing tools to insert them -into the ``License-Expression`` field following the specification above. +into the ``License-Expression`` field following the +`specification above `_. Many legacy license classifiers intend to specify a particular license, -but do not specify the particular version or variant, leading to critical -ambiguity as to their terms, compatibility and acceptability [#issue17]_. -Tools MUST NOT attempt to automatically infer a ``License-Expression`` -when one of these classifiers is used, and SHOULD instead prompt the user -to affirmatively select and confirm their intended license choice. +but do not specify the particular version or variant, leading to +`critical ambiguity <#classifierissue_>`_ as to their terms, compatibility +and acceptability. Tools MUST NOT attempt to automatically infer a +``License-Expression`` when one of these classifiers is used, and SHOULD +instead prompt the user to affirmatively select and confirm their intended +license choice. These classifiers are the following: @@ -780,7 +805,7 @@ These classifiers are the following: - ``License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)`` A comprehensive mapping of these classifiers to their possible specific -identifiers was assembled by Dustin Ingram [#badclassifiers]_, which tools +identifiers was `assembled by Dustin Ingram <#badclassifiers_>`_, which tools MAY use as a reference for the identifier selection options to offer users when prompting the user to explicitly select the license identifier they intended for their project. @@ -799,11 +824,13 @@ considered canonical and normative for the purposes of this specification: ``License-Expression: LicenseRef-Public-Domain``. If tools do so, they SHOULD issue an informational warning encouraging the use of more explicit and legally portable license identifiers - such as ``CC0-1.0`` [#cc0]_ or the ``Unlicense`` [#unlic]_, + such as those for the `CC0 1.0 license <#cc0_>`_ (``CC0-1.0``), + the `Unlicense <#unlicense_>`_ (``Unlicense``), + or the `MIT license <#mitlicense_>`_ (``MIT``), since the meaning associated with the term "public domain" is thoroughly dependent on the specific legal jurisdiction involved, some of which lack the concept entirely. - Alternatively, tools MAY choose to treat the above as ambiguous and + Alternatively, tools MAY choose to treat these classifiers as ambiguous and require user confirmation to fill ``License-Expression`` in these cases. - The generic and sometimes ambiguous classifiers @@ -816,7 +843,7 @@ considered canonical and normative for the purposes of this specification: ``License :: Other/Proprietary License`` MAY be mapped to the generic ``License-Expression: LicenseRef-Proprietary``, but tools MUST issue a prominent, informative warning if they do so. - Alternatively, tools MAY choose to treat the above as ambiguous and + Alternatively, tools MAY choose to treat these classifiers as ambiguous and require user confirmation to fill ``License-Expression`` in these cases. - The generic and ambiguous classifiers ``License :: OSI Approved`` and @@ -824,7 +851,7 @@ considered canonical and normative for the purposes of this specification: and thus tools MUST treat them as ambiguous and require user intervention to fill ``License-Expression``. -- The classifiers ``License :: GUST Font License 1.0*`` and +- The classifiers ``License :: GUST Font License 1.0`` and ``License :: GUST Font License 2006-09-30`` have no mapping to SPDX license identifiers and no PyPI package uses them, as of the writing of this PEP. Therefore, tools MUST treat them as ambiguous when attempting to fill @@ -864,13 +891,13 @@ I just want to share my own work without legal restrictions ----------------------------------------------------------- While you aren't required to include a license, if you don't, no one has -*any* permission to download, use or improve your work [#dontchoosealicense]_, +`any permission to download, use or improve your work <#dontchoosealicense_>`_, so that's probably the *opposite* of what you actually want. -The MIT license [#mitlicense]_ is a great choice for this, as its simple, +The `MIT license <#mitlicense_>`_ is a great choice for this, as its simple, widely used and allows anyone to do whatever they want with your work (other than sue you, which you probably also don't want). -To apply it, just paste the text [#chooseamitlicense]_ into a file named +To apply it, just paste `the text <#chooseamitlicense_>`_ into a file named ``LICENSE.txt`` at the root of your repo, and add the year and your name to the copyright line. Then, just add ``license-expression = "MIT"`` under ``[project]`` in your ``pyproject.toml`` if your packaging tool supports it, @@ -888,8 +915,8 @@ file at the root of your repo (if you don't have it in a file starting with ``pyproject.toml`` if your packaging tool supports it, or in its config file (e.g. for Setuptools, ``license_expression = LICENSE-ID`` under ``[metadata]`` in ``setup.cfg``). You can find the ``LICENSE-ID`` -and copyable license text on sites like ChooseALicense [#choosealicenselist]_ -or SPDX [#spdxlist]_. +and copyable license text on sites like +`ChooseALicense <#choosealicenselist_>`_ or `SPDX <#spdxlist_>`_. Many popular code hosts, project templates and packaging tools can add the license file for you, and may support the expression as well in the future. @@ -908,7 +935,7 @@ In your project config file, enter your license expression under packaging tool, and make sure to remove any legacy ``license`` value or ``License ::`` classifiers. Your existing ``license`` value may already be valid as one (e.g. ``MIT``, ``Apache-2.0 OR BSD-2-Clause``, etc); -otherwise, check the SPDX license list [#spdxlist]_ for the identifier +otherwise, check the `SPDX license list <#spdxlist_>`_ for the identifier that matches the license used in your project. If your license files begin with ``LICENSE``, ``COPYING``, ``NOTICE`` or @@ -919,7 +946,7 @@ or ``license-files.globs`` under ``[project]`` in ``pyproject.toml`` (if your tool supports it), or in your tool's configuration file (e.g. ``license_files`` in ``setup.cfg`` for Setuptools). -See the `Basic Example`_ for a simple but complete real-world demo of how +See the `basic example`_ for a simple but complete real-world demo of how this works in practice, including some additional technical details. Packaging tools may support automatically converting legacy licensing metadata; check your tool's documentation for details. @@ -968,9 +995,9 @@ as glob patterns, or ``["LICENSE.txt", "_vendor/LICENSE-APACHE.txt", "_vendor/LICENSE-BSD.txt"]`` as literal file paths. -See a fully worked out `Advanced Example`_ for a comprehensive end-to-end +See a fully worked out `advanced example`_ for a comprehensive end-to-end application of this to a real-world complex project, with copious technical -details, and consult a tutorial [#spdxtutorial]_ for more help and examples +details, and consult a `tutorial <#spdxtutorial_>`_ for more help and examples on using SPDX identifiers and expressions. @@ -1020,7 +1047,7 @@ the names of existing licenses. While minor additions will be made to the source distribution (sdist) built distribution (wheel) and installed project specifications, all of these -are merely documenting, clarifing and formally specifying behaviors explicitly +are merely documenting, clarifying and formally specifying behaviors explicitly allowed under their current respective specifications, and already implemented in practice, and gating them behind the explicit presence of both the new metadata versions and the new fields. In particular, sdsts may contain @@ -1091,13 +1118,14 @@ Reference Implementation Tools will need to support parsing and validating license expressions in the ``License-Expression`` field. -The license-expression library [#licexp]_ is a reference Python +The `license-expression library <#licenseexplib_>`_ is a reference Python implementation of a library that handles license expressions including parsing, validating and formatting license expressions using flexible lists of license symbols (including SPDX license identifiers and any extra identifiers referenced here). It is licensed under the Apache-2.0 license and is used in a few projects -such as the SPDX Python Tools [#spdxpy]_, the ScanCode toolkit [#scancodetk]_ -and the Free Software Foundation Europe (FSFE) Reuse project [#reuse]_. +such as the `SPDX Python Tools <#spdxpy_>`_, +the `ScanCode toolkit <#scancodetk_>`_ +and the Free Software Foundation Europe (FSFE) `Reuse project <#reuse_>`_. Rejected Ideas @@ -1113,7 +1141,7 @@ core metadata fields specified in this PEP. Re-use the ``License`` field '''''''''''''''''''''''''''' -Following initial discussion [#reusediscussion]_, earlier versions of this +Following `initial discussion <#reusediscussion_>`_, earlier versions of this PEP proposed to re-use the existing ``License`` field, which tools would attempt to parse as a SPDX license expression with a fall back to treating as free text. Initially, this would merely cause a warning (or even pass @@ -1234,7 +1262,7 @@ to a free-form description, to the same SPDX identifier they would be entering in the ``license-expression`` key anyway, assuming they can easily find documentation at all about it). In fact, this can be made even easier thanks to the new field. For example, GitHub's popular -ChooseALicense.com [#choosealicense]_ links to how to add SPDX license +`ChooseALicense.com <#choosealicense_>`_ links to how to add SPDX license identifiers to the project source metadata of various languages that support them right in the sidebar of every license page; the SPDX support in this PEP enables adding Python to that list. @@ -1698,10 +1726,9 @@ Flatten license files in subdirectories ''''''''''''''''''''''''''''''''''''''' Previous drafts of this PEP were silent on the issue of handling license files -in subdirectories. Currently, Wheel [#wheelfiles]_ and (following its example) -Setuptools [#setuptoolsfiles]_ flattens all license files into the -``.dist-info`` directory [#setuptoolsfiles]_, without preserving the source -subdirectory hierarchy. +in subdirectories. Currently, `Wheel <#wheelfiles_>`_ and (following its +example) `Setuptools <#setuptoolsfiles_>`_ flattens all license files into the +``.dist-info`` directory without preserving the source subdirectory hierarchy. While this is the simplest approach and matches existing ad hoc practice, this can result in name conflicts and license files clobbering others, @@ -1775,7 +1802,7 @@ Therefore, now is a prudent time to specify an alternate approach. The simplest and most obvious solution, as suggested by several on the Wheel and Setuptools implementation issues, is to simply root the license files relative to a ``license_files`` subdirectory of ``.dist-info``. This is simple -to implement and solves all the problems noted above, without clear significant +to implement and solves all the problems noted here, without clear significant drawbacks relative to other more complex options. It does make the specification a bit more complex and less elegant, but @@ -1883,8 +1910,8 @@ Map identifiers to source files ''''''''''''''''''''''''''''''' File-level notices are not considered as part of the scope of this PEP and the -existing ``SPDX-License-Identifier`` [#spdxids]_ convention can be used and -may not need further specification as a PEP. +existing ``SPDX-License-Identifier`` `convention <#spdxid_>`_ can +be used and may not need further specification as a PEP. Don't freeze compatibility with a specific SPDX version @@ -1902,7 +1929,7 @@ compatibility with a specific version of these specifications here and requiring a PEP or similar process to update it avoids that from occurring, and follows the practice of other packaging ecosystems. -Therefore, it was decided [#spdxversion]_ to specify a minimum version +Therefore, it was `decided <#spdxversion_>`_ to specify a minimum version and requires tools to be compatible with it, while still allowing updates so long as they don't break backward compatibility. This enables tools to immediate take advantage of improvements and accept new @@ -1918,10 +1945,10 @@ PEP to handle cases where the license expression for a binary distribution (wheel) is different from that for a source distribution (sdist), such as in cases of non-pure-Python packages that compile and bundle binaries under different licenses than the project itself. An example cited was -PyTorch [#pytorch]_, which contains CUDA from Nvidia, which is freely -distributable but not open source. NumPy [#numpyissue]_ and SciPy -[#scipyissue]_ also had similar issues, as reported by the original author -of this PEP and now resolved for those cases. +`PyTorch <#pytorch_>`_, which contains CUDA from Nvidia, which is freely +distributable but not open source. `NumPy <#numpyissue_>`_ and +`SciPy <#scipyissue_>`_ also had similar issues, as reported by the +original author of this PEP and now resolved for those cases. However, given the inherent complexity here and a lack of an obvious mechanism to do so, the fact that each wheel would need its own license @@ -1967,7 +1994,7 @@ Appendix 1. License Expression Examples Basic example ------------- -The Setuptools project itself, as of version 59.1.1 [#setuptools5911]_, +The Setuptools project itself, as of `version 59.1.1 <#setuptools5911_>`_, does not use the ``License`` field in its own project source metadata. Further, it no longer explicitly specifies ``license_file``/``license_files`` as it did previously, since Setuptools relies on its own automatic @@ -1998,7 +2025,7 @@ The output core metadata for the distribution packages would then be:: The ``LICENSE`` file would be stored at ``/setuptools-{version}/LICENSE`` in the sdist and ``/setuptools-{version}.dist-info/license_files/LICENSE`` in the wheel, and unpacked from there into the site directory (e.g. -``site-packages) on installation; ``/`` is the root of the respective archive +``site-packages``) on installation; ``/`` is the root of the respective archive and ``{version}`` the version of the Setuptools release in the core metadata. @@ -2033,7 +2060,7 @@ of the MIT license and the copyrights used by Setuptools, ``pyparsing``, ``more_itertools`` and ``ordered-set``; and the ``LICENSE`` files in the ``setuptools/_vendor/packaging/`` directory contain the Apache 2.0 and 2-clause BSD license text, and the Packaging copyright statement and -license choice notice [#packlic]_. +`license choice notice <#packaginglicense_>`_. Therefore, we assume the license files are located at the following paths in the project source tree (relative to the project root and @@ -2094,7 +2121,7 @@ the license files would be located at the paths:: /setuptools-{version}/setuptools/_vendor/packaging/LICENSE.BSD In the built wheel, with ``/`` being the root of the archive and -``{version}`` as above, the license files would be stored at:: +``{version}`` as the previous, the license files would be stored at:: /setuptools-{version}.dist-info/license_files/LICENSE /setuptools-{version}.dist-info/license_files/setuptools/_vendor/packaging/LICENSE @@ -2102,7 +2129,7 @@ In the built wheel, with ``/`` being the root of the archive and /setuptools-{version}.dist-info/license_files/setuptools/_vendor/packaging/LICENSE.BSD Finally, in the installed project, with ``site-packages`` being the site dir -and ``{version}`` as above, the license files would be installed to:: +and ``{version}`` as the previous, the license files would be installed to:: site-packages/setuptools-{version}.dist-info/license_files/LICENSE site-packages/setuptools-{version}.dist-info/license_files/setuptools/_vendor/packaging/LICENSE @@ -2164,8 +2191,8 @@ Core metadata ------------- There are two overlapping core metadata fields to document a license: the -license ``Classifier`` strings [#classif]_ prefixed with ``License ::`` -and the ``License`` field as free text [#licfield]_. +license ``Classifier`` `strings <#classifiers_>`_ prefixed with ``License ::`` +and the ``License`` `field <#licensefield_>`_ as free text. The core metadata ``License`` field documentation is currently:: @@ -2204,7 +2231,7 @@ Beyond a license code or qualifier, license text files are documented and included in a built package either implicitly or explicitly and this is another possible source of confusion: -- In Setuptools [#setuptoolssdist]_ and Wheel [#wheels]_, license files +- In `Setuptools <#setuptoolssdist_>`_ and `Wheel <#wheels_>`_, license files are automatically added to the distribution (at their source location in in a source distribution/sdist, and in the ``.dist-info`` directory of a built wheel) if they match one of a number of common license file @@ -2215,44 +2242,37 @@ possible source of confusion: to the ``setuptools.setup()`` function. At present, following Wheel's lead, Setuptools flattens the collected license files into the metadata directory, clobbering files with the same name, and dump license files - directly into the top-level ``.dist-info`` directory, but there is a desire - to resolve both these issues, contingent on the this PEP being accepted - [#setuptoolsfiles]_. + directly into the top-level ``.dist-info`` directory, but there is a + `desire to resolve both these issues <#setuptoolsfiles_>`_, + contingent on the this PEP being accepted. - Both tools also support an older, singular ``license_file`` parameter that allows specifying only one license file to add to the distribution, which - has been deprecated for some time but still sees some use. - See [#pipsetup]_ for instance. + has been deprecated for some time but still sees `some use <#pipsetup_>`_. - Following the publication of an earlier draft of this PEP, Setuptools - added support for ``License-File`` in distribution metadata as described - herein [#setuptoolspep639]_. This allows other tools consuming the resulting - metadata to unambiguously locate the license file(s) for a given package. - -**Note:** The ``License-File`` field proposed in this PEP already exists in -Wheel and Setuptools with the same behaviour as explained above. -This PEP is only recognizing and documenting the existing practice as used -in Wheel and Setuptools to add license files to the distribution, -and formally including their paths in core metadata (which has since been -implemented on the basis of a draft of this PEP). + `added support <#setuptoolspep639_>`_ for ``License-File`` in distribution + metadata as described in this specification. This allows other tools + consuming the resulting metadata to unambiguously locate the license file(s) + for a given package. PyPA Packaging Guide and Sample Project --------------------------------------- -Both the PyPA beginner packaging tutorial [#packagingtuttxt]_ and its more -comprehensive packaging guide [#packagingguidetxt]_ state that it is important -that every package include a license file. They point to the ``LICENSE.txt`` -in the official PyPA sample project as an example, which is explicitly listed -under the ``license_files`` key in its ``setup.cfg`` [#samplesetupcfg]_, -following existing practice formally specified by this PEP. +Both the `PyPA beginner packaging tutorial <#packagingtuttxt_>`_ and its more +comprehensive `packaging guide <#packagingguidetxt_>`_ state that it is +important that every package include a license file. They point to the +``LICENSE.txt`` in the official PyPA sample project as an example, which is +`explicitly listed <#samplesetupcfg_>`_ under the ``license_files`` key in +its ``setup.cfg``, following existing practice formally specified by this PEP. -Both the beginner packaging tutorial [#packagingtutkey]_ and the sample project -[#samplesetuppy]_ only use classifiers to declare a package's license, and do -not include or mention the ``License`` field. The full packaging guide does -mention this field, but states that authors should use the license classifiers -instead, unless the project uses a non-standard license (which the guide -discourages) [#licfield]_. +Both the `beginner packaging tutorial <#packagingtutkey_>`_ and the +`sample project <#samplesetuppy_>`_ only use classifiers to declare a +package's license, and do not include or mention the ``License`` field. +The `full packaging guide <#licensefield_>`_ does mention this field, but +states that authors should use the license classifiers instead, unless the +project uses a non-standard license (which the guide discourages). Python source code files @@ -2260,10 +2280,9 @@ Python source code files **Note:** Documenting licenses in source code is not in the scope of this PEP. -Beside using comments and/or ``SPDX-License-Identifier`` conventions, the license -is sometimes documented in Python code files using "dunder" variables typically -named after one of the lower cased core metadata fields such as ``__license__`` -[#pycode]_. +Beside using comments and/or ``SPDX-License-Identifier`` conventions, the +license is `sometimes <#pycode_>`_ documented in Python code files using +a "dunder" variable, typically named ``__license__``. This convention (dunder global variables) is recognized by the built-in ``help()`` function and the standard ``pydoc`` module. The dunder variable(s) will show up in @@ -2273,17 +2292,17 @@ the ``help()`` DATA section for a module. Other Python packaging tools ---------------------------- -- Conda package manifests [#conda]_ have support for ``license`` and +- `Conda package manifests <#conda_>`_ have support for ``license`` and ``license_file`` fields, and automatically include license files following similar naming patterns as Wheel and Setuptools. -- Flit [#flit]_ recommends using classifiers instead of the ``License`` field +- `Flit <#flit_>`_ recommends using classifiers instead of the ``License`` field (per the current PyPA packaging guide). -- PBR [#pbr]_ uses similar data as Setuptools, but always stored in +- `PBR <#pbr_>`_ uses similar data as Setuptools, but always stored in ``setup.cfg``. -- Poetry [#poetry]_ specifies the use of the ``license`` field in +- `Poetry <#poetry_>`_ specifies the use of the ``license`` field in ``pyproject.toml`` with SPDX license identifiers. @@ -2299,27 +2318,30 @@ Linux distribution packages **Note:** in most cases the license texts of the most common licenses are included globally once in a shared documentation directory (e.g. ``/usr/share/doc``). -- Debian documents package licenses with machine readable copyright files - [#dep5]_. This specification defines its own license expression syntax that is +- Debian documents package licenses with + `machine readable copyright files <#dep5_>`_. + This specification defines its own license expression syntax that is very similar to the SDPX syntax and use its own list of license identifiers for common licenses (also closely related to SPDX identifiers). -- Fedora packages [#fedora]_ specify how to include ``License Texts`` - [#fedoratext]_ and how use a ``License`` field [#fedoralic]_ that must be filled +- `Fedora packages <#fedora_>`_ specify how to include + `License Texts <#fedoratext_>`_ and how use a + `License field <#fedoralicense_>`_ that must be filled with an appropriate license Short License identifier(s) from an extensive list - of "Good Licenses" identifiers [#fedoralist]_. Fedora also defines its own + of `"Good License" identifiers <#fedoralist_>`_. Fedora also defines its own license expression syntax very similar to the SDPX syntax. -- openSUSE packages [#opensuse]_ use SPDX license expressions with - SPDX license identifiers and a list of extra license identifiers - [#opensuselist]_. +- `OpenSUSE packages <#opensuse_>`_ use SPDX license expressions with + SPDX license identifiers and a + `list of extra license identifiers <#opensuselist_>`_. -- Gentoo ebuild uses a ``LICENSE`` variable [#gentoo]_. This field is specified - in GLEP-0023 [#glep23]_ and in the Gentoo development manual [#gentoodev]_. +- `Gentoo ebuild <#pycode_>`_ uses a ``LICENSE`` variable. This field is + specified in `GLEP-0023 <#glep23_>`_ and in the + `Gentoo development manual <#gentoodev_>`_. Gentoo also defines a license expression syntax and a list of allowed licenses. The expression syntax is rather different from SPDX. -- FreeBSD package Makefile [#freebsd]_ provides ``LICENSE`` and +- The `FreeBSD package Makefile <#freebsd_>`_ provides ``LICENSE`` and ``LICENSE_FILE`` fields with a list of custom license symbols. For non-standard licenses, FreeBSD recommend to use ``LICENSE=UNKNOWN`` and add ``LICENSE_NAME`` and ``LICENSE_TEXT`` fields, as well as sophisticated @@ -2329,95 +2351,97 @@ globally once in a shared documentation directory (e.g. ``/usr/share/doc``). expression syntax. FreeBSD also recommends the use of ``SPDX-License-Identifier`` in source code files. -- Arch Linux PKGBUILD [#archinux]_ define its own license identifiers - [#archlinuxlist]_. The value ``'unknown'`` can be used if the license is not - defined. +- `Arch Linux PKGBUILD <#archinux_>`_ define its + `own license identifiers <#archlinuxlist_>`_. + The value ``'unknown'`` can be used if the license is not defined. -- OpenWRT ipk packages [#openwrt]_ use the ``PKG_LICENSE`` and +- `OpenWRT ipk packages <#openwrt_>`_ use the ``PKG_LICENSE`` and ``PKG_LICENSE_FILES`` variables and recommend the use of SPDX License identifiers. -- NixOS uses SPDX identifiers [#nixos]_ and some extra license identifiers in - its license field. +- `NixOS uses SPDX identifiers <#nixos_>`_ and some extra license identifiers + in its license field. -- GNU Guix (based on NixOS) has a single License field, uses its own license - symbols list [#guix]_ and specifies to use one license or a list of licenses - [#guixlic]_. +- GNU Guix (based on NixOS) has a single License field, uses its own + `license symbols list <#guix_>`_ and specifies to use one license or a + `list of licenses <#guixlicense_>`_. -- Alpine Linux packages [#alpine]_ recommend using SPDX identifiers in the +- `Alpine Linux packages <#alpine_>`_ recommend using SPDX identifiers in the license field. Language and application packages --------------------------------- -- In Java, Maven POM [#maven]_ defines a ``licenses`` XML tag with a list of license - items each with a name, URL, comments and "distribution" type. This is not - mandatory and the content of each field is not specified. +- In Java, `Maven POM <#maven_>`_ defines a ``licenses`` XML tag with a list + of license items each with a name, URL, comments and "distribution" type. + This is not mandatory and the content of each field is not specified. -- JavaScript npm package.json [#npm]_ use a single license field with SPDX +- `JavaScript NPM package.json <#npm_>`_ use a single license field with SPDX license expression or the ``UNLICENSED`` id if no license is specified. A license file can be referenced as an alternative using "SEE LICENSE IN " in the single ``license`` field. -- Rubygems gemspec [#gem]_ specifies either a singular license string or a list - of license strings. The relationship between multiple licenses in a list is - not specified. They recommend using SPDX license identifiers. +- `Rubygems gemspec <#gem_>`_ specifies either a singular license string or + a list of license strings. The relationship between multiple licenses in a + list is not specified. They recommend using SPDX license identifiers. -- CPAN Perl modules [#perl]_ use a single license field which is either a single - string or a list of strings. The relationship between the licenses in a list - is not specified. There is a list of custom license identifiers plus +- `CPAN Perl modules <#perl_>`_ use a single license field which is either a + single string or a list of strings. The relationship between the licenses in + a list is not specified. There is a list of custom license identifiers plus these generic identifiers: ``open_source``, ``restricted``, ``unrestricted``, ``unknown``. -- Rust Cargo [#cargo]_ specifies the use of an SPDX license expression (v2.1) in - the ``license`` field. It also supports an alternative expression syntax using - slash-separated SPDX license identifiers. There is also a ``license_file`` - field. The crates.io package registry [#cratesio]_ requires that either - ``license`` or ``license_file`` fields are set when you upload a package. +- `Rust Cargo <#cargo_>`_ specifies the use of an SPDX license expression + (v2.1) in the ``license`` field. It also supports an alternative expression + syntax using slash-separated SPDX license identifiers. There is also a + ``license_file`` field. The `crates.io package registry <#cratesio_>`_ + requires that either ``license`` or ``license_file`` fields are set when + you upload a package. -- PHP Composer composer.json [#composer]_ uses a ``license`` field with an SPDX - license id or "proprietary". The ``license`` field is either a single string - that can use something which resembles the SPDX license expression syntax with - "and" and "or" keywords; or is a list of strings if there is a choice of - licenses (aka. a "disjunctive" choice of license). +- `PHP Composer composer.json <#composer_>`_ uses a ``license`` field with + an SPDX license id or "proprietary". The ``license`` field is either a + single string that can use something which resembles the SPDX license + expression syntax with "and" and "or" keywords; or is a list of strings + if there is a choice of licenses (aka. a "disjunctive" choice of license). -- NuGet packages [#nuget]_ were using only a simple license URL and are now +- `NuGet packages <#nuget_>`_ were using only a simple license URL and are now specifying to use an SPDX License expression and/or the path to a license file within the package. The NuGet.org repository states that they only - accepts license expressions that are `approved by the Open Source Initiative - or the Free Software Foundation.` + accepts license expressions that are "approved by the Open Source Initiative + or the Free Software Foundation." - Go language modules ``go.mod`` have no provision for any metadata beyond dependencies. Licensing information is left for code authors and other community package managers to document. -- Dart/Flutter spec [#flutter]_ recommends to use a single ``LICENSE`` file +- `Dart/Flutter spec <#flutter_>`_ recommends to use a single ``LICENSE`` file that should contain all the license texts each separated by a line with 80 hyphens. -- JavaScript Bower [#bower]_ ``license`` field is either a single string or a list - of strings using either SPDX license identifiers, or a path or a URL to a - license file. +- `JavaScript Bower <#bower_>`_ ``license`` field is either a single string + or a list of strings using either SPDX license identifiers, or a path or + a URL to a license file. -- Cocoapods podspec [#cocoapod]_ ``license`` field is either a single string or a - mapping with attributes of type, file and text keys. This is mandatory unless - there is a LICENSE or LICENCE file provided. +- `Cocoapods podspec <#cocoapod_>`_ ``license`` field is either a single + string or a mapping with attributes of type, file and text keys. + This is mandatory unless there is a ``LICENSE`` or ``LICENCE`` file provided. -- Haskell Cabal [#cabal]_ accepts an SPDX license expression since version 2.2. - The version of the SPDX license list used is a function of the ``cabal`` version. - The specification also provides a mapping between pre-SPDX Legacy license - Identifiers and SPDX identifiers. Cabal also specifies a ``license-file(s)`` - field that lists license files that will be installed with the package. +- `Haskell Cabal <#cabal_>`_ accepts an SPDX license expression since + version 2.2. The version of the SPDX license list used is a function of + the ``cabal`` version. The specification also provides a mapping between + pre-SPDX Legacy license Identifiers and SPDX identifiers. + Cabal also specifies a ``license-file(s)`` field that lists license files + that will be installed with the package. -- Erlang/Elixir mix/hex package [#mix]_ specifies a ``licenses`` field as a +- `Erlang/Elixir mix/hex package <#mix_>`_ specifies a ``licenses`` field as a required list of license strings and recommends to use SPDX license identifiers. -- D lang dub package [#dub]_ defines its own list of license identifiers and +- `D lang dub package <#dub_>`_ defines its own list of license identifiers and its own license expression syntax and both are similar to the SPDX conventions. -- R Package DESCRIPTION [#cran]_ defines its own sophisticated license +- `R Package DESCRIPTION <#cran_>`_ defines its own sophisticated license expression syntax and list of licenses identifiers. R has a unique way to support specifiers for license versions such as ``LGPL (>= 2.0, < 3)`` in its license expression syntax. @@ -2426,143 +2450,146 @@ Language and application packages Other ecosystems ---------------- -- ``SPDX-License-Identifier`` [#spdxids]_ is a simple convention to document the - license inside a file. +- The ``SPDX-License-Identifier`` `header <#spdxid_>`_ is a simple + convention to document the license inside a file. -- The Free Software Foundation (FSF) promotes the use of SPDX license identifiers - for clarity in the GPL and other versioned free software licenses [#gnu]_ - [#fsf]_. +- The `Free Software Foundation (FSF) <#fsf_>`_ promotes the use of + SPDX license identifiers for clarity in the `GPL <#gnu_>`_ and other + versioned free software licenses. -- The Free Software Foundation Europe (FSFE) REUSE project [#reuse]_ promotes - using ``SPDX-License-Identifier``. +- The Free Software Foundation Europe (FSFE) `REUSE project <#reuse_>`_ + promotes using ``SPDX-License-Identifier``. -- The Linux kernel uses ``SPDX-License-Identifier`` and parts of the FSFE REUSE - conventions to document its licenses [#linux]_. +- The `Linux kernel <#linux_>`_ uses ``SPDX-License-Identifier`` + and parts of the FSFE REUSE conventions to document its licenses. -- U-Boot spearheaded using ``SPDX-License-Identifier`` in code and now follows the - Linux ways [#uboot]_. +- `U-Boot <#uboot_>`_ spearheaded using ``SPDX-License-Identifier`` in code + and now follows the Linux ways. -- The Apache Software Foundation projects use RDF DOAP [#apache]_ with a single - license field pointing to SPDX license identifiers. +- The Apache Software Foundation projects use `RDF DOAP <#apache_>`_ with + a single license field pointing to SPDX license identifiers. -- The Eclipse Foundation promotes using ``SPDX-license-Identifiers`` [#eclipse]_ +- The `Eclipse Foundation <#eclipse_>`_ promotes using + ``SPDX-license-Identifiers``. -- The ClearlyDefined project [#cd]_ promotes using SPDX license identifiers and - expressions to improve license clarity. +- The `ClearlyDefined project <#clearlydefined_>`_ promotes using SPDX + license identifiers and expressions to improve license clarity. -- The Android Open Source Project [#android]_ use ``MODULE_LICENSE_XXX`` empty - tag files where ``XXX`` is a license code such as BSD, APACHE, GPL, etc. And - side by side with this ``MODULE_LICENSE`` file there is a ``NOTICE`` file - that contains license and notices texts. +- The `Android Open Source Project <#android_>`_ use ``MODULE_LICENSE_XXX`` + empty tag files, where ``XXX`` is a license code such as BSD, APACHE, GPL, + etc. And side by side with this ``MODULE_LICENSE`` file there is a + ``NOTICE`` file that contains license and notices texts. References ========== -.. [#pypugglossary] https://packaging.python.org/glossary/ -.. [#cms] https://packaging.python.org/specifications/core-metadata -.. [#projectspec] https://packaging.python.org/specifications/declaring-project-metadata/ -.. [#sdistspec] https://packaging.python.org/specifications/source-distribution-format/ -.. [#wheelspec] https://packaging.python.org/specifications/binary-distribution-format/ -.. [#installedspec] https://packaging.python.org/specifications/recording-installed-packages/ -.. [#wheelproject] https://wheel.readthedocs.io/en/stable/ -.. [#cdstats] https://clearlydefined.io/stats -.. [#cd] https://clearlydefined.io -.. [#osi] https://opensource.org -.. [#pypi] https://pypi.org/ -.. [#classif] https://pypi.org/classifiers -.. [#classifersrepo] https://github.com/pypa/trove-classifiers -.. [#issue17] https://github.com/pypa/trove-classifiers/issues/17 -.. [#badclassifiers] https://github.com/pypa/trove-classifiers/issues/17#issuecomment-385027197 -.. [#setuptoolspep639] https://github.com/pypa/setuptools/pull/2645 -.. [#wheelfiles] https://github.com/pypa/wheel/issues/138 -.. [#setuptoolsfiles] https://github.com/pypa/setuptools/issues/2739 -.. [#globmodule] https://docs.python.org/3/library/glob.html -.. [#spdxlist] https://spdx.org/licenses/ -.. [#spdx] https://spdx.dev/ -.. [#spdxid] https://spdx.dev/ids/ -.. [#spdxpression] https://spdx.github.io/spdx-spec/SPDX-license-expressions/ -.. [#wheels] https://github.com/pypa/wheel/blob/0.37.0/docs/user_guide.rst#including-license-files-in-the-generated-wheel-file -.. [#reuse] https://reuse.software/ -.. [#licexp] https://github.com/nexB/license-expression/ -.. [#spdxpy] https://github.com/spdx/tools-python/ -.. [#reusediscussion] https://github.com/pombredanne/spdx-pypi-pep/issues/7 -.. [#choosealicense] https://choosealicense.com/ -.. [#choosealicenselist] https://choosealicense.com/licenses/ -.. [#dontchoosealicense] https://choosealicense.com/no-permission/ -.. [#chooseamitlicense] https://choosealicense.com/licenses/mit/ -.. [#mitlicense] https://opensource.org/licenses/MIT -.. [#spdxtutorial] https://github.com/david-a-wheeler/spdx-tutorial -.. [#spdxversion] https://github.com/pombredanne/spdx-pypi-pep/issues/6 -.. [#pytorch] https://pypi.org/project/torch/ -.. [#numpyissue] https://github.com/numpy/numpy/issues/8689 -.. [#scipyissue] https://github.com/scipy/scipy/issues/7093 -.. [#scancodetk] https://github.com/nexB/scancode-toolkit -.. [#licfield] https://packaging.python.org/guides/distributing-packages-using-setuptools/#license -.. [#samplesetuppy] https://github.com/pypa/sampleproject/blob/3a836905fbd687af334db16b16c37cf51dcbc99c/setup.py#L98 -.. [#samplesetupcfg] https://github.com/pypa/sampleproject/blob/3a836905fbd687af334db16b16c37cf51dcbc99c/setup.cfg -.. [#pipsetup] https://github.com/pypa/pip/blob/21.3.1/setup.cfg#L114 -.. [#setuptoolssdist] https://github.com/pypa/setuptools/pull/1767 -.. [#packagingtuttxt] https://packaging.python.org/tutorials/packaging-projects/#creating-a-license -.. [#packagingguidetxt] https://packaging.python.org/guides/distributing-packages-using-setuptools/#license-txt -.. [#packagingtutkey] https://packaging.python.org/tutorials/packaging-projects/#configuring-metadata -.. [#pycode] https://github.com/search?l=Python&q=%22__license__%22&type=Code -.. [#setuptools5911] https://github.com/pypa/setuptools/blob/v59.1.1/setup.cfg -.. [#packlic] https://github.com/pypa/packaging/blob/21.2/LICENSE -.. [#conda] https://docs.conda.io/projects/conda-build/en/stable/resources/define-metadata.html#about-section -.. [#flit] https://flit.readthedocs.io/en/stable/pyproject_toml.html -.. [#poetry] https://python-poetry.org/docs/pyproject/#license -.. [#pbr] https://docs.openstack.org/pbr/latest/user/features.html -.. [#dep5] https://dep-team.pages.debian.net/deps/dep5/ -.. [#fedora] https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/ -.. [#fedoratext] https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/#_license_text -.. [#fedoralic] https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/#_valid_license_short_names -.. [#fedoralist] https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses -.. [#opensuse] https://en.opensuse.org/openSUSE:Packaging_guidelines#Licensing -.. [#opensuselist] https://docs.google.com/spreadsheets/d/14AdaJ6cmU0kvQ4ulq9pWpjdZL5tkR03exRSYJmPGdfs/pub -.. [#gentoo] https://devmanual.gentoo.org/ebuild-writing/variables/index.html#license -.. [#glep23] https://www.gentoo.org/glep/glep-0023.html -.. [#gentoodev] https://devmanual.gentoo.org/general-concepts/licenses/index.html -.. [#freebsd] https://docs.freebsd.org/en/books/porters-handbook/makefiles/#licenses -.. [#archinux] https://wiki.archlinux.org/title/PKGBUILD#license -.. [#archlinuxlist] https://archlinux.org/packages/core/any/licenses/files/ -.. [#openwrt] https://openwrt.org/docs/guide-developer/packages#buildpackage_variables -.. [#nixos] https://github.com/NixOS/nixpkgs/blob/21.05/lib/licenses.nix -.. [#guix] https://git.savannah.gnu.org/cgit/guix.git/tree/guix/licenses.scm?h=v1.3.0 -.. [#guixlic] https://guix.gnu.org/manual/en/html_node/package-Reference.html#index-license_002c-of-packages -.. [#alpine] https://wiki.alpinelinux.org/wiki/Creating_an_Alpine_package#license -.. [#maven] https://maven.apache.org/pom.html#Licenses -.. [#npm] https://docs.npmjs.com/cli/v8/configuring-npm/package-json#license -.. [#gem] https://guides.rubygems.org/specification-reference/#license= -.. [#perl] https://metacpan.org/pod/CPAN::Meta::Spec#license -.. [#cargo] https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata -.. [#cratesio] https://doc.rust-lang.org/cargo/reference/registries.html#publish -.. [#composer] https://getcomposer.org/doc/04-schema.md#license -.. [#nuget] https://docs.microsoft.com/en-us/nuget/reference/nuspec#licenseurl -.. [#flutter] https://flutter.dev/docs/development/packages-and-plugins/developing-packages#adding-licenses-to-the-license-file -.. [#bower] https://github.com/bower/spec/blob/b00c4403e22e3f6177c410ed3391b9259687e461/json.md#license -.. [#cocoapod] https://guides.cocoapods.org/syntax/podspec.html#license -.. [#cabal] https://cabal.readthedocs.io/en/3.6/cabal-package.html?highlight=license#pkg-field-license -.. [#mix] https://hex.pm/docs/publish -.. [#dub] https://dub.pm/package-format-json.html#licenses -.. [#cran] https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Licensing -.. [#spdxids] https://spdx.dev/resources/use/#identifiers -.. [#gnu] https://www.gnu.org/licenses/identify-licenses-clearly.html -.. [#fsf] https://www.fsf.org/blogs/rms/rms-article-for-claritys-sake-please-dont-say-licensed-under-gnu-gpl-2 -.. [#linux] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/license-rules.rst -.. [#uboot] https://www.denx.de/wiki/U-Boot/Licensing -.. [#apache] https://svn.apache.org/repos/asf/allura/doap_Allura.rdf -.. [#eclipse] https://www.eclipse.org/legal/epl-2.0/faq.php -.. [#android] https://github.com/aosp-mirror/platform_external_tcpdump/blob/android-platform-12.0.0_r1/MODULE_LICENSE_BSD -.. [#cc0] https://creativecommons.org/publicdomain/zero/1.0/ -.. [#unlic] https://unlicense.org/ +.. _#alpine: https://wiki.alpinelinux.org/wiki/Creating_an_Alpine_package#license +.. _#android: https://github.com/aosp-mirror/platform_external_tcpdump/blob/android-platform-12.0.0_r1/MODULE_LICENSE_BSD +.. _#apache: https://svn.apache.org/repos/asf/allura/doap_Allura.rdf +.. _#archinux: https://wiki.archlinux.org/title/PKGBUILD#license +.. _#archlinuxlist: https://archlinux.org/packages/core/any/licenses/files/ +.. _#badclassifiers: https://github.com/pypa/trove-classifiers/issues/17#issuecomment-385027197 +.. _#bower: https://github.com/bower/spec/blob/b00c4403e22e3f6177c410ed3391b9259687e461/json.md#license +.. _#cabal: https://cabal.readthedocs.io/en/3.6/cabal-package.html?highlight=license#pkg-field-license +.. _#cargo: https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata +.. _#cc0: https://creativecommons.org/publicdomain/zero/1.0/ +.. _#cdstats: https://clearlydefined.io/stats +.. _#choosealicense: https://choosealicense.com/ +.. _#choosealicenselist: https://choosealicense.com/licenses/ +.. _#chooseamitlicense: https://choosealicense.com/licenses/mit/ +.. _#classifierissue: https://github.com/pypa/trove-classifiers/issues/17 +.. _#classifiers: https://pypi.org/classifiers +.. _#classifiersrepo: https://github.com/pypa/trove-classifiers +.. _#clearlydefined: https://clearlydefined.io +.. _#cocoapod: https://guides.cocoapods.org/syntax/podspec.html#license +.. _#composer: https://getcomposer.org/doc/04-schema.md#license +.. _#conda: https://docs.conda.io/projects/conda-build/en/stable/resources/define-metadata.html#about-section +.. _#coremetadataspec: https://packaging.python.org/specifications/core-metadata +.. _#cran: https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Licensing +.. _#cratesio: https://doc.rust-lang.org/cargo/reference/registries.html#publish +.. _#dep5: https://dep-team.pages.debian.net/deps/dep5/ +.. _#dontchoosealicense: https://choosealicense.com/no-permission/ +.. _#dub: https://dub.pm/package-format-json.html#licenses +.. _#eclipse: https://www.eclipse.org/legal/epl-2.0/faq.php +.. _#fedora: https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/ +.. _#fedoralicense: https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/#_valid_license_short_names +.. _#fedoralist: https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses +.. _#fedoratext: https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/#_license_text +.. _#flit: https://flit.readthedocs.io/en/stable/pyproject_toml.html +.. _#flutter: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#adding-licenses-to-the-license-file +.. _#freebsd: https://docs.freebsd.org/en/books/porters-handbook/makefiles/#licenses +.. _#fsf: https://www.fsf.org/blogs/rms/rms-article-for-claritys-sake-please-dont-say-licensed-under-gnu-gpl-2 +.. _#gem: https://guides.rubygems.org/specification-reference/#license= +.. _#gentoo: https://devmanual.gentoo.org/ebuild-writing/variables/index.html#license +.. _#gentoodev: https://devmanual.gentoo.org/general-concepts/licenses/index.html +.. _#glep23: https://www.gentoo.org/glep/glep-0023.html +.. _#globmodule: https://docs.python.org/3/library/glob.html +.. _#gnu: https://www.gnu.org/licenses/identify-licenses-clearly.html +.. _#guix: https://git.savannah.gnu.org/cgit/guix.git/tree/guix/licenses.scm?h=v1.3.0 +.. _#guixlicense: https://guix.gnu.org/manual/en/html_node/package-Reference.html#index-license_002c-of-packages +.. _#installedspec: https://packaging.python.org/specifications/recording-installed-packages/ +.. _#interopissue: https://github.com/pypa/interoperability-peps/issues/46 +.. _#licenseexplib: https://github.com/nexB/license-expression/ +.. _#licensefield: https://packaging.python.org/guides/distributing-packages-using-setuptools/#license +.. _#linux: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/license-rules.rst +.. _#maven: https://maven.apache.org/pom.html#Licenses +.. _#mitlicense: https://opensource.org/licenses/MIT +.. _#mix: https://hex.pm/docs/publish +.. _#nixos: https://github.com/NixOS/nixpkgs/blob/21.05/lib/licenses.nix +.. _#npm: https://docs.npmjs.com/cli/v8/configuring-npm/package-json#license +.. _#nuget: https://docs.microsoft.com/en-us/nuget/reference/nuspec#licenseurl +.. _#numpyissue: https://github.com/numpy/numpy/issues/8689 +.. _#opensuse: https://en.opensuse.org/openSUSE:Packaging_guidelines#Licensing +.. _#opensuselist: https://docs.google.com/spreadsheets/d/14AdaJ6cmU0kvQ4ulq9pWpjdZL5tkR03exRSYJmPGdfs/pub +.. _#openwrt: https://openwrt.org/docs/guide-developer/packages#buildpackage_variables +.. _#osi: https://opensource.org +.. _#packagingguidetxt: https://packaging.python.org/guides/distributing-packages-using-setuptools/#license-txt +.. _#packagingissue: https://github.com/pypa/packaging-problems/issues/41 +.. _#packaginglicense: https://github.com/pypa/packaging/blob/21.2/LICENSE +.. _#packagingtutkey: https://packaging.python.org/tutorials/packaging-projects/#configuring-metadata +.. _#packagingtuttxt: https://packaging.python.org/tutorials/packaging-projects/#creating-a-license +.. _#pbr: https://docs.openstack.org/pbr/latest/user/features.html +.. _#pep621spec: https://packaging.python.org/specifications/declaring-project-metadata/ +.. _#pepissue: https://github.com/pombredanne/spdx-pypi-pep/issues/1 +.. _#perl: https://metacpan.org/pod/CPAN::Meta::Spec#license +.. _#pipsetup: https://github.com/pypa/pip/blob/21.3.1/setup.cfg#L114 +.. _#poetry: https://python-poetry.org/docs/pyproject/#license +.. _#pycode: https://github.com/search?l=Python&q=%22__license__%22&type=Code +.. _#pypi: https://pypi.org/ +.. _#pypugglossary: https://packaging.python.org/glossary/ +.. _#pytorch: https://pypi.org/project/torch/ +.. _#reuse: https://reuse.software/ +.. _#reusediscussion: https://github.com/pombredanne/spdx-pypi-pep/issues/7 +.. _#samplesetupcfg: https://github.com/pypa/sampleproject/blob/3a836905fbd687af334db16b16c37cf51dcbc99c/setup.cfg +.. _#samplesetuppy: https://github.com/pypa/sampleproject/blob/3a836905fbd687af334db16b16c37cf51dcbc99c/setup.py#L98 +.. _#scancodetk: https://github.com/nexB/scancode-toolkit +.. _#scipyissue: https://github.com/scipy/scipy/issues/7093 +.. _#sdistspec: https://packaging.python.org/specifications/source-distribution-format/ +.. _#setuptools5911: https://github.com/pypa/setuptools/blob/v59.1.1/setup.cfg +.. _#setuptoolsfiles: https://github.com/pypa/setuptools/issues/2739 +.. _#setuptoolspep639: https://github.com/pypa/setuptools/pull/2645 +.. _#setuptoolssdist: https://github.com/pypa/setuptools/pull/1767 +.. _#spdx: https://spdx.dev/ +.. _#spdxid: https://spdx.dev/ids/ +.. _#spdxlist: https://spdx.org/licenses/ +.. _#spdxpression: https://spdx.github.io/spdx-spec/SPDX-license-expressions/ +.. _#spdxpy: https://github.com/spdx/tools-python/ +.. _#spdxtutorial: https://github.com/david-a-wheeler/spdx-tutorial +.. _#spdxversion: https://github.com/pombredanne/spdx-pypi-pep/issues/6 +.. _#uboot: https://www.denx.de/wiki/U-Boot/Licensing +.. _#unlicense: https://unlicense.org/ +.. _#wheelfiles: https://github.com/pypa/wheel/issues/138 +.. _#wheelproject: https://wheel.readthedocs.io/en/stable/ +.. _#wheels: https://github.com/pypa/wheel/blob/0.37.0/docs/user_guide.rst#including-license-files-in-the-generated-wheel-file +.. _#wheelspec: https://packaging.python.org/specifications/binary-distribution-format/ Copyright ========= -This document is placed in the public domain or under the CC0-1.0-Universal -license [#cc0]_, whichever is more permissive. +This document is placed in the public domain or under the +`CC0-1.0-Universal license <#cc0_>`_, whichever is more permissive. Acknowledgments