Skip to content

Commit 4a5cbf9

Browse files
committed
Update "Dropping older Python versions" guide
1 parent 08c54d4 commit 4a5cbf9

File tree

1 file changed

+53
-40
lines changed

1 file changed

+53
-40
lines changed

source/guides/dropping-older-python-versions.rst

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,17 @@
44
Dropping support for older Python versions
55
==========================================
66

7-
Dropping support for older Python versions is supported by the standard :ref:`core-metadata` 1.2 specification via a "Requires-Python" attribute.
7+
Dropping support for older Python versions is supported by the standard :ref:`core-metadata` 1.2 specification via a :ref:`"Requires-Python" <core-metadata-requires-python>` attribute.
88

99
Metadata 1.2+ clients, such as Pip 9.0+, will adhere to this specification by matching the current Python runtime and comparing it with the required version
1010
in the package metadata. If they do not match, it will attempt to install the last package distribution that supported that Python runtime.
1111

12-
This mechanism can be used to drop support for older Python versions, by amending the "Requires-Python" attribute in the package metadata.
13-
14-
This guide is specifically for users of :ref:`setuptools`, other packaging tools such as ``flit`` may offer similar functionality but users will need to consult relevant documentation.
12+
This mechanism can be used to drop support for older Python versions, by amending the ``Requires-Python`` attribute in the package metadata.
1513

1614
Requirements
1715
------------
1816

19-
This workflow requires that:
20-
21-
1. The publisher is using the latest version of :ref:`setuptools`,
22-
2. The latest version of :ref:`twine` is used to upload the package,
23-
3. The user installing the package has at least Pip 9.0, or a client that supports the Metadata 1.2 specification.
17+
This workflow requires that the user installing the package has at least Pip 9.0, or a client that supports the Metadata 1.2 specification.
2418

2519
Dealing with the universal wheels
2620
---------------------------------
@@ -52,42 +46,50 @@ explicitly set ``universal`` to ``0``:
5246
Defining the Python version required
5347
------------------------------------
5448

55-
1. Download the newest version of Setuptools
56-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57-
58-
Ensure that before you generate source distributions or binary distributions, you update Setuptools and install twine.
49+
1. Install twine
50+
~~~~~~~~~~~~~~~~
5951

52+
Ensure that you have twine available at its latest version.
6053
Steps:
6154

6255
.. tab:: Unix/macOS
6356

6457
.. code-block:: bash
6558
66-
python3 -m pip install --upgrade setuptools twine
59+
python3 -m pip install --upgrade twine
6760
6861
.. tab:: Windows
6962

7063
.. code-block:: bat
7164
72-
py -m pip install --upgrade setuptools twine
73-
74-
``setuptools`` version should be above 24.0.0.
65+
py -m pip install --upgrade twine
7566
7667
2. Specify the version ranges for supported Python distributions
7768
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7869

79-
You can specify version ranges and exclusion rules, such as at least Python 3. Or, Python 2.7, 3.4 and beyond.
80-
81-
Examples:
70+
You can specify version ranges and exclusion rules (complying with the :ref:`version-specifiers` specification),
71+
such as at least Python 3. Or, Python 2.7, 3.4 and beyond:
8272

8373
.. code-block:: text
8474
85-
Requires-Python: ">=3"
86-
Requires-Python: ">2.7,!=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
75+
Requires-Python: ">= 3"
76+
Requires-Python: ">= 2.7, != 3.0.*, != 3.1.*, != 3.2.*, != 3.3.*"
77+
78+
79+
The way to set those values is within your :file:`pyproject.toml`. The :ref:`requires-python` field of the
80+
``[project]`` table corresponds to the ``Requires-Python`` metadata field.
81+
82+
.. code-block:: toml
8783
88-
The way to set those values is within the call to ``setup`` within your
89-
:file:`setup.py` script. This will insert the ``Requires-Python``
90-
metadata values based on the argument you provide in ``python_requires``.
84+
[build-system]
85+
...
86+
87+
[project]
88+
requires-python = ">= 3.8" # At least Python 3.8
89+
90+
91+
For :ref:`setuptools` users, another way to achieve this is using the ``python_requires`` parameter
92+
in the call to ``setup`` within your :file:`setup.py` script.
9193

9294
.. code-block:: python
9395
@@ -96,43 +98,54 @@ metadata values based on the argument you provide in ``python_requires``.
9698
9799
setup(
98100
# Your setup arguments
99-
python_requires='>=2.7', # Your supported Python ranges
101+
python_requires='>= 3.8',
100102
)
101103
104+
It is warned against adding upper bounds to the version ranges, e. g. ``">= 3.8 < 3.10"``. This can cause different errors
105+
and version conflicts. See the `discourse discussion`_ for more information.
106+
102107
3. Validating the Metadata before publishing
103108
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
104109

105110
Within a Python source package (the zip or the tar-gz file you download) is a text file called PKG-INFO.
106111

107-
This file is generated by :ref:`distutils` or :ref:`setuptools` when it generates the source package.
108-
The file contains a set of keys and values, the list of keys is part of the PyPa standard metadata format.
112+
This file is generated by the build backend when it generates the source package.
113+
The file contains a set of keys and values, the list of keys is part of the PyPA standard metadata format.
109114

110115
You can see the contents of the generated file like this:
111116

112117
.. code-block:: bash
113118
114-
tar xfO dist/my-package-1.0.0.tar.gz my-package-1.0.0/PKG-INFO
119+
tar xf dist/my-package-1.0.0.tar.gz my-package-1.0.0/PKG-INFO -O
115120
116121
Validate that the following is in place, before publishing the package:
117122

118123
- If you have upgraded correctly, the Metadata-Version value should be 1.2 or higher.
119-
- The Requires-Python field is set and matches your specification in setup.py.
124+
- The ``Requires-Python`` field is set and matches your specification in the configuration file.
120125

121-
4. Using Twine to publish
126+
4. Publishing the package
122127
~~~~~~~~~~~~~~~~~~~~~~~~~
123128

124-
Twine has a number of advantages, apart from being faster it is now the supported method for publishing packages.
129+
Proceed as suggested in :ref:`Uploading your Project to PyPI`.
125130

126-
Make sure you are using the newest version of Twine, at least 1.9.
127-
128-
Dropping a Python release
131+
Dropping a Python version
129132
-------------------------
130133

131-
Once you have published a package with the Requires-Python metadata, you can then make a further update removing that Python runtime from support.
134+
In principle, at least metadata support for Python versions should be kept as long as possible, because
135+
once that has been dropped, people still depending on a version will be forced to downgrade.
136+
If however supporting a specific version becomes a blocker for a new feature or other issues occur, the metadata
137+
``Requires-Python`` should be amended. Of course this also depends on whether the project needs to be stable and
138+
well-covered for a wider range of users.
139+
140+
Each version compatibility change should have an own release.
141+
142+
For example, you published version 1.0.0 of your package with ``Requires-Python: ">= 2.7"`` metadata.
143+
144+
If you then update the version string to ``">= 3.5"``, and publish a new version 2.0.0 of your package, any users running Pip 9.0+ from version 2.7 will have version 1.0.0 of the package installed, and any ``>= 3.5`` users will receive version 2.0.0.
132145

133-
It must be done in this order for the automated fallback to work.
146+
It may be a good idea to create a minor release, stating that it is the last one compatible with the Python version to be removed, just before dropping that version.
134147

135-
For example, you published the Requires-Python: ">=2.7" as version 1.0.0 of your package.
148+
When dropping a Python version, it might also be rewarding to upgrade the project's code syntax generally, apart from updating the versions used in visible places (like the testing environment). Tools like pyupgrade_ can simplify this task.
136149

137-
If you were then to update the version string to ">=3.5", and publish a new version 2.0.0 of your package, any users running Pip 9.0+ from version 2.7 will
138-
have version 1.0.0 of the package installed, and any >=3.5 users will receive version 2.0.0.
150+
.. _discourse discussion: https://discuss.python.org/t/requires-python-upper-limits/12663
151+
.. _pyupgrade: https://pypi.org/project/pyupgrade/

0 commit comments

Comments
 (0)