Skip to content

Commit 76e5a15

Browse files
authored
Merge pull request #1474 from jeanas/tool-recommendations
Update tool recommendations
2 parents 241a870 + c3ef36c commit 76e5a15

3 files changed

+141
-77
lines changed

source/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. _trusted-publishing:
2+
13
=============================================================================
24
Publishing package distribution releases using GitHub Actions CI/CD workflows
35
=============================================================================

source/guides/tool-recommendations.rst

+138-77
Original file line numberDiff line numberDiff line change
@@ -4,111 +4,172 @@
44
Tool recommendations
55
====================
66

7-
If you're familiar with Python packaging and installation, and just want to know
8-
what tools are currently recommended, then here it is.
7+
The Python packaging landscape consists of many different tools. For many tasks,
8+
the :term:`Python Packaging Authority <Python Packaging Authority (PyPA)>`
9+
(PyPA, the working group which encompasses many packaging tools and
10+
maintains this guide) purposefully does not make a blanket recommendation; for
11+
example, the reason there are many build backends is that the landscape was
12+
opened up in order to enable the development of new backends serving certain users'
13+
needs better than the previously unique backend, setuptools. This guide does
14+
point to some tools that are widely recognized, and also makes some
15+
recommendations of tools that you should *not* use because they are deprecated
16+
or insecure.
17+
18+
19+
Virtual environments
20+
====================
21+
22+
The standard tools to create and use virtual environments manually are
23+
:ref:`virtualenv` (PyPA project) and :doc:`venv <python:library/venv>` (part of
24+
the Python standard library, though missing some features of virtualenv).
25+
26+
27+
Installing packages
28+
===================
29+
30+
:ref:`Pip` is the standard tool to install packages from :term:`PyPI <Python
31+
Package Index (PyPI)>`. You may want to read pip's recommendations for
32+
:doc:`secure installs <pip:topics/secure-installs>`. Pip is available by default
33+
in most Python installations through the standard library package
34+
:doc:`ensurepip <python:library/ensurepip>`.
35+
36+
Alternatively, consider :ref:`pipx` for the specific use case of installing Python
37+
applications that are distributed through PyPI and run from the command line.
38+
Pipx is a wrapper around pip and venv that installs each
39+
application into a dedicated virtual environment. This avoids conflicts between
40+
the dependencies of different applications, and also with system-wide applications
41+
making use of the same Python interpreter (especially on Linux).
42+
43+
For scientific software specifically, consider :ref:`Conda` or :ref:`Spack`.
44+
45+
.. todo:: Write a "pip vs. Conda" comparison, here or in a new discussion.
46+
47+
Do **not** use ``easy_install`` (part of :ref:`setuptools`), which is deprecated
48+
in favor of pip (see :ref:`pip vs easy_install` for details). Likewise, do
49+
**not** use ``python setup.py install`` or ``python setup.py develop``, which
50+
are also deprecated (see :ref:`setup-py-deprecated` for background and
51+
:ref:`modernize-setup-py-project` for migration advice).
52+
53+
54+
Lock files
55+
==========
56+
57+
:ref:`pip-tools` and :ref:`Pipenv` are two recognized tools to create lock
58+
files, which contain the exact versions of all packages installed into an
59+
environment, for reproducibility purposes.
60+
61+
62+
Build backends
63+
==============
64+
65+
.. important::
966

67+
Please, remember: this document does not seek to steer the reader towards
68+
a particular tool, only to enumerate common tools. Different use cases often
69+
need specialized workflows.
1070

11-
Application dependency management
12-
=================================
71+
Popular :term:`build backends <build backend>` for pure-Python packages include,
72+
in alphabetical order:
1373

14-
* Use :ref:`pip` in a `secure manner`_ to install a Python application and its
15-
dependencies during deployment.
74+
- :doc:`Flit-core <flit:pyproject_toml>` -- developed with but separate from :ref:`Flit`.
75+
A minimal and opinionated build backend. It does not support plugins.
1676

17-
* Use :ref:`virtualenv` or :doc:`venv <python:library/venv>` to isolate
18-
application-specific dependencies from a shared Python installation. [4]_
77+
- Hatchling_ -- developed with but separate from :ref:`Hatch`. Supports plugins.
1978

20-
* Use `pip-tools`_, :ref:`pipenv`, or `poetry`_ to generate the fully-specified
21-
application-specific dependencies, when developing Python applications.
79+
- PDM-backend_ -- developed with but separate from :ref:`PDM`. Supports plugins.
2280

23-
.. _secure manner: https://pip.pypa.io/en/latest/topics/secure-installs/
24-
.. _pip-tools: https://github.com/jazzband/pip-tools
25-
.. _Poetry: https://python-poetry.org/
81+
- Poetry-core_ -- developed with but separate from :ref:`Poetry`. Supports
82+
plugins.
2683

27-
Installation tool recommendations
28-
=================================
84+
Unlike other backends on this list, Poetry-core does not support the standard
85+
:ref:`[project] table <writing-pyproject-toml>` (it uses a different format,
86+
in the ``[tool.poetry]`` table).
2987

30-
* Use :ref:`pip` to install Python :term:`packages <Distribution Package>` from
31-
:term:`PyPI <Python Package Index (PyPI)>`. [1]_ [2]_ Depending on how :ref:`pip`
32-
is installed, you may need to also install :ref:`wheel` to get the benefit
33-
of wheel caching. [3]_
88+
- :ref:`setuptools`, which used to be the only build backend. Supports plugins.
3489

35-
* Use :ref:`virtualenv` or :doc:`venv <python:library/venv>` to isolate
36-
project-specific dependencies from a shared Python installation. [4]_
90+
.. caution::
3791

38-
* If you're looking for management of fully integrated cross-platform software
39-
stacks, consider:
92+
If you use setuptools, please be aware that some features that predate
93+
standardisation efforts are now deprecated and only *temporarily kept*
94+
for compatibility.
4095

41-
* :ref:`buildout`: primarily focused on the web development community
96+
In particular, do **not** use direct ``python setup.py`` invocations. On the
97+
other hand, configuring setuptools with a :file:`setup.py` file is still fully
98+
supported, although it is recommended to use the modern :ref:`[project] table
99+
in pyproject.toml <writing-pyproject-toml>` (or :file:`setup.cfg`) whenever possible and keep
100+
:file:`setup.py` only if programmatic configuration is needed. See
101+
:ref:`setup-py-deprecated`.
42102

43-
* :ref:`spack`, :ref:`hashdist`, or :ref:`conda`: primarily focused
44-
on the scientific community.
103+
Other examples of deprecated features you should **not** use include the
104+
``setup_requires`` argument to ``setup()`` (use the :ref:`[build-system] table
105+
<pyproject-guide-build-system-table>` in :file:`pyproject.toml` instead), and
106+
the ``easy_install`` command (cf. :ref:`pip vs easy_install`).
45107

108+
Do **not** use :ref:`distutils`, which is deprecated, and has been removed from
109+
the standard library in Python 3.12, although it still remains available from
110+
setuptools.
46111

47-
Packaging tool recommendations
48-
==============================
112+
For packages with :term:`extension modules <extension module>`, it is best to use
113+
a build system with dedicated support for the language the extension is written in,
114+
for example:
49115

50-
* Use :ref:`setuptools` to define projects. [5]_ [6]_
116+
- :ref:`setuptools` -- natively supports C and C++ (with third-party plugins for Go and Rust),
117+
- :ref:`meson-python` -- C, C++, Fortran, Rust, and other languages supported by Meson,
118+
- :ref:`scikit-build-core` -- C, C++, Fortran, and other languages supported by CMake,
119+
- :ref:`maturin` -- Rust, via Cargo.
51120

52-
* Use :ref:`build` to create :term:`Source Distributions
53-
<Source Distribution (or "sdist")>` and :term:`wheels <Wheel>`.
54121

55-
If you have binary extensions and want to distribute wheels for multiple
56-
platforms, use :ref:`cibuildwheel` as part of your CI setup to build
57-
distributable wheels.
122+
Building distributions
123+
======================
58124

59-
* Use `twine <https://pypi.org/project/twine>`_ for uploading distributions
60-
to :term:`PyPI <Python Package Index (PyPI)>`.
125+
The standard tool to build :term:`source distributions <source distribution (or
126+
"sdist")>` and :term:`wheels <wheel>` for uploading to PyPI is :ref:`build`. It
127+
will invoke whichever build backend you :ref:`declared
128+
<pyproject-guide-build-system-table>` in :file:`pyproject.toml`.
61129

130+
Do **not** use ``python setup.py sdist`` and ``python setup.py bdist_wheel`` for
131+
this task. All direct invocations of :file:`setup.py` are :ref:`deprecated
132+
<setup-py-deprecated>`.
62133

63-
Publishing platform migration
64-
=============================
134+
If you have :term:`extension modules <extension module>` and want to distribute
135+
wheels for multiple platforms, use :ref:`cibuildwheel` as part of your CI setup
136+
to build distributable wheels.
65137

66-
The original Python Package Index implementation (previously hosted at
67-
`pypi.python.org <https://pypi.python.org>`_) has been phased out in favour
68-
of an updated implementation hosted at `pypi.org <https://pypi.org>`_.
69138

70-
See :ref:`Migrating to PyPI.org` for more information on the status of the
71-
migration, and what settings to change in your clients.
139+
Uploading to PyPI
140+
=================
72141

73-
----
142+
For projects hosted on GitHub, it is recommended to use the :ref:`trusted publishing
143+
<trusted-publishing>`, which allows the package to be securely uploaded to PyPI
144+
from a GitHub Actions job. (This is not yet supported on software forges other
145+
than GitHub.)
74146

75-
.. [1] There are some cases where you might choose to use ``easy_install`` (from
76-
:ref:`setuptools`), e.g. if you need to install from :term:`Eggs <Egg>`
77-
(which pip doesn't support). For a detailed breakdown, see :ref:`pip vs
78-
easy_install`.
147+
The other available method is to upload the package manually using :ref:`twine`.
79148

80-
.. [2] The acceptance of :pep:`453` means that :ref:`pip`
81-
will be available by default in most installations of Python 3.4 or
82-
later. See the :pep:`rationale section <453#rationale>` from :pep:`453`
83-
as for why pip was chosen.
149+
**Never** use ``python setup.py upload`` for this task. In addition to being
150+
:ref:`deprecated <setup-py-deprecated>`, it is insecure.
84151

85-
.. [3] `get-pip.py <https://github.com/pypa/get-pip/#readme>`_ and
86-
:ref:`virtualenv` install
87-
:ref:`wheel`, whereas :ref:`ensurepip` and :ref:`venv <venv>` do not
88-
currently. Also, the common "python-pip" package that's found in various
89-
linux distros, does not depend on "python-wheel" currently.
90152

91-
.. [4] Beginning with Python 3.4, ``venv`` will create virtualenv environments
92-
with ``pip`` installed, thereby making it an equal alternative to
93-
:ref:`virtualenv`. However, using :ref:`virtualenv` will still be
94-
recommended for users that need cross-version consistency.
153+
Workflow tools
154+
==============
95155

96-
.. [5] Although you can use pure :ref:`distutils` for many projects, it does not
97-
support defining dependencies on other projects and is missing several
98-
convenience utilities for automatically populating distribution metadata
99-
correctly that are provided by ``setuptools``. Being outside the
100-
standard library, ``setuptools`` also offers a more consistent feature
101-
set across different versions of Python, and (unlike ``distutils``),
102-
recent versions of ``setuptools`` support all of the modern metadata
103-
fields described in :ref:`core-metadata`.
156+
These tools are environment managers that automatically manage virtual
157+
environments for a project. They also act as "task runners", allowing you to
158+
define and invoke tasks such as running tests, compiling documentation,
159+
regenerating some files, etc. Some of them provide shortcuts for building
160+
distributions and uploading to PyPI, and some support lock files for
161+
applications. They often call the tools mentioned above under the hood. In
162+
alphabetical order:
104163

105-
Even for projects that do choose to use ``distutils``, when :ref:`pip`
106-
installs such projects directly from source (rather than installing
107-
from a prebuilt :term:`wheel <Wheel>` file), it will actually build
108-
your project using :ref:`setuptools` instead.
164+
- :ref:`Flit`,
165+
- :ref:`Hatch`,
166+
- :doc:`nox <nox:index>`,
167+
- :ref:`PDM`,
168+
- :ref:`Pipenv`,
169+
- :ref:`Poetry`,
170+
- :doc:`tox <tox:index>`.
109171

110-
.. [6] `distribute`_ (a fork of setuptools) was merged back into
111-
:ref:`setuptools` in June 2013, thereby making setuptools the default
112-
choice for packaging.
113172

114-
.. _distribute: https://pypi.org/project/distribute
173+
.. _hatchling: https://pypi.org/project/hatchling/
174+
.. _pdm-backend: https://backend.pdm-project.org
175+
.. _poetry-core: https://pypi.org/project/poetry-core/

source/guides/writing-pyproject-toml.rst

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ three possible TOML tables in this file.
4040
:ref:`setup-py-deprecated`.
4141

4242

43+
.. _pyproject-guide-build-system-table:
4344

4445
Declaring the build backend
4546
===========================

0 commit comments

Comments
 (0)