Skip to content

Commit 6d0b21a

Browse files
Latest setuptools and flit now support PEP 639
This updates the now outdated notes added in faf4c7d. Closes #1831.
1 parent 1415b22 commit 6d0b21a

File tree

4 files changed

+73
-98
lines changed

4 files changed

+73
-98
lines changed

source/guides/licensing-examples-and-user-scenarios.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ This document aims to provide clear guidance how to migrate from the legacy
1212
to the standardized way of declaring licenses.
1313
Make sure your preferred build backend supports :pep:`639` before
1414
trying to apply the newer guidelines.
15-
As of February 2025, :doc:`setuptools <setuptools:userguide/pyproject_config>`
16-
and :ref:`flit <flit:pyproject_toml_project>` don't support :pep:`639` yet.
1715

1816

1917
Licensing Examples

source/guides/writing-pyproject-toml.rst

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -291,22 +291,43 @@ You can also specify the format explicitly, like this:
291291
readme = {file = "README.txt", content-type = "text/x-rst"}
292292
293293
294-
.. _license:
294+
.. _license-and-license-files:
295295

296-
``license``
297-
-----------
296+
``license`` and ``license-files``
297+
---------------------------------
298+
299+
As per :pep:`639` licenses should be declared with two fields:
300+
301+
- ``license`` is an :term:`SPDX license expression <License Expression>` consisting
302+
of one or more :term:`license identifiers <License Identifier>`.
303+
- ``license-files`` is a list of license file glob patterns.
304+
305+
A previous PEP had specified ``license`` to be a table with a ``file`` or a
306+
``text`` key, this format is now deprecated. Most :term:`build backends<build
307+
backend>` now support the new format as shown in the following table.
308+
309+
.. list-table:: build backend versions that introduced :pep:`639` support
310+
:header-rows: 1
298311

299-
:pep:`639` (accepted in August 2024) has changed the way the ``license`` field
300-
is declared. Make sure your preferred build backend supports :pep:`639` before
301-
trying to apply the newer guidelines.
302-
As of February 2025, :doc:`setuptools <setuptools:userguide/pyproject_config>`
303-
and :ref:`flit <flit:pyproject_toml_project>` don't support :pep:`639` yet.
312+
* - hatchling
313+
- setuptools
314+
- flit-core [#flit-core-pep639]_
315+
- pdm-backend
316+
- poetry-core
317+
* - 1.27.0
318+
- 77.0.3
319+
- 3.12
320+
- 2.4.0
321+
- `not yet <poetry-pep639-issue_>`_
304322

305-
:pep:`639` license declaration
306-
''''''''''''''''''''''''''''''
307323

308-
This is a valid :term:`SPDX license expression <License Expression>` consisting
309-
of one or more :term:`license identifiers <License Identifier>`.
324+
.. _license:
325+
326+
``license``
327+
'''''''''''
328+
329+
The new format for ``license`` is a valid :term:`SPDX license expression <License Expression>`
330+
consisting of one or more :term:`license identifiers <License Identifier>`.
310331
The full license list is available at the
311332
`SPDX license list page <spdxlicenselist_>`_. The supported list version is
312333
3.17 or any later compatible one.
@@ -318,6 +339,11 @@ The full license list is available at the
318339
# or
319340
license = "MIT AND (Apache-2.0 OR BSD-2-Clause)"
320341
342+
.. note:: If you get a build error that ``license`` should be a dict/table,
343+
your build backend doesn't yet support the new format. See the
344+
`above section <license-and-license-files_>`_ for more context.
345+
The now deprecated format is `described in PEP 621 <https://peps.python.org/pep-0621/#license>`__.
346+
321347
As a general rule, it is a good idea to use a standard, well-known
322348
license, both to avoid confusion and because some organizations avoid software
323349
whose license is unapproved.
@@ -332,41 +358,11 @@ The custom identifiers must follow the SPDX specification,
332358
[project]
333359
license = "LicenseRef-My-Custom-License"
334360
335-
Legacy license declaration
336-
''''''''''''''''''''''''''
337-
338-
This can take two forms. You can put your license in a file, typically
339-
:file:`LICENSE` or :file:`LICENSE.txt`, and link that file here:
340-
341-
.. code-block:: toml
342-
343-
[project]
344-
license = {file = "LICENSE"}
345-
346-
or you can write the name of the license:
347-
348-
.. code-block:: toml
349-
350-
[project]
351-
license = {text = "MIT License"}
352-
353-
If you are using a standard, well-known license, it is not necessary to use this
354-
field. Instead, you should use one of the :ref:`classifiers` starting with ``License
355-
::``. (As a general rule, it is a good idea to use a standard, well-known
356-
license, both to avoid confusion and because some organizations avoid software
357-
whose license is unapproved.)
358-
359361
360362
.. _license-files:
361363

362364
``license-files``
363-
-----------------
364-
365-
:pep:`639` (accepted in August 2024) has introduced the ``license-files`` field.
366-
Make sure your preferred build backend supports :pep:`639` before declaring the
367-
field.
368-
As of February 2025, :doc:`setuptools <setuptools:userguide/pyproject_config>`
369-
and :ref:`flit <flit:pyproject_toml_project>` don't support :pep:`639` yet.
365+
'''''''''''''''''
370366

371367
This is a list of license files and files containing other legal
372368
information you want to distribute with your package.
@@ -541,7 +537,7 @@ A full example
541537
]
542538
description = "Lovely Spam! Wonderful Spam!"
543539
readme = "README.rst"
544-
license = "MIT" # or license = {file = "LICENSE.txt"} for legacy declaration
540+
license = "MIT"
545541
license-files = ["LICEN[CS]E.*"]
546542
keywords = ["egg", "bacon", "sausage", "tomatoes", "Lobster Thermidor"]
547543
classifiers = [
@@ -579,13 +575,17 @@ A full example
579575
like ``requires-python = "<= 3.10"`` here. `This blog post <requires-python-blog-post_>`_
580576
contains some information regarding possible problems.
581577
578+
.. [#flit-core-pep639] flit-core `does not yet <flit-issue-735_>`_ support WITH in SPDX license expressions.
579+
580+
.. _flit-issue-735: https://github.com/pypa/flit/issues/735
582581
.. _gfm: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax
583582
.. _setuptools: https://setuptools.pypa.io
584583
.. _poetry: https://python-poetry.org
585584
.. _pypi-pip: https://pypi.org/project/pip
586585
.. _pypi-search-pip: https://pypi.org/search?q=pip
587586
.. _classifier-list: https://pypi.org/classifiers
588587
.. _requires-python-blog-post: https://iscinumpy.dev/post/bound-version-constraints/#pinning-the-python-version-is-special
588+
.. _poetry-pep639-issue: https://github.com/python-poetry/poetry/issues/9670
589589
.. _pytest: https://pytest.org
590590
.. _pygments: https://pygments.org
591591
.. _rest: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html

source/shared/build-backend-tabs.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,34 @@
11
.. (comment) This file is included in guides/writing-pyproject-toml.rst and tutorials/packaging-projects.rst.
2+
.. The minimum versions here are the versions that introduced support for PEP 639.
23
34
.. tab:: Hatchling
45

56
.. code-block:: toml
67
78
[build-system]
8-
requires = ["hatchling"]
9+
requires = ["hatchling >= 1.26"]
910
build-backend = "hatchling.build"
1011
1112
.. tab:: setuptools
1213

1314
.. code-block:: toml
1415
1516
[build-system]
16-
requires = ["setuptools >= 61.0"]
17+
requires = ["setuptools >= 77.0.3"]
1718
build-backend = "setuptools.build_meta"
1819
1920
.. tab:: Flit
2021

2122
.. code-block:: toml
2223
2324
[build-system]
24-
requires = ["flit_core >= 3.4"]
25+
requires = ["flit_core >= 3.12.0"]
2526
build-backend = "flit_core.buildapi"
2627
2728
.. tab:: PDM
2829

2930
.. code-block:: toml
3031
3132
[build-system]
32-
requires = ["pdm-backend"]
33+
requires = ["pdm-backend >= 2.4.0"]
3334
build-backend = "pdm.backend"

source/tutorials/packaging-projects.rst

Lines changed: 24 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ Frontends usually run builds in isolated environments, so omitting dependencies
144144
here may cause build-time errors.
145145
This should always include your backend's package, and might have other build-time
146146
dependencies.
147+
The minimum version specified in the above code block is the one that introduced support
148+
for :ref:`the new license metadata <license-and-license-files>`.
147149

148150
The ``build-backend`` key is the name of the Python object that frontends will use
149151
to perform the build.
@@ -169,52 +171,27 @@ to include your username; this ensures that you have a unique
169171
package name that doesn't conflict with packages uploaded by other people
170172
following this tutorial.
171173

172-
.. tab:: hatchling/pdm
173-
174-
.. code-block:: toml
175-
176-
[project]
177-
name = "example_package_YOUR_USERNAME_HERE"
178-
version = "0.0.1"
179-
authors = [
180-
{ name="Example Author", email="[email protected]" },
181-
]
182-
description = "A small example package"
183-
readme = "README.md"
184-
requires-python = ">=3.8"
185-
classifiers = [
186-
"Programming Language :: Python :: 3",
187-
"Operating System :: OS Independent",
188-
]
189-
license = "MIT"
190-
license-files = ["LICEN[CS]E*"]
191-
192-
[project.urls]
193-
Homepage = "https://github.com/pypa/sampleproject"
194-
Issues = "https://github.com/pypa/sampleproject/issues"
195-
196-
.. tab:: setuptools/flit
197-
198-
.. code-block:: toml
199-
200-
[project]
201-
name = "example_package_YOUR_USERNAME_HERE"
202-
version = "0.0.1"
203-
authors = [
204-
{ name="Example Author", email="[email protected]" },
205-
]
206-
description = "A small example package"
207-
readme = "README.md"
208-
requires-python = ">=3.8"
209-
classifiers = [
210-
"Programming Language :: Python :: 3",
211-
"Operating System :: OS Independent",
212-
"License :: OSI Approved :: MIT License",
213-
]
214-
215-
[project.urls]
216-
Homepage = "https://github.com/pypa/sampleproject"
217-
Issues = "https://github.com/pypa/sampleproject/issues"
174+
.. code-block:: toml
175+
176+
[project]
177+
name = "example_package_YOUR_USERNAME_HERE"
178+
version = "0.0.1"
179+
authors = [
180+
{ name="Example Author", email="[email protected]" },
181+
]
182+
description = "A small example package"
183+
readme = "README.md"
184+
requires-python = ">=3.8"
185+
classifiers = [
186+
"Programming Language :: Python :: 3",
187+
"Operating System :: OS Independent",
188+
]
189+
license = "MIT"
190+
license-files = ["LICEN[CS]E*"]
191+
192+
[project.urls]
193+
Homepage = "https://github.com/pypa/sampleproject"
194+
Issues = "https://github.com/pypa/sampleproject/issues"
218195
219196
- ``name`` is the *distribution name* of your package. This can be any name as
220197
long as it only contains letters, numbers, ``.``, ``_`` , and ``-``. It also
@@ -243,10 +220,9 @@ following this tutorial.
243220
your package will work on. For a complete list of classifiers, see
244221
https://pypi.org/classifiers/.
245222
- ``license`` is the :term:`SPDX license expression <License Expression>` of
246-
your package. Not supported by all the build backends yet.
223+
your package.
247224
- ``license-files`` is the list of glob paths to the license files,
248225
relative to the directory where :file:`pyproject.toml` is located.
249-
Not supported by all the build backends yet.
250226
- ``urls`` lets you list any number of extra links to show on PyPI.
251227
Generally this could be to the source, documentation, issue trackers, etc.
252228

0 commit comments

Comments
 (0)