Skip to content

Commit 4c1831e

Browse files
authored
Merge pull request #1837 from not-my-profile/pep639-supported
Latest setuptools and flit now support PEP 639
2 parents 29e2df4 + 8a64c52 commit 4c1831e

File tree

4 files changed

+104
-158
lines changed

4 files changed

+104
-158
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: 45 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -56,38 +56,7 @@ Usually, you'll just copy what your build backend's documentation
5656
suggests (after :ref:`choosing your build backend <choosing-build-backend>`).
5757
Here are the values for some common build backends:
5858

59-
.. tab:: Hatchling
60-
61-
.. code-block:: toml
62-
63-
[build-system]
64-
requires = ["hatchling"]
65-
build-backend = "hatchling.build"
66-
67-
.. tab:: setuptools
68-
69-
.. code-block:: toml
70-
71-
[build-system]
72-
requires = ["setuptools >= 61.0"]
73-
build-backend = "setuptools.build_meta"
74-
75-
.. tab:: Flit
76-
77-
.. code-block:: toml
78-
79-
[build-system]
80-
requires = ["flit_core >= 3.4"]
81-
build-backend = "flit_core.buildapi"
82-
83-
.. tab:: PDM
84-
85-
.. code-block:: toml
86-
87-
[build-system]
88-
requires = ["pdm-backend"]
89-
build-backend = "pdm.backend"
90-
59+
.. include:: ../shared/build-backend-tabs.rst
9160

9261

9362
Static vs. dynamic metadata
@@ -322,22 +291,43 @@ You can also specify the format explicitly, like this:
322291
readme = {file = "README.txt", content-type = "text/x-rst"}
323292
324293
325-
.. _license:
294+
.. _license-and-license-files:
326295

327-
``license``
328-
-----------
296+
``license`` and ``license-files``
297+
---------------------------------
329298

330-
:pep:`639` (accepted in August 2024) has changed the way the ``license`` field
331-
is declared. Make sure your preferred build backend supports :pep:`639` before
332-
trying to apply the newer guidelines.
333-
As of February 2025, :doc:`setuptools <setuptools:userguide/pyproject_config>`
334-
and :ref:`flit <flit:pyproject_toml_project>` don't support :pep:`639` yet.
299+
As per :pep:`639` licenses should be declared with two fields:
335300

336-
:pep:`639` license declaration
337-
''''''''''''''''''''''''''''''
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.
338304

339-
This is a valid :term:`SPDX license expression <License Expression>` consisting
340-
of one or more :term:`license identifiers <License Identifier>`.
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
311+
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_>`_
322+
323+
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>`.
341331
The full license list is available at the
342332
`SPDX license list page <spdxlicenselist_>`_. The supported list version is
343333
3.17 or any later compatible one.
@@ -349,6 +339,11 @@ The full license list is available at the
349339
# or
350340
license = "MIT AND (Apache-2.0 OR BSD-2-Clause)"
351341
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+
352347
As a general rule, it is a good idea to use a standard, well-known
353348
license, both to avoid confusion and because some organizations avoid software
354349
whose license is unapproved.
@@ -363,41 +358,11 @@ The custom identifiers must follow the SPDX specification,
363358
[project]
364359
license = "LicenseRef-My-Custom-License"
365360
366-
Legacy license declaration
367-
''''''''''''''''''''''''''
368-
369-
This can take two forms. You can put your license in a file, typically
370-
:file:`LICENSE` or :file:`LICENSE.txt`, and link that file here:
371-
372-
.. code-block:: toml
373-
374-
[project]
375-
license = {file = "LICENSE"}
376-
377-
or you can write the name of the license:
378-
379-
.. code-block:: toml
380-
381-
[project]
382-
license = {text = "MIT License"}
383-
384-
If you are using a standard, well-known license, it is not necessary to use this
385-
field. Instead, you should use one of the :ref:`classifiers` starting with ``License
386-
::``. (As a general rule, it is a good idea to use a standard, well-known
387-
license, both to avoid confusion and because some organizations avoid software
388-
whose license is unapproved.)
389-
390361
391362
.. _license-files:
392363

393364
``license-files``
394-
-----------------
395-
396-
:pep:`639` (accepted in August 2024) has introduced the ``license-files`` field.
397-
Make sure your preferred build backend supports :pep:`639` before declaring the
398-
field.
399-
As of February 2025, :doc:`setuptools <setuptools:userguide/pyproject_config>`
400-
and :ref:`flit <flit:pyproject_toml_project>` don't support :pep:`639` yet.
365+
'''''''''''''''''
401366

402367
This is a list of license files and files containing other legal
403368
information you want to distribute with your package.
@@ -572,7 +537,7 @@ A full example
572537
]
573538
description = "Lovely Spam! Wonderful Spam!"
574539
readme = "README.rst"
575-
license = "MIT" # or license = {file = "LICENSE.txt"} for legacy declaration
540+
license = "MIT"
576541
license-files = ["LICEN[CS]E.*"]
577542
keywords = ["egg", "bacon", "sausage", "tomatoes", "Lobster Thermidor"]
578543
classifiers = [
@@ -610,13 +575,17 @@ A full example
610575
like ``requires-python = "<= 3.10"`` here. `This blog post <requires-python-blog-post_>`_
611576
contains some information regarding possible problems.
612577
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
613581
.. _gfm: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax
614582
.. _setuptools: https://setuptools.pypa.io
615583
.. _poetry: https://python-poetry.org
616584
.. _pypi-pip: https://pypi.org/project/pip
617585
.. _pypi-search-pip: https://pypi.org/search?q=pip
618586
.. _classifier-list: https://pypi.org/classifiers
619587
.. _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
620589
.. _pytest: https://pytest.org
621590
.. _pygments: https://pygments.org
622591
.. _rest: https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html

source/shared/build-backend-tabs.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
.. (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.
3+
4+
.. tab:: Hatchling
5+
6+
.. code-block:: toml
7+
8+
[build-system]
9+
requires = ["hatchling >= 1.26"]
10+
build-backend = "hatchling.build"
11+
12+
.. tab:: setuptools
13+
14+
.. code-block:: toml
15+
16+
[build-system]
17+
requires = ["setuptools >= 77.0.3"]
18+
build-backend = "setuptools.build_meta"
19+
20+
.. tab:: Flit
21+
22+
.. code-block:: toml
23+
24+
[build-system]
25+
requires = ["flit_core >= 3.12.0, <4"]
26+
build-backend = "flit_core.buildapi"
27+
28+
.. tab:: PDM
29+
30+
.. code-block:: toml
31+
32+
[build-system]
33+
requires = ["pdm-backend >= 2.4.0"]
34+
build-backend = "pdm.backend"

source/tutorials/packaging-projects.rst

Lines changed: 25 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -136,45 +136,16 @@ The :file:`pyproject.toml` tells :term:`build frontend <Build Frontend>` tools l
136136
examples for common build backends, but check your backend's own documentation
137137
for more details.
138138

139-
.. tab:: Hatchling
140-
141-
.. code-block:: toml
142-
143-
[build-system]
144-
requires = ["hatchling"]
145-
build-backend = "hatchling.build"
146-
147-
.. tab:: setuptools
148-
149-
.. code-block:: toml
150-
151-
[build-system]
152-
requires = ["setuptools>=61.0"]
153-
build-backend = "setuptools.build_meta"
154-
155-
.. tab:: Flit
156-
157-
.. code-block:: toml
158-
159-
[build-system]
160-
requires = ["flit_core>=3.4"]
161-
build-backend = "flit_core.buildapi"
162-
163-
.. tab:: PDM
164-
165-
.. code-block:: toml
166-
167-
[build-system]
168-
requires = ["pdm-backend"]
169-
build-backend = "pdm.backend"
170-
139+
.. include:: ../shared/build-backend-tabs.rst
171140

172141
The ``requires`` key is a list of packages that are needed to build your package.
173142
The :term:`frontend <Build Frontend>` should install them automatically when building your package.
174143
Frontends usually run builds in isolated environments, so omitting dependencies
175144
here may cause build-time errors.
176145
This should always include your backend's package, and might have other build-time
177146
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>`.
178149

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

203-
.. tab:: hatchling/pdm
204-
205-
.. code-block:: toml
206-
207-
[project]
208-
name = "example_package_YOUR_USERNAME_HERE"
209-
version = "0.0.1"
210-
authors = [
211-
{ name="Example Author", email="[email protected]" },
212-
]
213-
description = "A small example package"
214-
readme = "README.md"
215-
requires-python = ">=3.8"
216-
classifiers = [
217-
"Programming Language :: Python :: 3",
218-
"Operating System :: OS Independent",
219-
]
220-
license = "MIT"
221-
license-files = ["LICEN[CS]E*"]
222-
223-
[project.urls]
224-
Homepage = "https://github.com/pypa/sampleproject"
225-
Issues = "https://github.com/pypa/sampleproject/issues"
226-
227-
.. tab:: setuptools/flit
228-
229-
.. code-block:: toml
230-
231-
[project]
232-
name = "example_package_YOUR_USERNAME_HERE"
233-
version = "0.0.1"
234-
authors = [
235-
{ name="Example Author", email="[email protected]" },
236-
]
237-
description = "A small example package"
238-
readme = "README.md"
239-
requires-python = ">=3.8"
240-
classifiers = [
241-
"Programming Language :: Python :: 3",
242-
"Operating System :: OS Independent",
243-
"License :: OSI Approved :: MIT License",
244-
]
245-
246-
[project.urls]
247-
Homepage = "https://github.com/pypa/sampleproject"
248-
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"
249195
250196
- ``name`` is the *distribution name* of your package. This can be any name as
251197
long as it only contains letters, numbers, ``.``, ``_`` , and ``-``. It also
@@ -274,10 +220,9 @@ following this tutorial.
274220
your package will work on. For a complete list of classifiers, see
275221
https://pypi.org/classifiers/.
276222
- ``license`` is the :term:`SPDX license expression <License Expression>` of
277-
your package. Not supported by all the build backends yet.
223+
your package.
278224
- ``license-files`` is the list of glob paths to the license files,
279225
relative to the directory where :file:`pyproject.toml` is located.
280-
Not supported by all the build backends yet.
281226
- ``urls`` lets you list any number of extra links to show on PyPI.
282227
Generally this could be to the source, documentation, issue trackers, etc.
283228

0 commit comments

Comments
 (0)