|
4 | 4 | Tool recommendations
|
5 | 5 | ====================
|
6 | 6 |
|
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 Python Packaging Authority (PyPA, the umbrella organization which |
| 9 | +encompasses many packaging tools and maintains this guide) purposefully does not |
| 10 | +make a blanket recommendation; for example, the reason there exist many build |
| 11 | +backends is that the landscape was opened in order to enable the development of |
| 12 | +new backends serving certain users' needs better than the previously unique |
| 13 | +backend, setuptools. This guide does point to some tools that are widely |
| 14 | +recognized, and also makes some recommendations of tools that you should *not* |
| 15 | +use because they are deprecated or insecure. |
| 16 | + |
| 17 | + |
| 18 | +Virtual environments |
| 19 | +==================== |
| 20 | + |
| 21 | +The standard tools to create and use virtual environments manually are |
| 22 | +:ref:`virtualenv` (PyPA project) and :doc:`venv <python:library/venv>` (part of |
| 23 | +the Python standard library, though missing some features of virtualenv). |
| 24 | + |
| 25 | + |
| 26 | +Installing packages |
| 27 | +=================== |
| 28 | + |
| 29 | +:ref:`Pip` is a standard tool to install packages from :term:`PyPI <Python |
| 30 | +Package Index (PyPI)>`. It can install into the global environment or into |
| 31 | +virtual environments. 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. |
| 34 | + |
| 35 | +Alternatively, for installing Python command line applications specifically, |
| 36 | +consider :ref:`pipx`, which is a wrapper around pip that installs each |
| 37 | +application into a dedicated virtual environment in order to avoid conflicts |
| 38 | +with other applications and, on Linux, conflicts with the system. |
| 39 | + |
| 40 | +For scientific software specifically, consider :ref:`Conda` or :ref:`Spack`. |
| 41 | + |
| 42 | +.. todo:: Write a "pip vs. Conda" comparison, here or in a new discussion. |
| 43 | + |
| 44 | +Do **not** use ``easy_install`` (part of :ref:`setuptools`), which is deprecated |
| 45 | +in favor of pip (see :ref:`pip vs easy_install` for details). Likewise, do |
| 46 | +**not** use ``python setup.py install`` or ``python setup.py develop``, which |
| 47 | +are also deprecated (see :ref:`setup-py-deprecated` for background and |
| 48 | +:ref:`modernize-setup-py-project` for migration advice). |
| 49 | + |
| 50 | + |
| 51 | +Lock files |
| 52 | +========== |
9 | 53 |
|
| 54 | +:ref:`pip-tools` and :ref:`Pipenv` are two recognized tools to create lock |
| 55 | +files, which contain the exact versions of all packages installed into an |
| 56 | +environment, for reproducibility purposes. |
10 | 57 |
|
11 |
| -Application dependency management |
12 |
| -================================= |
13 | 58 |
|
14 |
| -* Use :ref:`pip` in a `secure manner`_ to install a Python application and its |
15 |
| - dependencies during deployment. |
| 59 | +Build backends |
| 60 | +============== |
16 | 61 |
|
17 |
| -* Use :ref:`virtualenv` or :doc:`venv <python:library/venv>` to isolate |
18 |
| - application-specific dependencies from a shared Python installation. [4]_ |
| 62 | +Popular :term:`build backends <build backend>` for pure-Python packages include: |
19 | 63 |
|
20 |
| -* Use `pip-tools`_, :ref:`pipenv`, or `poetry`_ to generate the fully-specified |
21 |
| - application-specific dependencies, when developing Python applications. |
| 64 | +- Hatchling, which is part of :ref:`Hatch` (but can be used without |
| 65 | + Hatch as well). Hatchling is extensible through a plugin system. |
22 | 66 |
|
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/ |
| 67 | +- :ref:`setuptools`, the historical build backend. It can be configured |
| 68 | + programmatically through the :file:`setup.py` file. |
26 | 69 |
|
27 |
| -Installation tool recommendations |
28 |
| -================================= |
| 70 | + If you use setuptools, please be aware that it contains many deprecated |
| 71 | + features which are currently kept for compatibility, but should not be used. |
| 72 | + For example, do not use ``python setup.py`` invocations |
| 73 | + (cf. :ref:`setup-py-deprecated`), the ``python_requires`` argument to |
| 74 | + ``setup()`` (use the :ref:`[build-system] table |
| 75 | + <pyproject-guide-build-system-table>` of :file:`pyproject.toml` instead), or |
| 76 | + the ``easy_install`` command (cf. :ref:`pip vs easy_install`). |
29 | 77 |
|
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]_ |
| 78 | +- Flit-core, part of :ref:`Flit` (but usable standalone). It is meant to be a |
| 79 | + minimal and opinionated build backend. It is not extensible. |
34 | 80 |
|
35 |
| -* Use :ref:`virtualenv` or :doc:`venv <python:library/venv>` to isolate |
36 |
| - project-specific dependencies from a shared Python installation. [4]_ |
| 81 | +- PDM-backend_, part of :ref:`PDM` (but usable standalone). It provides build |
| 82 | + hooks for extensibility. |
37 | 83 |
|
38 |
| -* If you're looking for management of fully integrated cross-platform software |
39 |
| - stacks, consider: |
| 84 | +- Poetry-core, part of :ref:`Poetry` (but usable standalone). It is extensible |
| 85 | + through plugins. |
40 | 86 |
|
41 |
| - * :ref:`buildout`: primarily focused on the web development community |
| 87 | +Do **not** use distutils, which is deprecated, and has been removed from the |
| 88 | +standard library in Python 3.12, although it still remains available from |
| 89 | +setuptools. |
42 | 90 |
|
43 |
| - * :ref:`spack`, :ref:`hashdist`, or :ref:`conda`: primarily focused |
44 |
| - on the scientific community. |
| 91 | +For packages with :term:`extension modules <extension module>`, you may use |
| 92 | +setuptools, but consider using a build system dedicated to the language the |
| 93 | +extension is written in, such as Meson or CMake for C/C++, or Cargo for Rust, |
| 94 | +and bridging this build system to Python using a dedicated build backend: |
45 | 95 |
|
| 96 | +- :ref:`meson-python` for Meson, |
46 | 97 |
|
47 |
| -Packaging tool recommendations |
48 |
| -============================== |
| 98 | +- :ref:`scikit-build-core` for CMake, |
49 | 99 |
|
50 |
| -* Use :ref:`setuptools` to define projects. [5]_ [6]_ |
| 100 | +- :ref:`maturin` for Cargo. |
51 | 101 |
|
52 |
| -* Use :ref:`build` to create :term:`Source Distributions |
53 |
| - <Source Distribution (or "sdist")>` and :term:`wheels <Wheel>`. |
54 | 102 |
|
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. |
| 103 | +Building distributions |
| 104 | +====================== |
58 | 105 |
|
59 |
| -* Use `twine <https://pypi.org/project/twine>`_ for uploading distributions |
60 |
| - to :term:`PyPI <Python Package Index (PyPI)>`. |
| 106 | +The standard tool to build :term:`source distributions <source distribution (or |
| 107 | +"sdist")>` and :term:`wheels <wheel>` for uploading to PyPI is :ref:`build`. It |
| 108 | +will invoke whichever build backend you :ref:`declared |
| 109 | +<pyproject-guide-build-system-table>` in :file:`pyproject.toml`. |
61 | 110 |
|
| 111 | +Do **not** use ``python setup.py sdist`` and ``python setup.py bdist_wheel`` for |
| 112 | +this task. All direct invocations of :file:`setup.py` are :ref:`deprecated |
| 113 | +<setup-py-deprecated>`. |
62 | 114 |
|
63 |
| -Publishing platform migration |
64 |
| -============================= |
| 115 | +If you have :term:`extension modules <extension module>` and want to distribute |
| 116 | +wheels for multiple platforms, use :ref:`cibuildwheel` as part of your CI setup |
| 117 | +to build distributable wheels. |
65 | 118 |
|
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>`_. |
69 | 119 |
|
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. |
| 120 | +Uploading to PyPI |
| 121 | +================= |
72 | 122 |
|
73 |
| ----- |
| 123 | +The standard tool for this task is :ref:`twine`. |
74 | 124 |
|
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`. |
| 125 | +**Never** use ``python setup.py upload`` for this task. In addition to being |
| 126 | +:ref:`deprecated <setup-py-deprecated>`, it is insecure. |
79 | 127 |
|
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. |
84 | 128 |
|
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. |
| 129 | +Integrated workflow tools |
| 130 | +========================= |
90 | 131 |
|
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. |
| 132 | +These are tools that combine many features in one command line application, such |
| 133 | +as automatically managing virtual environments for a project, building |
| 134 | +distributions, uploading to PyPI, or creating and using lock files. |
95 | 135 |
|
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`. |
| 136 | +- :ref:`Hatch`, |
| 137 | +- :ref:`Flit`, |
| 138 | +- :ref:`PDM`, |
| 139 | +- :ref:`Poetry`. |
104 | 140 |
|
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. |
109 | 141 |
|
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. |
113 | 142 |
|
114 |
| -.. _distribute: https://pypi.org/project/distribute |
| 143 | +.. _pdm-backend: https://backend.pdm-project.org |
0 commit comments