From 8d686288ea11225f313f95fc3b6d07c2b2227162 Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Thu, 30 Jun 2022 20:20:44 -0500 Subject: [PATCH 01/11] PEP 639: Bump versions of Core Metadata and SPDX license list --- pep-0639.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pep-0639.rst b/pep-0639.rst index 39c9f693139..f4f37de5901 100644 --- a/pep-0639.rst +++ b/pep-0639.rst @@ -53,7 +53,7 @@ The PEP also: :ref:`other ecosystems <639-license-doc-other-projects>`. The changes in this PEP will update the -:`core metadata `__ to version 2.3, modify the +`core metadata `__ to version 2.4, modify the `PEP 621 project metadata specification `__, and make minor additions to the `source distribution (sdist) `__, `built distribution (wheel) `__ and @@ -381,7 +381,7 @@ publishing tools; end-user-facing install tools MAY be more lenient than mentioned here when encountering malformed metadata that does not conform to this specification. -As it adds new fields, this PEP updates the core metadata to version 2.3. +As it adds new fields, this PEP updates the core metadata to version 2.4. .. _639-spec-field-license-expression: @@ -407,7 +407,7 @@ 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 `__, version 3.15 or any later compatible + `SPDX License List `__, version 3.17 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". @@ -487,7 +487,7 @@ if a built distribution's metadata contains no ``License-File`` entries, and publishing tools MAY but build tools MUST NOT raise an error. For all newly-uploaded distribution packages that include one or more -``License-File`` fields and declare a ``Metadata-Version`` of ``2.3`` or +``License-File`` fields and declare a ``Metadata-Version`` of ``2.4`` or higher, PyPI SHOULD validate that the specified files are present in all uploaded distributions, and MUST reject uploads that do not validate. @@ -728,14 +728,14 @@ each format, per the :ref:`639-spec-field-license-file` section. **Source distributions** *(sdists)* The `sdist specification `__ will be updated to reflect that for - ``Metadata-Version`` is ``2.3`` or greater, the sdist MUST contain any + ``Metadata-Version`` is ``2.4`` 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 `__ will be updated to reflect that if - the ``Metadata-Version`` is ``2.3`` or greater and one or more + the ``Metadata-Version`` is ``2.4`` 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 in the ``License-File`` fields in the ``METADATA`` file at their respective @@ -743,7 +743,7 @@ each format, per the :ref:`639-spec-field-license-file` section. **Installed projects** The `Recording Installed Projects specification `__ will be - updated to reflect that if the ``Metadata-Version`` is ``2.3`` or greater + updated to reflect that if the ``Metadata-Version`` is ``2.4`` 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 in the ``License-File`` fields in the ``METADATA`` file @@ -1201,7 +1201,7 @@ field was separate from the existing ``License``, which would make validation much more challenging and backwards-incompatible, breaking existing packages. With that change, there was a clear consensus that the new field should be validated from the start, guaranteeing that all -distributions uploaded to PyPI that declare core metadata version 2.3 +distributions uploaded to PyPI that declare core metadata version 2.4 or higher and have the ``License-Expression`` field will have a valid expression, such that PyPI and consumers of its packages and metadata can rely upon to follow the specification here. From ba780459c6bf7519c521b99c0f488e6fd3c46b46 Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Thu, 30 Jun 2022 20:23:49 -0500 Subject: [PATCH 02/11] PEP 639: Update headers to reflect author no longer needing a sponsor --- pep-0639.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pep-0639.rst b/pep-0639.rst index f4f37de5901..7f14fd6794b 100644 --- a/pep-0639.rst +++ b/pep-0639.rst @@ -2,7 +2,6 @@ PEP: 639 Title: Improving License Clarity with Better Package Metadata Author: Philippe Ombredanne , C.A.M. Gerlach , -Sponsor: Paul Moore PEP-Delegate: Brett Cannon Discussions-To: https://discuss.python.org/t/12622 Status: Draft @@ -11,7 +10,7 @@ Topic: Packaging Content-Type: text/x-rst Created: 15-Aug-2019 Post-History: `15-Aug-2019 `__, - `17-Dec-2021 `__ + `17-Dec-2021 `__, .. _639-abstract: From d98339fc6868c1ad8d19dee4ea025509f0df132d Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Thu, 30 Jun 2022 21:05:12 -0500 Subject: [PATCH 03/11] PEP 639: Refer to pyproject.toml project table instead of PEP 621 --- pep-0639.rst | 174 ++++++++++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 77 deletions(-) diff --git a/pep-0639.rst b/pep-0639.rst index 7f14fd6794b..34e2f0408b7 100644 --- a/pep-0639.rst +++ b/pep-0639.rst @@ -37,7 +37,7 @@ The PEP also: and ``license ::`` :ref:`classifiers <639-spec-field-classifier>`. - :ref:`Adds and deprecates <639-spec-source-metadata>` the corresponding keys - in the :pep:`621` project source metadata format. + in the ``pyproject.toml`` ``[project]`` table. - :ref:`Provides clear guidance <639-spec-converting-metadata>` for authors and tools converting legacy license metadata, adding license files and @@ -53,7 +53,7 @@ The PEP also: The changes in this PEP will update the `core metadata `__ to version 2.4, modify the -`PEP 621 project metadata specification `__, +`project (source) metadata specification `__, and make minor additions to the `source distribution (sdist) `__, `built distribution (wheel) `__ and `installed project `__ standards. @@ -223,7 +223,7 @@ This PEP seeks to clearly define the terms it uses, given that some have multiple established meanings (e.g. import vs. distribution package, wheel *format* vs. Wheel *project*); are related and often used interchangeably, but have critical distinctions in meaning -(e.g. :pep:`621` *key* vs. core metadata *field*); are existing concepts +(e.g. ``[project]`` *key* vs. core metadata *field*); are existing concepts that don't have formal terms/definitions (e.g. project/source metadata vs. distribution/built metadata, build vs. publishing tools), or are new concepts introduced here (e.g. license expression/identifier). @@ -251,8 +251,8 @@ for the purposes of this PEP (``Syn:``). **Core Metadata Field** *(Short: Metadata Field/Field)* A single key-value pair, or sequence of such with the same key, as defined - by the core metadata specification. Notably, *not* a :pep:`621` project - metadata format key. + by the `core metadata specification `__. + Notably, distinct from a ``pyproject.toml`` ``[project]`` table *key*. **Distribution Package** *(Sub: Package, Distribution Archive)* (`See PyPUG `__) @@ -261,8 +261,10 @@ for the purposes of this PEP (``Syn:``). specifically references the physical **distribution archive**. **License Classifier** - A `PyPI Trove classifier `__ (as originally defined in - :pep:`301`) which begins with ``License ::``, currently used to indicate + A `PyPI Trove classifier `__ + (as `described in the core metadata specification + `__) + which begins with ``License ::``, currently used to indicate a project's license status by including it as a ``Classifier`` in the core metadata. @@ -285,18 +287,21 @@ for the purposes of this PEP (``Syn:``). project takes once installed from a distribution, as `specified by PyPA `__. -**Project Source Metadata** *(Sub: PEP 621 Metadata, Key, Subkey)* +**Project Source Metadata** *(Sub: Project Table Metadata, Key, Subkey)* Core metadata defined by the package author in the project source tree, - as top-level keys in the ``[project]`` table of a :pep:`621` ``pyproject.toml``, + as top-level keys in the ``[project]`` table of a ``pyproject.toml`` file, in the ``[metadata]`` table of ``setup.cfg``, or the equivalent for other build tools. - The **PEP 621 metadata** refers specifically to the former, as defined by the - `PyPA Declaring Project Metadata specification `__. - A **PEP 621 metadata key**, or an unqualified *key* refers specifically to - a top-level ``[project]`` key (notably, *not* a core metadata *field*), + The **Project Table Metadata**, or ``pyproject.toml`` ``[project]`` metadata, + refers specifically to the former, as defined by the + `PyPA Declaring Project Metadata specification `__ + and originally specified in :pep:`621`. + A **Project Table Key**, or an unqualified *key* refers specifically to + a top-level ``[project]`` key + (notably, distinct from a core metadata *field*), while a **subkey** refers to a second-level key in a table-valued - :pep:`621` key. + ``[project]`` key. **Root License Directory** *(Short: License Directory)* The directory under which license files are stored in a project/distribution @@ -329,7 +334,7 @@ for the purposes of this PEP (``Syn:``). **Wheel** *(Short: wheel, Rel: wheel format, Wheel project)* Here, **wheel**, the standard built distribution format introduced in - :pep:`427` and `specified by PyPA `__, will be referred to in + :pep:`427` and `specified by the PyPA `__, will be referred to in lowercase, while the `Wheel project `__, its reference implementation, will be referred to as such with **Wheel** in Title Case. @@ -344,7 +349,8 @@ this PEP include those in both :ref:`distribution package metadata <639-spec-core-metadata>`, as defined in the `core metadata specification `__, and :ref:`author-provided project source metadata <639-spec-source-metadata>`, -as originally defined in :pep:`621`. +as defined in the `project source metadata specification <_pep621spec>`__ +(and originally introduced in :pep:`621`). Further, :ref:`minor additions <639-spec-project-formats>` to the source distribution (sdist), built distribution (wheel) and installed project @@ -520,8 +526,8 @@ Deprecate license classifiers ''''''''''''''''''''''''''''' Using license `classifiers `__ in the ``Classifier`` field -(described in :pep:`301`) is deprecated and replaced by the more precise -``License-Expression`` field. +(`described in the core metadata specification `__) +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 @@ -553,7 +559,7 @@ Project source metadata As originally introduced in :pep:`621`, the `PyPA Declaring Project Metadata specification `__ defines how to declare a project's source -metadata in a ``[project]`` table in the ``pyproject.toml`` file for +metadata under a ``[project]`` table in the ``pyproject.toml`` file for build tools to consume and output distribution core metadata. This PEP :ref:`adds <639-spec-key-license-expression>` the ``license-expression`` @@ -566,9 +572,9 @@ key, :ref:`adds <639-spec-key-license-files>` the ``license-files`` key and Add ``license-expression`` key '''''''''''''''''''''''''''''' -A new ``license-expression`` key is added to the ``project`` table, which has -a string value that is a valid SPDX license expression, as -:ref:`defined previously <639-license-expression-definition>`. +A new ``license-expression`` key is added to the ``[project]`` table, +which has a string value that is a valid SPDX license expression, +as :ref:`defined previously <639-license-expression-definition>`. Its value maps to the ``License-Expression`` field in the core metadata. Build tools SHOULD validate the expression as described in the @@ -592,7 +598,7 @@ of the ``license-expression`` key. Add ``license-files`` key ''''''''''''''''''''''''' -A new ``license-files`` key is added to the ``project`` table for specifying +A new ``license-files`` key is added to the ``[project]`` table for specifying paths in the project source tree relative to ``pyproject.toml`` to file(s) containing licenses and other legal notices to be distributed with the package. It corresponds to the ``License-File`` fields in the core metadata. @@ -676,7 +682,7 @@ user has explicitly specified their own. Deprecate ``license`` key ''''''''''''''''''''''''' -The ``license`` key in the ``project`` table is now deprecated. +The ``license`` key in the ``[project]`` table is now deprecated. It MUST NOT be used or listed as ``dynamic`` if either of the new ``license-expression`` or ``license-files`` keys are defined, and build tools MUST raise an error if either is the case. @@ -756,13 +762,15 @@ each format, per the :ref:`639-spec-field-license-file` section. Converting legacy metadata -------------------------- -If the contents of the ``license.text`` :pep:`621` source metadata key +If the contents of the ``license.text`` +``[project]`` table key in ``pyproject.toml`` (or equivalent for tool-specific config formats) is a valid license expression -containing solely known, non-deprecated license identifiers, and, if -:pep:`621` metadata are defined, the ``license-expression`` key is listed as -``dynamic``, build tools MAY use it to fill the ``License-Expression`` field. +containing solely known, non-deprecated license identifiers, and +(if the ``[project]`` table is present) +the ``license-expression`` key is listed as ``dynamic``, +build tools MAY use it to fill the ``License-Expression`` field. -Similarly, if the ``classifiers`` :pep:`621` source metadata key (or equivalent +Similarly, if the ``classifiers`` ``[project]`` table key (or equivalent for tool-specific config formats) contains exactly one license classifier that unambiguously maps to exactly one valid, non-deprecated SPDX license identifier, tools MAY fill the ``License-Expression`` field with the latter. @@ -888,13 +896,14 @@ Backwards Compatibility ======================= Adding a new, dedicated ``License-Expression`` core metadata field and -``license-expression`` :pep:`621` source metadata key unambiguously signals -support for the specification in this PEP. This avoids the risk of new tooling +``license-expression`` key to the ``pyproject.toml`` ``[project]`` table +unambiguously signals support for the specification in this PEP. +This avoids the risk of new tooling misinterpreting a license expression as a free-form license description or vice versa, and raises an error if and only if the user affirmatively upgrades to the latest metadata version and adds the new field/key. -The legacy ``License`` core metadata field and ``license`` :pep:`621` source +The legacy ``License`` core metadata field and ``license`` project source metadata key will be deprecated along with the license classifiers, retaining backwards compatibility while gently preparing users for their future removal. Such a removal would follow a suitable transition period, and @@ -905,10 +914,10 @@ inclusion of the listed files in the distribution merely codifies and refines the existing practices in popular packaging tools, including the Wheel and Setuptools projects, and is designed to be largely backwards-compatible with their existing use of that field. Likewise, the new ``license-files`` -:pep:`621` source metadata key standardizes statically specifying the files -to include, as well as the default behavior, and allows other tools to -make use of them, while only having an effect once users and tools expressly -adopt it. +key in the ``[project]`` table of ``pyproject.toml`` +standardizes statically specifying the files to include, +as well as the default behavior, and allows other tools to make use of them, +while only having an effect once users and tools expressly adopt it. Due to requiring license files not be flattened into ``.dist-info`` and specifying that they should be placed in a dedicated ``license_files`` subdir, @@ -1220,14 +1229,14 @@ Source metadata ``license`` key ------------------------------- Alternate possibilities related to the ``license`` key in the -``pyproject.toml`` project source metadata specified in :pep:`621`. +``pyproject.toml`` project source metadata. Add ``expression`` and ``files`` subkeys to table ''''''''''''''''''''''''''''''''''''''''''''''''' A previous working draft of this PEP added ``expression`` and ``files`` subkeys -to the existing ``license`` table in the :pep:`621` source metadata, to parallel +to the existing ``license`` table in the project source metadata, to parallel the existing ``file`` and ``text`` subkeys. While this seemed perhaps the most obvious approach at first glance, it had several serious drawbacks relative to that ultimately taken here. @@ -1241,8 +1250,9 @@ This also breaks from the consensus for the core metadata fields, namely to separate the license expression into its own explicit field. Furthermore, this leads to a conflict with marking the key as ``dynamic`` -(assuming that is intended to specify :pep:`621` keys, as that PEP seems to rather -imprecisely imply, rather than core metadata fields), as either both would have +(assuming that is intended to specify the ``[project]`` table keys, +as that PEP seems to imprecisely imply, +rather than core metadata fields), as either both would have to be treated as ``dynamic``. A user may want to specify the ``expression`` key as ``dynamic``, if they intend their tooling to generate it automatically; conversely, they may rely on their build tool to dynamically detect license @@ -1256,9 +1266,9 @@ keep track of which fields are mutually exclusive with which of the others, greatly increasing cognitive and code complexity, and in turn the probability of errors. Conceptually, juxtaposing so many different fields under the same key is rather jarring, and leads to a much more complex mapping between -:pep:`621` keys and core metadata fields, not in keeping with :pep:`621`. -This causes the :pep:`621` naming and structure to diverge further from -both the core metadata and native formats of the various popular packaging +``[project]`` keys and core metadata fields, not in keeping with :pep:`621`. +This causes the ``[project]`` table naming and structure to diverge further +from both the core metadata and native formats of the various popular packaging tools that use it. Finally, this results in the spec being significantly more complex and convoluted to understand and implement than the alternatives. @@ -1268,7 +1278,8 @@ all the issues identified above, and results in a much clearer and cleaner design overall. It allows ``license`` and ``license-files`` to be tagged ``dynamic`` independently, separates two independent types of metadata (syntactically and semantically), restores a closer to 1:1 mapping of -:pep:`621` keys to core metadata fields, and reduces nesting by a level for both. +``[project]`` table keys to core metadata fields, +and reduces nesting by a level for both. Other than adding two extra keys to the file, there was no significant apparent downside to this latter approach, so it was adopted for this PEP. @@ -1294,13 +1305,17 @@ ultimately rejected, as it shared most of the downsides identified with adding new subkeys under the existing ``license`` table, as well as several of its own, with again minimal advantage over separating both. -Most importantly, it still means that per :pep:`621`, it is not possible to -separately mark the ``[project]`` keys corresponding to the ``License`` and -``License-Expression`` metadata fields as dynamic. This, in turn, still +Most importantly, it still means that per the +`project source metadata spec `__, +it is not possible to separately mark the ``[project]`` keys +corresponding to the ``License`` and ``License-Expression`` metadata fields +as ``dynamic``. +This, in turn, still renders specifying metadata following that standard incompatible with conversion of legacy metadata, as specified in this PEP's -:ref:`639-spec-converting-metadata`, as :pep:`621` strictly prohibits the -``license`` key from being both present (to define the existing value of +:ref:`639-spec-converting-metadata`, +as the project source metadata spec strictly prohibits the ``license`` key +from being both present (to define the existing value of the ``License`` field, or the path to a license file, and thus able to be converted), and specified as ``dynamic`` (which would allow tools to use the generated value for the ``License-Expression`` field. @@ -1309,7 +1324,7 @@ For the same reasons, this would make it impossible to back-fill the ``License`` field from the ``License-Expression`` field as this PEP currently allows (without making an exception from strict ``dynamic`` behavior in this case), as again, marking ``license`` as dynamic -would mean it cannot be specified in the ``project`` table at all. +would mean it cannot be specified in the ``[project]`` table at all. Furthermore, this would mean existing project source metadata specifying ``license`` as ``dynamic`` would be ambiguous, as it would be impossible for @@ -1367,7 +1382,7 @@ Add a ``type`` key to treat as expression ''''''''''''''''''''''''''''''''''''''''' Instead of creating a new top-level ``license-expression`` key in the -:pep:`621` source metadata, one could add a ``type`` subkey to the existing +``[project]`` table, one could add a ``type`` subkey to the existing ``license`` table to control whether ``text`` (or a string value) is interpreted as free-text or a license expression. This could make backward compatibility a little more seamless, as older tools could ignore @@ -1379,9 +1394,9 @@ alternative way that SPDX license expressions could be implemented. However, all the same downsides as in the previous item apply here, including greater complexity, a more complex mapping between the project source metadata and core metadata and inconsistency between the presentation -in tool config, :pep:`621` and core metadata, a much less clean deprecation, -further bikeshedding over what to name it, and inability to mark one but -not the other as dynamic, among others. +in tool config, project source metadata and core metadata, +a much less clean deprecation, further bikeshedding over what to name it, +and inability to mark one but not the other as dynamic, among others. In addition, while theoretically potentially a little easier in the short term, in the long term it would mean users would always have to remember @@ -1405,7 +1420,7 @@ to be automatically back-filled from the value of the ``license-expression`` key. This would be more explicit that the filling will be done, as strictly speaking the ``license`` key is not (and cannot be) specified in ``pyproject.toml``, and satisfies a stricter interpretation of the letter -of the current :pep:`621` specification that this PEP revises. +of the previous :pep:`621` specification that this PEP revises. However, this isn't seen to be necessary, because it is simply using the static, verbatim literal value of the ``license-expression`` key, as specified @@ -1430,7 +1445,7 @@ Source metadata ``license-files`` key ------------------------------------- Alternatives considered for the ``license-files`` key in the -:pep:`621` project source metadata, primarily related to the +``pyproject.toml`` ``[project]`` table, primarily related to the path/glob type handling. @@ -1438,7 +1453,7 @@ Add a ``type`` subkey to ``license-files`` '''''''''''''''''''''''''''''''''''''''''' Instead of defining mutually exclusive ``paths`` and ``globs`` subkeys -of the ``license-files`` :pep:`621` project metadata key, we could +of the ``license-files`` ``[project]`` table key, we could achieve the same effect with a ``files`` subkey for the list and a ``type`` subkey for how to interpret it. However, the latter offers no real advantage over the former, in exchange for requiring more keystrokes, @@ -1615,7 +1630,7 @@ Must be marked dynamic to use defaults '''''''''''''''''''''''''''''''''''''' It may seem outwardly sensible, at least with a particularly restrictive -interpretation of :pep:`621` 's description of the ``dynamic`` list, to +interpretation of :pep:`621`'s description of the ``dynamic`` list, to consider requiring the ``license-files`` key to be explicitly marked as ``dynamic`` in order for the default glob patterns to be used, or alternatively for license files to be matched and included at all. @@ -1640,8 +1655,9 @@ Finally, aside from adding an additional line of default-required boilerplate to the file, not defining the default as dynamic allows authors to clearly and unambiguously indicate when their build/packaging tools are going to be handling the inclusion of license files themselves rather than strictly -conforming to the :pep:`621` portions of this PEP; to do otherwise would defeat -the primary purpose of the ``dynamic`` list as a marker and escape hatch. +conforming to the project source metadata portions of this PEP; +to do otherwise would defeat the primary purpose of the ``dynamic`` list +as a marker and escape hatch. License file paths @@ -1668,10 +1684,10 @@ their specified license files have not been included. Furthermore, this leads to inconsistent relative file paths for non-root license files between the source, sdist and wheel, and prevents the paths -given in the :pep:`621` "static" metadata from being truly static, as they need -to be flattened, and may potentially overwrite one another. Finally, -the source directory structure often implies valuable information about -what the licenses apply to, and where to find them in the source, +given in the "static" ``[project]`` table metadata from being truly static, +as they need to be flattened, and may potentially overwrite one another. +Finally, the source directory structure often implies valuable information +about what the licenses apply to, and where to find them in the source, which is lost when flattening them and far from trivial to reconstruct. To resolve this, the PEP now proposes, as did contributors on both of the @@ -1796,9 +1812,9 @@ Both ``licenses`` and ``license_files`` have been suggested as potential names for the root license directory inside ``.dist-info`` of wheels and installed projects. The former is slightly shorter, but the latter is more clear and unambiguous regarding its contents, and is consistent with -the name of the core metadata field (``License-File``) and the :pep:`621` -project source metadata key (``license-files``). Therefore, the latter -was chosen instead. +the name of the core metadata field (``License-File``) and the +project source metadata key (``license-files``). +Therefore, the latter was chosen instead. Other ideas @@ -2022,7 +2038,7 @@ The simplest migration to this PEP would consist of using this instead: [metadata] license_expression = MIT -Or, in a :pep:`621` ``pyproject.toml``: +Or, in the ``[project]`` table of ``pyproject.toml``: .. code-block:: toml @@ -2107,8 +2123,8 @@ Putting it all together, our ``setup.cfg`` would be: setuptools/_vendor/packaging/LICENSE.APACHE setuptools/_vendor/packaging/LICENSE.BSD -In a :pep:`621` ``pyproject.toml``, with license files specified explicitly -via the ``paths`` subkey, this would look like: +In the ``[project]`` table of ``pyproject.toml``, with license files +specified explicitly via the ``paths`` subkey, this would look like: .. code-block:: toml @@ -2293,9 +2309,10 @@ should only need to make a couple of tweaks to take advantage of the new functionality. In your project config file, enter your license expression under -``license-expression`` (:pep:`621` ``pyproject.toml``), ``license_expression`` -(Setuptools ``setup.cfg`` / ``setup.py``), or the equivalent for your -packaging tool, and make sure to remove any legacy ``license`` value or +``license-expression`` (``[project]`` table in ``pyproject.toml``), +``license_expression`` (Setuptools ``setup.cfg`` / ``setup.py``), +or the equivalent for your 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 `__ for the identifier @@ -2333,10 +2350,11 @@ parenthesis (``()``) for grouping to form expressions that cover even the most complex situations. In your project config file, enter your license expression under -``license-expression`` (:pep:`621` ``pyproject.toml``), ``license_expression`` -(Setuptools ``setup.cfg`` / ``setup.py``), or the equivalent for your -packaging tool, and make sure to remove any legacy ``license`` value or -``License ::`` classifiers. +``license-expression`` (``[project]`` table of ``pyproject.toml``), +``license_expression`` (Setuptools ``setup.cfg`` / ``setup.py``), +or the equivalent for your packaging tool, +and make sure to remove any legacy ``license`` value +or ``License ::`` classifiers. Also, make sure you add the full license text of all the licenses as files somewhere in your project repository. If all of them are in the root directory @@ -2705,6 +2723,7 @@ References .. _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 +.. _coremetadataclassifiers: https://packaging.python.org/en/latest/specifications/core-metadata/#classifier-multiple-use .. _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/ @@ -2750,6 +2769,7 @@ References .. _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/ +.. _pep621specdynamic: https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#dynamic .. _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 From 2a24d3ebb64e2a6b67430765744f96c166eae319 Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Sun, 10 Jul 2022 01:30:57 -0500 Subject: [PATCH 04/11] PEP 639: Add short blurb explictly referencing terms from RFC 2119 --- pep-0639.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pep-0639.rst b/pep-0639.rst index 34e2f0408b7..8b378651044 100644 --- a/pep-0639.rst +++ b/pep-0639.rst @@ -234,6 +234,10 @@ This PEP also uses terms defined in the *project* and *source distribution*), and by the `SPDX Project `__ (*license identifier*, *license expression*). +The keywords "MUST", "MUST NOT", "REQUIRED", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" +in this document are to be interpreted as described in :rfc:`2119`. + Terms are listed here in their full versions; related words (``Rel:``) are in parenthesis, including short forms (``Short:``), sub-terms (``Sub:``) and common synonyms From b2bbbe70352a33c19ae06cff2c323b215765aa45 Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Thu, 30 Jun 2022 21:21:42 -0500 Subject: [PATCH 05/11] PEP 639: Tweak specifications for handling existing license.file value --- pep-0639.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pep-0639.rst b/pep-0639.rst index 8b378651044..6165fc46fa6 100644 --- a/pep-0639.rst +++ b/pep-0639.rst @@ -701,14 +701,14 @@ the ``license-files`` key instead. However, if the file is present in the source, build tools SHOULD still use it to fill the ``License-File`` field in the core metadata, and if so, MUST include the specified file in any distribution archives for the project. If the file does not exist at the -specified path, tools SHOULD issue a warning, and MUST NOT fill it in a -``License-File`` field. +specified path, tools MUST NOT fill it in a ``License-File`` field, +and SHOULD raise an error or, if not, MUST issue a warning. For backwards compatibility, to preserve consistent behavior with current tools and ensure that users do not unknowingly create packages that are not legally distributable, tools MUST assume the :ref:`specified default value <639-default-patterns>` for the -``license-files`` key and also include, in addition to the license file +``license-files`` key and also include, in addition to a license file specified under this ``file`` subkey, any license files that match the specified list of patterns. From e34c03f36d2f09279d761c1fa98438e7a21840bd Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Thu, 30 Jun 2022 21:52:38 -0500 Subject: [PATCH 06/11] PEP 639: Move description of status quo to Motivation & tweak text --- pep-0639.rst | 57 ++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/pep-0639.rst b/pep-0639.rst index 6165fc46fa6..aafc7c85607 100644 --- a/pep-0639.rst +++ b/pep-0639.rst @@ -121,8 +121,10 @@ binary distribution packages don't have :ref:`the same licenses Motivation ========== -All software is licensed, and providing accurate license information to Python -package users is an important matter. Today, there are multiple fields where +Software must be licensed in order for anyone other than its creator to +download, use, share and modify it, so providing accurate license information +to Python package users is an important matter. +Today, there are multiple fields where licenses are documented in core metadata, and there are limitations to what can be expressed in each of them. This often leads to confusion and a lack of clarity, both for package authors and end users. @@ -137,6 +139,29 @@ including on `outdated and ambiguous PyPI classifiers `__, `limited support for license files in the Wheel project `__, and `the lack of clear, precise and standardized license metadata `__. +The current license classifiers address some common cases, and could +theoretically be extended to include the full range of current SPDX +identifiers while deprecating the many ambiguous classifiers (including some +extremely popular and particularly problematic ones, such as +``License :: OSI Approved :: BSD License``). However, this both requires a +substantial amount of effort to duplicate the SPDX license list and keep +it in sync, and is effectively a hard break in backward compatibility, +forcing a huge proportion of package authors to immediately update to new +classifiers (in most cases, with many possible choices that require closely +examining the project's license) immediately when PyPI deprecates the old ones. + +Furthermore, this only covers simple packages entirely under a single license; +it doesn't address the substantial fraction of common projects that vendor +dependencies (e.g. Setuptools), offer a choice of licenses (e.g. Packaging) +or were relicensed, adapt code from other projects or contain fonts, images, +examples, binaries or other assets under other licenses. It also requires +both authors and tools understand and implement the PyPI-specific bespoke +classifier system, rather than using short, easy to add and standardized +SPDX identifiers in a simple text field, as increasingly widely adopted by +most other packaging systems to reduce the overall burden on the ecosystem. +Finally, this does not provide as clear an indicator that a package +has adopted the new system, and should be treated accordingly. + On average, Python packages tend to have more ambiguous and missing license information than other common ecosystems (such as npm, Maven or Gem). This is supported by the `statistics page `__ of the @@ -158,7 +183,8 @@ and license documentation in a variety of other packaging systems, Linux distros, languages ecosystems and applications is surveyed in :ref:`another appendix <639-license-doc-other-projects>`. -There are a few takeaways from the survey: +There are a few takeaways from the survey, which have guided the design +and recommendations of this PEP: - Most package formats use a single ``License`` field. @@ -174,31 +200,6 @@ There are a few takeaways from the survey: Open Source Software licenses require package authors to include their full text in a distribution. -These considerations have guided the design and recommendations of this PEP. - -The current license classifiers cover some common cases, and could -theoretically be extended to include the full range of current SPDX -identifiers while deprecating the many ambiguous classifiers (including some -extremely popular and particularly problematic ones, such as -``License :: OSI Approved :: BSD License``). However, this both requires a -substantial amount of effort to duplicate the SPDX license list and keep -it in sync, and is effectively a hard break in backward compatibility, -forcing a huge proportion of package authors to immediately update to new -classifiers (in most cases, with many possible choices that require closely -examining the project's license) immediately when PyPI deprecates the old ones. - -Furthermore, this only covers simple packages entirely under a single license; -it doesn't address the substantial fraction of common projects that vendor -dependencies (e.g. Setuptools), offer a choice of licenses (e.g. Packaging) -or were relicensed, adapt code from other projects or contain fonts, images, -examples, binaries or other assets under other licenses. It also requires -both authors and tools understand and implement the PyPI-specific bespoke -classifier system, rather than using short, easy to add and standardized -SPDX identifiers in a simple text field, as increasingly widely adopted by -most other packaging systems to reduce the overall burden on the ecosystem. -Finally, this does not provide as clear an indicator that a package -has adopted the new system, and should be treated accordingly. - The use of a new ``License-Expression`` field will provide an intuitive, structured and unambiguous way to express the license of a package using a well-defined syntax and well-known license identifiers. From 0962fe04619185c8c8c8a4d8e5ae3539d403a76a Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Thu, 30 Jun 2022 21:53:56 -0500 Subject: [PATCH 07/11] PEP 639: Mention implementations of this PEP in Hatch & Setuptools --- pep-0639.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pep-0639.rst b/pep-0639.rst index aafc7c85607..1b846585450 100644 --- a/pep-0639.rst +++ b/pep-0639.rst @@ -208,6 +208,15 @@ way to ensure that the full text of the license(s) are included with the package when distributed, as legally required, and allows other tools consuming the core metadata to unambiguously locate a distribution's license files. +While dramatically simplifying and improving the present Python license +metadata story, this specification standardizes and builds upon +existing practice in the `Setuptools `__ and +`Wheel `__ projects. +Furthermore, an up-to-date version of the current draft of this PEP is +`already successfully implemented `__ in the popular +PyPA `Hatch `__ packaging tool, and an earlier draft of the +license files portion is `implemented in Setuptools `__. + Over time, encouraging the use of these fields and deprecating the ambiguous, duplicative and confusing legacy alternatives will help Python software publishers improve the clarity, accuracy and portability of their licensing @@ -2751,6 +2760,8 @@ References .. _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 +.. _hatch: https://hatch.pypa.io/latest/ +.. _hatchimplementation: https://discuss.python.org/t/12622/22 .. _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/ From 9b90b35477941117d6f59add7cd6113c156d6ccc Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Thu, 30 Jun 2022 22:04:09 -0500 Subject: [PATCH 08/11] PEP 639: Rename licence_files license directory to just licenses --- pep-0639.rst | 54 +++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/pep-0639.rst b/pep-0639.rst index 1b846585450..c67f7aaeb10 100644 --- a/pep-0639.rst +++ b/pep-0639.rst @@ -322,8 +322,8 @@ for the purposes of this PEP (``Syn:``). and the root directory that their paths, as recorded under the ``License-File`` core metadata fields, are relative to. Defined here to be the project root directory for source trees and source - distributions, and a subdirectory named ``license_files`` of the directory - containing the core metadata (i.e., the ``.dist-info/license_files`` + distributions, and a subdirectory named ``licenses`` of the directory + containing the core metadata (i.e., the ``.dist-info/licenses`` directory) for built distributions and installed projects. **Tool** *(Sub: Packaging Tool, Build Tool, Install Tool, Publishing Tool)* @@ -756,17 +756,17 @@ each format, per the :ref:`639-spec-field-license-file` section. The `wheel specification `__ will be updated to reflect that if the ``Metadata-Version`` is ``2.4`` 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 + contain a ``licenses`` subdirectory, which MUST contain the files listed in the ``License-File`` fields in the ``METADATA`` file at their respective - paths relative to the ``license_files`` directory. + paths relative to the ``licenses`` directory. **Installed projects** The `Recording Installed Projects specification `__ will be updated to reflect that if the ``Metadata-Version`` is ``2.4`` or greater and one or more ``License-File`` fields is specified, the ``.dist-info`` - directory MUST contain a ``license_files`` subdirectory which MUST contain + directory MUST contain a ``licenses`` subdirectory which MUST contain the files listed in the ``License-File`` fields in the ``METADATA`` file - at their respective paths relative to the ``license_files`` directory, + at their respective paths relative to the ``licenses`` directory, and that any files in this directory MUST be copied from wheels by install tools. @@ -934,7 +934,7 @@ as well as the default behavior, and allows other tools to make use of them, while only having an effect once users and tools expressly adopt it. Due to requiring license files not be flattened into ``.dist-info`` and -specifying that they should be placed in a dedicated ``license_files`` subdir, +specifying that they should be placed in a dedicated ``licenses`` subdir, wheels produced following this change will have differently-located licenses relative to those produced via the previous unspecified, installer-specific behavior, but as until this PEP there was no way of @@ -1712,7 +1712,7 @@ directory. There is still a risk of collision with edge-case custom filenames (e.g. ``RECORD``, ``METADATA``), but that is also the case with the previous approach, and in fact with fewer files flattened into the root, this would actually reduce the risk. Furthermore, -the following proposal rooting the license files under a ``license_files`` +the following proposal rooting the license files under a ``licenses`` subdirectory eliminates both collisions and the clutter problem entirely. @@ -1759,7 +1759,7 @@ without having to reference each of their paths from the core metadata. 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 +relative to a ``licenses`` subdirectory of ``.dist-info``. This is simple to implement and solves all the problems noted here, without clear significant drawbacks relative to other more complex options. @@ -1783,7 +1783,7 @@ Therefore, the latter has been incorporated into current drafts of this PEP. Add new ``licenses`` category to wheel '''''''''''''''''''''''''''''''''''''' -Instead of defining a root license directory (``license_files``) inside +Instead of defining a root license directory (``licenses``) inside the core metadata directory (``.dist-info``) for wheels, we could instead define a new category (and, presumably, a corresponding install scheme), similar to the others currently included under ``.data`` in the wheel archive, @@ -1819,16 +1819,18 @@ and decided that would avoid name clashes. Therefore, to keep this PEP in scope, the current approach was retained. -Name the subdirectory ``licenses`` -'''''''''''''''''''''''''''''''''' +Name the subdirectory ``license_files`` +''''''''''''''''''''''''''''''''''''''' Both ``licenses`` and ``license_files`` have been suggested as potential names for the root license directory inside ``.dist-info`` of wheels and -installed projects. The former is slightly shorter, but the latter is -more clear and unambiguous regarding its contents, and is consistent with -the name of the core metadata field (``License-File``) and the -project source metadata key (``license-files``). -Therefore, the latter was chosen instead. +installed projects. An initial draft of the PEP specified the former +due to being slightly clearer and consistent with the +name of the core metadata field (``License-File``) +and the ``[project]`` table key (``license-files``). +However, the current version of the PEP adopts the ``license`` name, +due to a general preference by the community for its shorter length, +greater simplicity and the lack of a separator character (``_``, ``-``, etc.). Other ideas @@ -2067,7 +2069,7 @@ The output core metadata for the distribution packages would then be: License-File: LICENSE The ``LICENSE`` file would be stored at ``/setuptools-${VERSION}/LICENSE`` -in the sdist and ``/setuptools-${VERSION}.dist-info/license_files/LICENSE`` +in the sdist and ``/setuptools-${VERSION}.dist-info/licenses/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 and ``${VERSION}`` the version of the Setuptools release in the core metadata. @@ -2189,20 +2191,20 @@ In the built wheel, with ``/`` being the root of the archive and .. code-block:: shell - /setuptools-${VERSION}.dist-info/license_files/LICENSE - /setuptools-${VERSION}.dist-info/license_files/setuptools/_vendor/packaging/LICENSE - /setuptools-${VERSION}.dist-info/license_files/setuptools/_vendor/packaging/LICENSE.APACHE - /setuptools-${VERSION}.dist-info/license_files/setuptools/_vendor/packaging/LICENSE.BSD + /setuptools-${VERSION}.dist-info/licenses/LICENSE + /setuptools-${VERSION}.dist-info/licenses/setuptools/_vendor/packaging/LICENSE + /setuptools-${VERSION}.dist-info/licenses/setuptools/_vendor/packaging/LICENSE.APACHE + /setuptools-${VERSION}.dist-info/licenses/setuptools/_vendor/packaging/LICENSE.BSD Finally, in the installed project, with ``site-packages`` being the site dir and ``{version}`` as the previous, the license files would be installed to: .. code-block:: shell - site-packages/setuptools-${VERSION}.dist-info/license_files/LICENSE - site-packages/setuptools-${VERSION}.dist-info/license_files/setuptools/_vendor/packaging/LICENSE - site-packages/setuptools-${VERSION}.dist-info/license_files/setuptools/_vendor/packaging/LICENSE.APACHE - site-packages/setuptools-${VERSION}.dist-info/license_files/setuptools/_vendor/packaging/LICENSE.BSD + site-packages/setuptools-${VERSION}.dist-info/licenses/LICENSE + site-packages/setuptools-${VERSION}.dist-info/licenses/setuptools/_vendor/packaging/LICENSE + site-packages/setuptools-${VERSION}.dist-info/licenses/setuptools/_vendor/packaging/LICENSE.APACHE + site-packages/setuptools-${VERSION}.dist-info/licenses/setuptools/_vendor/packaging/LICENSE.BSD .. _639-example-conversion: From b6bb2b6618298fa39ed2c6a8e9c1884fe0d20b56 Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Sun, 10 Jul 2022 13:54:30 -0500 Subject: [PATCH 09/11] PEP 639: Simply conversion guidance and don't focus on at build-time --- pep-0639.rst | 198 ++++++++++++++++++--------------------------------- 1 file changed, 69 insertions(+), 129 deletions(-) diff --git a/pep-0639.rst b/pep-0639.rst index c67f7aaeb10..45d4b60ebc1 100644 --- a/pep-0639.rst +++ b/pep-0639.rst @@ -596,11 +596,6 @@ Build tools SHOULD validate the expression as described in the an error or warning as specified. When generating the core metadata, tools MUST perform case normalization. -If and only if the ``license-expression`` key is listed as ``dynamic`` -(and is not specified), tools MAY infer a value for the ``License-Expression`` -field if they can do so unambiguously, but MUST follow the provisions in the -:ref:`639-spec-converting-metadata` section. - If the ``license-expression`` key is present and valid (and the ``license`` key is not specified), for purposes of backward compatibility, tools MAY back-fill the ``License`` core metadata field with the case-normalized value @@ -776,37 +771,13 @@ each format, per the :ref:`639-spec-field-license-file` section. Converting legacy metadata -------------------------- -If the contents of the ``license.text`` -``[project]`` table key in ``pyproject.toml`` -(or equivalent for tool-specific config formats) is a valid license expression -containing solely known, non-deprecated license identifiers, and -(if the ``[project]`` table is present) -the ``license-expression`` key is listed as ``dynamic``, -build tools MAY use it to fill the ``License-Expression`` field. - -Similarly, if the ``classifiers`` ``[project]`` table key (or equivalent -for tool-specific config formats) contains exactly one license classifier -that unambiguously maps to exactly one valid, non-deprecated SPDX license -identifier, tools MAY fill the ``License-Expression`` field with the latter. - -If both a ``license.text`` or equivalent value and a single license classifier -are present, the contents of the former, including capitalization -(but excluding leading and trailing whitespace), MUST exactly match the SPDX -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 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 project source metadata be updated accordingly -with the indicated license expression. - -In any other case, tools MUST NOT use the contents of the ``license.text`` -key (or equivalent) or license classifiers to fill the -``License-Expression`` field without informing the user and requiring -unambiguous, affirmative user action to select and confirm the desired -``License-Expression`` value before proceeding. +Tools MUST NOT use the contents of the ``license.text`` ``[project]`` key +(or equivalent tool-specific format), +license classifiers or the value of the core metadata ``License`` field +to fill the top-level string value of the ``license`` key `` +or the core metadata ``License-Expression`` field +without informing the user and requiring unambiguous, affirmative user action +to select and confirm the desired license expression value before proceeding. .. _639-spec-mapping-classifiers-identifiers: @@ -815,19 +786,19 @@ 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 -:ref:`specification above <639-spec-converting-metadata>`. - -Many legacy license classifiers intend to specify a particular license, +map to a single valid SPDX license identifier, +allowing tools to infer the SPDX license identifier they correspond to, +both for use when analyzing and auditing packages, +and providing a semi-automated mechanism of filling the ``license`` key +or the the ``License-Expression`` field +following the :ref:`specification above <639-spec-converting-metadata>`. + +Some legacy license classifiers intend to specify a particular license, but do not specify the particular version or variant, leading to a -`critical ambiguity `__ 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: +`critical ambiguity `__ +as to their terms, compatibility and acceptability. +Tools MUST NOT attempt to automatically infer a ``License-Expression`` +when one of these classifiers is used without affirmative user action: - ``License :: OSI Approved :: Academic Free License (AFL)`` - ``License :: OSI Approved :: Apache Software License`` @@ -850,12 +821,14 @@ 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. -**Note**: Several additional classifiers, namely the "or later" variants of -the AGPLv3, GPLv2, GPLv3 and LGPLv3, are also listed in the aforementioned -mapping, but as they were merely proposed for textual harmonization and -still unambiguously map to their respective licenses, -they were not included here; LGPLv2 is, however, as it could ambiguously -refer to either the distinct v2.0 or v2.1 variants of that license. +.. note:: + + Several additional classifiers, namely the "or later" variants of + the AGPLv3, GPLv2, GPLv3 and LGPLv3, are also listed in the aforementioned + mapping, but unambiguously map to their respective licenses, + and so are not listed here. + However, LGPLv2 is included above, as it could ambiguously + refer to either the distinct v2.0 or v2.1 variants of that license. In addition, for the various special cases, the following mappings are considered canonical and normative for the purposes of this specification: @@ -870,38 +843,39 @@ considered canonical and normative for the purposes of this specification: 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 these classifiers as ambiguous and - require user confirmation to fill ``License-Expression`` in these cases. - -- The generic and sometimes ambiguous classifiers - ``License :: Free For Educational Use``, - ``License :: Free For Home Use``, - ``License :: Free for non-commercial use``, - ``License :: Freely Distributable``, - ``License :: Free To Use But Restricted``, - ``License :: Freeware``, and - ``License :: Other/Proprietary License`` MAY be mapped to the generic + Alternatively, tools MAY choose to treat these classifiers as ambiguous. + +- The generic and sometimes ambiguous classifiers: + + - ``License :: Free For Educational Use`` + - ``License :: Free For Home Use`` + - ``License :: Free for non-commercial use`` + - ``License :: Freely Distributable`` + - ``License :: Free To Use But Restricted`` + - ``License :: Freeware`` + - ``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 these classifiers as ambiguous and - require user confirmation to fill ``License-Expression`` in these cases. + Alternatively, tools MAY choose to treat these classifiers as ambiguous. - The generic and ambiguous classifiers ``License :: OSI Approved`` and ``License :: DFSG approved`` do not map to any license expression, - and thus tools MUST treat them as ambiguous and require user intervention - to fill ``License-Expression``. + and thus tools SHOULD treat them as ambiguous, or if not MUST ignore them. - 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 - ``License-Expression``. + identifiers, and no PyPI package uses them as of 2022-07-09. When multiple license classifiers are used, their relationship is ambiguous, and it is typically not possible to determine if all the licenses apply or if -there is a choice that is possible among the licenses. In this case, tools -MUST NOT automatically infer a license expression, and SHOULD suggest that the -package author construct one which expresses their intent. +there is a choice that is possible among the licenses, +In this case, tools MUST NOT automatically infer a license expression, +unless one license classifier is a parent of the other, +i.e. the child contains all ``::``-delineated components of the parent, +in which case tools MAY ignore the parent classifier +but SHOULD issue an informative warning when doing so. .. _639-backwards-compatibility: @@ -1014,12 +988,19 @@ many, if not most common cases: tool authors with guidelines on how to suggest a license expression produced from legacy classifiers. -- Tools may also be able to infer and suggest how to update an existing - ``License`` value and convert that to a ``License-Expression``. - For instance, a tool may suggest converting from a ``License`` field with - ``Apache2`` (which is not a valid license expression as defined in this PEP) - to a ``License-Expression`` field with ``Apache-2.0`` (which is a valid - license expression using an SPDX license identifier). +- Tools may also be able to infer and suggest how to update + an existing ``License`` value in project source metadata + and convert that to a license expression, + as also :ref:`specified in this PEP <639-spec-converting-metadata>`. + For instance, a tool may suggest converting a value of ``MIT`` + in the ``license.text`` key in ``[project]`` + (or the equivalent in tool-specific formats) + to a top-level string value of the ``license`` key (or equivalent). + Likewise, a tool could suggest converting from a ``License`` of ``Apache2`` + (which is not a valid license expression + as :ref:`defined in this PEP <639-spec-field-license-expression>`) + to a ``License-Expression`` of ``Apache-2.0`` + (the equivalent valid license expression using an SPDX license identifier). .. _639-reference-implementation: @@ -1319,25 +1300,15 @@ ultimately rejected, as it shared most of the downsides identified with adding new subkeys under the existing ``license`` table, as well as several of its own, with again minimal advantage over separating both. -Most importantly, it still means that per the +Also, this still means that per the `project source metadata spec `__, it is not possible to separately mark the ``[project]`` keys corresponding to the ``License`` and ``License-Expression`` metadata fields as ``dynamic``. -This, in turn, still -renders specifying metadata following that standard incompatible with -conversion of legacy metadata, as specified in this PEP's -:ref:`639-spec-converting-metadata`, -as the project source metadata spec strictly prohibits the ``license`` key -from being both present (to define the existing value of -the ``License`` field, or the path to a license file, and thus able to be -converted), and specified as ``dynamic`` (which would allow tools to -use the generated value for the ``License-Expression`` field. - -For the same reasons, this would make it impossible to back-fill the -``License`` field from the ``License-Expression`` field as this PEP -currently allows (without making an exception from strict -``dynamic`` behavior in this case), as again, marking ``license`` as dynamic +This raises a potential concern with back-filling the ``License`` field +from the ``License-Expression`` field as this PEP currently allows +(without making an exception from strict ``dynamic`` behavior in this case), +as marking ``license`` as dynamic would mean it cannot be specified in the ``[project]`` table at all. Furthermore, this would mean existing project source metadata specifying @@ -2024,8 +1995,8 @@ determined to be unnecessary or too problematic in practice. .. _639-examples: -Appendix: License Expression Examples -===================================== +Appendix: Examples +================== .. _639-example-basic: @@ -2207,37 +2178,6 @@ and ``{version}`` as the previous, the license files would be installed to: site-packages/setuptools-${VERSION}.dist-info/licenses/setuptools/_vendor/packaging/LICENSE.BSD -.. _639-example-conversion: - -Conversion example ------------------- - -Suppose we were to return to our simple Setuptools case. -Per the specification, given it only has the following license classifier: - -.. code-block:: email - - Classifier: License :: OSI Approved :: MIT License - -And no value for the ``License`` field, or equivalently, if it had a -value of: - -.. code-block:: email - - License: MIT - -Then the suggested value for the ``License-Expression`` field would be: - -.. code-block:: email - - License-Expression: MIT - -For the more complex case, assuming it was currently expressed as multiple -license classifiers, no automatic conversion could be performed due to the -inherent ambiguity, and the user would be prompted on how to handle the -situation themselves. - - .. _639-example-expression: Expression examples From e59ccc97bc3423c83c3699767514f8ba1df07fb6 Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Sun, 10 Jul 2022 15:28:00 -0500 Subject: [PATCH 10/11] PEP 639: Use flat string value of license for expression, not new key --- pep-0639.rst | 325 ++++++++++++++++++++++++++------------------------- 1 file changed, 164 insertions(+), 161 deletions(-) diff --git a/pep-0639.rst b/pep-0639.rst index 45d4b60ebc1..c183c17ca0e 100644 --- a/pep-0639.rst +++ b/pep-0639.rst @@ -576,30 +576,34 @@ defines how to declare a project's source metadata under a ``[project]`` table in the ``pyproject.toml`` file for build tools to consume and output distribution core metadata. -This PEP :ref:`adds <639-spec-key-license-expression>` the ``license-expression`` -key, :ref:`adds <639-spec-key-license-files>` the ``license-files`` key and -:ref:`deprecates <639-spec-key-license>` the ``license`` key. +This PEP :ref:`adds <639-spec-key-license-expression>` +a top-level string value for the ``license`` key, +:ref:`adds <639-spec-key-license-files>` the new ``license-files`` key +and :ref:`deprecates <639-spec-key-license>` +the table value for the ``license`` key +along with its corresponding table subkeys, ``text`` and ``file``. .. _639-spec-key-license-expression: -Add ``license-expression`` key -'''''''''''''''''''''''''''''' +Add string value to ``license`` key +''''''''''''''''''''''''''''''''''' -A new ``license-expression`` key is added to the ``[project]`` table, -which has a string value that is a valid SPDX license expression, +A top-level string value is defined +for the ``license`` key in the ``[project]`` table, +which specified to be a valid SPDX license expression, as :ref:`defined previously <639-license-expression-definition>`. Its value maps to the ``License-Expression`` field in the core metadata. Build tools SHOULD validate the expression as described in the -:ref:`639-spec-field-license-expression` section, outputting -an error or warning as specified. When generating the core metadata, tools -MUST perform case normalization. +:ref:`639-spec-field-license-expression` section, +outputting an error or warning as specified. +When generating the core metadata, tools MUST perform case normalization. -If the ``license-expression`` key is present and valid (and the ``license`` -key is not specified), for purposes of backward compatibility, tools MAY -back-fill the ``License`` core metadata field with the case-normalized value -of the ``license-expression`` key. +If a top-level string value for the ``license`` key is present and valid, +for purposes of backward compatibility +tools MAY back-fill the ``License`` core metadata field +with the normalized value of the ``license`` key. .. _639-spec-key-license-files: @@ -688,37 +692,39 @@ user has explicitly specified their own. .. _639-spec-key-license: -Deprecate ``license`` key -''''''''''''''''''''''''' - -The ``license`` key in the ``[project]`` table is now deprecated. -It MUST NOT be used or listed as ``dynamic`` if either of the new -``license-expression`` or ``license-files`` keys are defined, -and build tools MUST raise an error if either is the case. - -Otherwise, if the ``text`` subkey is present in the ``license`` table, tools -SHOULD issue a warning informing users it is deprecated and recommending the -``license-expression`` key instead. - -Likewise, if the ``file`` subkey is present in the ``license`` table, tools -SHOULD issue a warning informing users it is deprecated and recommending -the ``license-files`` key instead. However, if the file is present in the -source, build tools SHOULD still use it to fill the ``License-File`` field -in the core metadata, and if so, MUST include the specified file in any -distribution archives for the project. If the file does not exist at the -specified path, tools MUST NOT fill it in a ``License-File`` field, -and SHOULD raise an error or, if not, MUST issue a warning. - -For backwards compatibility, to preserve consistent behavior with current tools -and ensure that users do not unknowingly create packages that are not legally -distributable, tools MUST assume the -:ref:`specified default value <639-default-patterns>` for the -``license-files`` key and also include, in addition to a license file -specified under this ``file`` subkey, any license files that match the -specified list of patterns. +Deprecate ``license`` key table subkeys +''''''''''''''''''''''''''''''''''''''' -The ``license`` key may be removed from a new version of the specification -in a future PEP. +Table values for the ``license`` key in the ``[project]`` table, +including the ``text`` and ``file`` table subkeys, is now deprecated. +If the new ``license-files`` key is present, +build tools MUST raise an error if the ``license`` key is defined +and has a value other than a single top-level string. + +If the new ``license-files`` key is not present +and the ``text`` subkey is present in a ``license`` table, +tools SHOULD issue a warning informing users it is deprecated +and recommending a license expression as a top-level string key instead. + +Likewise, if the new ``license-files`` key is not present +and the ``file`` subkey is present in the ``license`` table, +tools SHOULD issue a warning informing users it is deprecated and recommending +the ``license-files`` key instead. + +If the specified license ``file`` is present in the source tree, +build tools SHOULD use it to fill the ``License-File`` field +in the core metadata, and MUST include the specified file +as if it were specified in a ``license-file.paths`` field. +If the file does not exist at the specified path, +tools MUST raise an informative error as previously specified. +However, tools MUST also still assume the +:ref:`specified default value <639-default-patterns>` +for the ``license-files`` key and also include, +in addition to a license file specified under the ``license.file`` subkey, +any license files that match the specified list of patterns. + +Table values for the ``license`` key MAY be removed +from a new version of the specification in a future PEP. .. _639-spec-project-formats: @@ -883,16 +889,19 @@ but SHOULD issue an informative warning when doing so. Backwards Compatibility ======================= -Adding a new, dedicated ``License-Expression`` core metadata field and -``license-expression`` key to the ``pyproject.toml`` ``[project]`` table +Adding a new, dedicated ``License-Expression`` core metadata field +and a top-level string value for the ``license`` key reserved for this purpose +in the ``pyproject.toml`` ``[project]`` table unambiguously signals support for the specification in this PEP. This avoids the risk of new tooling misinterpreting a license expression as a free-form license description or vice versa, and raises an error if and only if the user affirmatively upgrades to the latest metadata version and adds the new field/key. -The legacy ``License`` core metadata field and ``license`` project source -metadata key will be deprecated along with the license classifiers, +The legacy ``License`` core metadata field +and the ``license`` key table subkeys (``text`` and ``file``) +in the ``pyproject.toml`` ``[project]`` table +will be deprecated along with the license classifiers, retaining backwards compatibility while gently preparing users for their future removal. Such a removal would follow a suitable transition period, and be left to a future PEP and a new version of the core metadata specification. @@ -978,7 +987,7 @@ For authors still using the now-deprecated, less precise and more redundant ``License`` field or license classifiers, packaging tools will warn them and inform them of the modern replacement, ``License-Expression``. Finally, for users who may have forgotten or not be aware they need to do so, -publishing tools will gently guide them toward including ``license-expression`` +publishing tools will gently guide them toward including ``license`` and ``license-files`` in their project source metadata. Tools may also help with the conversion and suggest a license expression in @@ -1154,7 +1163,7 @@ dig through the list to figure out which one(s) apply (and be confused by many ambiguous options), or figure out on their own what should go in the ``license`` key (anything from nothing, to the license text, to a free-form description, to the same SPDX identifier they would be -entering in the ``license-expression`` key anyway, assuming they can +entering in the ``license`` 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 `__ links to how to add SPDX license @@ -1241,20 +1250,14 @@ specified under the same top-level key that require very different handling, and furthermore, unlike the previous arrangement, the subkeys were not mutually exclusive and can both be specified at once, and with some subkeys potentially being dynamic and others static, and mapping to different core metadata fields. -This also breaks from the consensus for the core metadata fields, namely to -separate the license expression into its own explicit field. Furthermore, this leads to a conflict with marking the key as ``dynamic`` (assuming that is intended to specify the ``[project]`` table keys, as that PEP seems to imprecisely imply, rather than core metadata fields), as either both would have -to be treated as ``dynamic``. A user may want to specify the ``expression`` -key as ``dynamic``, if they intend their tooling to generate it automatically; -conversely, they may rely on their build tool to dynamically detect license -files via means outside of that strictly specified here. And indeed, current -users may mark the present ``license`` key as ``dynamic`` to automatically -fill it in the metadata. Grouping all these uses under the same key forces an -"all or nothing" approach, and creates ambiguity as to user intent. +to be treated as ``dynamic``. +Grouping both license expressions and license files under the same key +forces an "all or nothing" approach, and creates ambiguity as to user intent. There are further downsides to this as well. Both users and tools would need to keep track of which fields are mutually exclusive with which of the others, @@ -1267,108 +1270,106 @@ from both the core metadata and native formats of the various popular packaging tools that use it. Finally, this results in the spec being significantly more complex and convoluted to understand and implement than the alternatives. -The approach this PEP now takes, adding distinct ``license-expression`` and -``license-files`` keys and simply deprecating the whole ``license`` key, avoids -all the issues identified above, and results in a much clearer and cleaner -design overall. It allows ``license`` and ``license-files`` to be tagged +The approach this PEP now takes, using the reserved top-level string value +of the ``license`` key, adding a new ``license-files`` key +and deprecating the ``license`` table subkeys (``text`` and ``file``), +avoids most of the issues identified above, +and results in a much clearer and cleaner design overall. +It allows ``license`` and ``license-files`` to be tagged ``dynamic`` independently, separates two independent types of metadata (syntactically and semantically), restores a closer to 1:1 mapping of ``[project]`` table keys to core metadata fields, and reduces nesting by a level for both. -Other than adding two extra keys to the file, there was no significant +Other than adding one extra key to the file, there was no significant apparent downside to this latter approach, so it was adopted for this PEP. -Define license expression as string value -''''''''''''''''''''''''''''''''''''''''' +Add an ``expression`` subkey instead of a string value +'''''''''''''''''''''''''''''''''''''''''''''''''''''' + +Adding just an ``expression`` subkey to the ``license`` table, +instead of using the reserved top-level string value, +would be more explicit for readers and writers, +in line with this PEP's goals. +However, it still has the downsides listed above +that are not specific to the inclusion of the ``files`` key. + +Relative to a flat string value, +it adds verbosity, complexity and an extra level of nesting, +and requires users and tools to remember and handle +the mutual exclusivity of the subkeys +and remember which are deprecated and which are not, +instead of cleanly deprecating the table subkeys as a whole. +Furthermore, it is less clearly the "default" choice for modern use, +given users tend to gravitate toward the simplest and most obvious option. +Finally, it seems reasonable to follow the suggested guidance in :pep:`621`, +given the top-level string value was specifically reserved for this purpose. + + +Define a new top-level ``license-expression`` key +''''''''''''''''''''''''''''''''''''''''''''''''' + +An earlier version of this PEP defined a new, top-level ``license-expression`` +under the ``[project]`` table, +rather than using the reserved string value of the ``license`` key. +This was seen as clearer and more explicit for readers and writers, +in line with the goals of this PEP. + +Additionally, while differences from existing tool formats (and core metadata +field names) has precedent in :pep:`621`, +using a key with an identical name as in most/all current tools +to mean something different (and map to a different core metadata field), +with distinct and incompatible syntax and semantics, does not, +and could cause confusion and ambiguity for readers and authors. + +Also, per the `project source metadata spec `__, +this would allow separately marking the ``[project]`` keys +corresponding to the ``License`` and ``License-Expression`` metadata fields +as ``dynamic``, +avoiding a potential concern with back-filling the ``License`` field +from the ``License-Expression`` field as this PEP currently allows +without it as ``license`` as dynamic +(which would not be possible, since they both map to the same top-level key). -A compromise approach between adding two new top-level keys for license -expressions and files would be adding a separate ``license-files`` key, -but re-using the ``license`` key for the license expression, either by -defining it as the (previously reserved) string value for the ``license`` -key, retaining the ``expression`` subkey in the ``license`` table, or -allowing both. Indeed, this would seem to have been envisioned by :pep:`621` -itself with this PEP in mind, in particular the first approach: +However, community consensus was in favor instead using +the top-level string value of the existing ``license`` key, +as :pep:`reserved for this purpose by PEP 621 <621#license>`: A practical string value for the license key has been purposefully left out to allow for a future PEP to specify support for SPDX expressions (the same logic applies to any sort of "type" field specifying what license the file or text represents). -However, while a working draft temporarily explored this solution, it was -ultimately rejected, as it shared most of the downsides identified with -adding new subkeys under the existing ``license`` table, as well as several -of its own, with again minimal advantage over separating both. +This is shorter and simpler for users to remember and type, +avoids adding a new top-level key while taking advantage of an existing one, +guides users toward using a license expression as the default, +and follows what was envisioned in the original :pep:`621`. -Also, this still means that per the -`project source metadata spec `__, -it is not possible to separately mark the ``[project]`` keys -corresponding to the ``License`` and ``License-Expression`` metadata fields -as ``dynamic``. -This raises a potential concern with back-filling the ``License`` field -from the ``License-Expression`` field as this PEP currently allows -(without making an exception from strict ``dynamic`` behavior in this case), -as marking ``license`` as dynamic -would mean it cannot be specified in the ``[project]`` table at all. - -Furthermore, this would mean existing project source metadata specifying -``license`` as ``dynamic`` would be ambiguous, as it would be impossible for -tools to statically determine if they are intended to conform to previous -metadata versions specifying ``License``, or this version specifying -``License-Expression``. Tools would have no way of determining which field, -if either, might be filled in the resulting distribution's core metadata. -By contrast, the present approach makes clear what the author intended, -allows tools to unambiguously determine which field(s) may be dynamically -inserted, and ensures backward compatibility such that current project -source metadata do not unknowingly specify both the old and the new field -as dynamic, and instead must do so explicitly per :pep:`621`'s intent. +Additionally, this allows cleanly deprecating the table values +without deprecating the key itself, +and makes them inherently mutually exclusive without users having to remember +and tools having to enforce it. -Additionally, while differences from existing tool formats (and core metadata -field names) has precedent in :pep:`621` (though is best avoided if practical), -using a key with an identical name as in all current tools (and of an existing -core metadata field) to mean something different (and map to a different -core metadata field), with distinct and incompatible syntax and semantics, -does not, and is likely to create substantial and confusion and ambiguity -for readers and authors, contrary to the fundamental goals of this PEP. - -Finally, this means that the top-level ``license`` key still maps to multiple -core metadata fields with different purposes and interpretation (``License`` -and ``License-Expression``), this would deny a clear separation from the -old behavior by not cleanly deprecating the ``license`` key, and -increases the complexity of the specification and implementation. - -In addition to the aforementioned issues, this also requires deciding between -the three individual approaches (``expression`` subkey, top-level string or -allowing both), all of which have further significant downsides and none of -which are clearly superior or more obvious, leading to needless bikeshedding. - -If the license expression was made the string value of the ``license`` key, -as reserved by :pep:`621`, it would be slightly shorter for users to type and -more obviously the preferred approach. However, it is far *less* obvious that -it is a license expression at all, to authors and those viewing the files, -and this lack of clarity, explicitness, ambiguity and potential for user -confusion is exactly what this PEP seeks to avoid, all to save a few characters -over other approaches. - -If an ``expression`` subkey was added to the ``license`` table, it would retain -the clarity of a new top-level key, but add additional complexity for no -real benefit, with an extra level of nesting, and users and tools needing to -deal with the mutual exclusivity of the subkeys, as before. And allowing both -(as a table subkey *and* the string value) would inherit both's downsides, -while adding even more spec and tool complexity and making there more than -"one obvious way to do it", further potentially confusing users. - -Therefore, a separate top-level ``license-expression`` key was adopted to avoid -all these issues, with relatively minimal downside aside from adding a single -additional key and (versus some approaches) a few extra characters to type. - - -Add a ``type`` key to treat as expression -''''''''''''''''''''''''''''''''''''''''' - -Instead of creating a new top-level ``license-expression`` key in the -``[project]`` table, one could add a ``type`` subkey to the existing -``license`` table to control whether ``text`` (or a string value) +Finally, consistency with other tool formats and the underlying core metadata +was not considered a sufficient priority +to override the advantages of using the existing key, +and the ``dynamic`` concerns were mostly mitigated by +not specifying legacy license to license expression conversion at build time, +explicitly specifying backfilling the ``License`` field when not ``dynamic``, +and the fact that both fields are mutually exclusive, +so there is little practical need to distinguish which is dynamic. + +Therefore, a top-level string value for ``license`` was adopted for this PEP, +as an earlier working draft had temporarily specified. + + +Add a ``type`` key to treat ``text`` as expression +'''''''''''''''''''''''''''''''''''''''''''''''''' + +Instead of using the reserved top-level string value +of the ``license`` key in the ``[project]`` table, +one could add a ``type`` subkey to the ``license`` table +to control whether ``text`` (or a string value) is interpreted as free-text or a license expression. This could make backward compatibility a little more seamless, as older tools could ignore it and always treat ``text`` as ``license``, while newer tools would @@ -1393,7 +1394,8 @@ with all the false positive and false negative issues as above. Therefore, for these as well as the same reasons this approach was rejected for the core metadata in favor of a distinct ``License-Expression`` field, -we similarly reject this here. +we similarly reject this here in favor of +the reserved string value of the ``license`` key. Must be marked dynamic to back-fill @@ -1401,14 +1403,15 @@ Must be marked dynamic to back-fill The ``license`` key in the ``pyproject.toml`` could be required to be explicitly set to dynamic in order for the ``License`` core metadata field -to be automatically back-filled from the value of the ``license-expression`` -key. This would be more explicit that the filling will be done, as strictly -speaking the ``license`` key is not (and cannot be) specified in +to be automatically back-filled from +the top-level string value of the ``license`` key. +This would be more explicit that the filling will be done, +as strictly speaking the ``license`` key is not (and cannot be) specified in ``pyproject.toml``, and satisfies a stricter interpretation of the letter of the previous :pep:`621` specification that this PEP revises. -However, this isn't seen to be necessary, because it is simply using the -static, verbatim literal value of the ``license-expression`` key, as specified +However, this doesn't seen to be necessary, because it is simply using the +static, verbatim literal value of the ``license`` key, as specified strictly in this PEP. Therefore, any conforming tool can trivially, deterministically and unambiguously derive this using only the static data in the ``pyproject.toml`` file itself. @@ -2030,7 +2033,7 @@ Or, in the ``[project]`` table of ``pyproject.toml``: .. code-block:: toml [project] - license-expression = "MIT" + license = "MIT" The output core metadata for the distribution packages would then be: @@ -2116,7 +2119,7 @@ specified explicitly via the ``paths`` subkey, this would look like: .. code-block:: toml [project] - license-expression = "MIT AND (Apache-2.0 OR BSD-2-Clause)" + license = "MIT AND (Apache-2.0 OR BSD-2-Clause)" license-files.paths = [ "LICENSE", "setuptools/_vendor/LICENSE", @@ -2129,7 +2132,7 @@ Or alternatively, matched via glob patterns, this could be: .. code-block:: toml [project] - license-expression = "MIT AND (Apache-2.0 OR BSD-2-Clause)" + license = "MIT AND (Apache-2.0 OR BSD-2-Clause)" license-files.globs = [ "LICENSE*", "setuptools/_vendor/LICENSE*", @@ -2234,7 +2237,7 @@ widely used and allows anyone to do whatever they want with your work To apply it, just paste `the text `__ 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 +the copyright line. Then, just add ``license = "MIT"`` under ``[project]`` in your ``pyproject.toml`` if your packaging tool supports it, or in its config file/section (e.g. Setuptools ``license_expression = MIT`` under ``[metadata]`` in ``setup.cfg``). You're done! @@ -2246,7 +2249,7 @@ I want to distribute my project under a specific license To use a particular license, simply paste its text into a ``LICENSE.txt`` file at the root of your repo, if you don't have it in a file starting with ``LICENSE`` or ``COPYING`` already, and add -``license-expression = "LICENSE-ID"`` under ``[project]`` in your +``license = "LICENSE-ID"`` under ``[project]`` in your ``pyproject.toml`` if your packaging tool supports it, or else in its config file (e.g. for Setuptools, ``license_expression = LICENSE-ID`` under ``[metadata]`` in ``setup.cfg``). You can find the ``LICENSE-ID`` @@ -2265,10 +2268,10 @@ should only need to make a couple of tweaks to take advantage of the new functionality. In your project config file, enter your license expression under -``license-expression`` (``[project]`` table in ``pyproject.toml``), +``license`` (``[project]`` table in ``pyproject.toml``), ``license_expression`` (Setuptools ``setup.cfg`` / ``setup.py``), or the equivalent for your packaging tool, -and make sure to remove any legacy ``license`` value or +and make sure to remove any legacy ``license`` table subkeys 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 `__ for the identifier @@ -2306,10 +2309,10 @@ parenthesis (``()``) for grouping to form expressions that cover even the most complex situations. In your project config file, enter your license expression under -``license-expression`` (``[project]`` table of ``pyproject.toml``), +``license`` (``[project]`` table of ``pyproject.toml``), ``license_expression`` (Setuptools ``setup.cfg`` / ``setup.py``), or the equivalent for your packaging tool, -and make sure to remove any legacy ``license`` value +and make sure to remove any legacy ``license`` table subkeys or ``License ::`` classifiers. Also, make sure you add the full license text of all the licenses as files @@ -2474,7 +2477,7 @@ Other Python packaging tools - `PBR `__ uses similar data as Setuptools, but always stored in ``setup.cfg``. -- `Poetry `__ specifies the use of the ``license`` field in +- `Poetry `__ specifies the use of the ``license`` key in ``pyproject.toml`` with SPDX license identifiers. From 39650442e6f75f98ef0bd2aa052f1990525a08cb Mon Sep 17 00:00:00 2001 From: "C.A.M. Gerlach" Date: Fri, 22 Jul 2022 14:36:52 -0500 Subject: [PATCH 11/11] PEP 639: Implement @JelleZijlstra 's suggested editorial fixes --- pep-0639.rst | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/pep-0639.rst b/pep-0639.rst index c183c17ca0e..183017a7232 100644 --- a/pep-0639.rst +++ b/pep-0639.rst @@ -140,12 +140,13 @@ including on `outdated and ambiguous PyPI classifiers `__, `the lack of clear, precise and standardized license metadata `__. The current license classifiers address some common cases, and could -theoretically be extended to include the full range of current SPDX -identifiers while deprecating the many ambiguous classifiers (including some -extremely popular and particularly problematic ones, such as -``License :: OSI Approved :: BSD License``). However, this both requires a -substantial amount of effort to duplicate the SPDX license list and keep -it in sync, and is effectively a hard break in backward compatibility, +be extended to include the full range of current SPDX identifiers +while deprecating the many ambiguous classifiers +(including some popular and problematic ones, +such as ``License :: OSI Approved :: BSD License``). +However, this requires a substantial amount of effort +to duplicate the SPDX license list and keep it in sync. +Furthermore, it is effectively a hard break in backward compatibility, forcing a huge proportion of package authors to immediately update to new classifiers (in most cases, with many possible choices that require closely examining the project's license) immediately when PyPI deprecates the old ones. @@ -213,7 +214,7 @@ metadata story, this specification standardizes and builds upon existing practice in the `Setuptools `__ and `Wheel `__ projects. Furthermore, an up-to-date version of the current draft of this PEP is -`already successfully implemented `__ in the popular +`already successfully implemented `__ in the popular PyPA `Hatch `__ packaging tool, and an earlier draft of the license files portion is `implemented in Setuptools `__. @@ -322,7 +323,7 @@ for the purposes of this PEP (``Syn:``). and the root directory that their paths, as recorded under the ``License-File`` core metadata fields, are relative to. Defined here to be the project root directory for source trees and source - distributions, and a subdirectory named ``licenses`` of the directory + distributions, and a subdirectory named ``licenses`` of the directory containing the core metadata (i.e., the ``.dist-info/licenses`` directory) for built distributions and installed projects. @@ -590,8 +591,8 @@ Add string value to ``license`` key ''''''''''''''''''''''''''''''''''' A top-level string value is defined -for the ``license`` key in the ``[project]`` table, -which specified to be a valid SPDX license expression, +for the ``license`` key in the ``[project]`` table, +which is specified to be a valid SPDX license expression, as :ref:`defined previously <639-license-expression-definition>`. Its value maps to the ``License-Expression`` field in the core metadata. @@ -696,7 +697,7 @@ Deprecate ``license`` key table subkeys ''''''''''''''''''''''''''''''''''''''' Table values for the ``license`` key in the ``[project]`` table, -including the ``text`` and ``file`` table subkeys, is now deprecated. +including the ``text`` and ``file`` table subkeys, are now deprecated. If the new ``license-files`` key is present, build tools MUST raise an error if the ``license`` key is defined and has a value other than a single top-level string. @@ -796,7 +797,7 @@ map to a single valid SPDX license identifier, allowing tools to infer the SPDX license identifier they correspond to, both for use when analyzing and auditing packages, and providing a semi-automated mechanism of filling the ``license`` key -or the the ``License-Expression`` field +or the ``License-Expression`` field following the :ref:`specification above <639-spec-converting-metadata>`. Some legacy license classifiers intend to specify a particular license, @@ -1254,7 +1255,7 @@ being dynamic and others static, and mapping to different core metadata fields. Furthermore, this leads to a conflict with marking the key as ``dynamic`` (assuming that is intended to specify the ``[project]`` table keys, as that PEP seems to imprecisely imply, -rather than core metadata fields), as either both would have +rather than core metadata fields), as either or both would have to be treated as ``dynamic``. Grouping both license expressions and license files under the same key forces an "all or nothing" approach, and creates ambiguity as to user intent. @@ -1316,7 +1317,7 @@ This was seen as clearer and more explicit for readers and writers, in line with the goals of this PEP. Additionally, while differences from existing tool formats (and core metadata -field names) has precedent in :pep:`621`, +field names) have precedent in :pep:`621`, using a key with an identical name as in most/all current tools to mean something different (and map to a different core metadata field), with distinct and incompatible syntax and semantics, does not, @@ -1331,7 +1332,7 @@ from the ``License-Expression`` field as this PEP currently allows without it as ``license`` as dynamic (which would not be possible, since they both map to the same top-level key). -However, community consensus was in favor instead using +However, community consensus favored using the top-level string value of the existing ``license`` key, as :pep:`reserved for this purpose by PEP 621 <621#license>`: @@ -1410,7 +1411,7 @@ as strictly speaking the ``license`` key is not (and cannot be) specified in ``pyproject.toml``, and satisfies a stricter interpretation of the letter of the previous :pep:`621` specification that this PEP revises. -However, this doesn't seen to be necessary, because it is simply using the +However, this doesn't seem to be necessary, because it is simply using the static, verbatim literal value of the ``license`` key, as specified strictly in this PEP. Therefore, any conforming tool can trivially, deterministically and unambiguously derive this using only the static data