Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update "Dropping older Python versions" guide #1471

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

chrysle
Copy link
Contributor

@chrysle chrysle commented Dec 23, 2023

An attempt to improve the guide. Actually I find the title a bit inaccurate. What about "Changing required Python versions in the package metadata"?


馃摎 Documentation preview 馃摎: https://python-packaging-user-guide--1471.org.readthedocs.build/en/1471/guides/dropping-older-python-versions/

@@ -4,23 +4,17 @@
Dropping support for older Python versions
==========================================

Dropping support for older Python versions is supported by the standard :ref:`core-metadata` 1.2 specification via a "Requires-Python" attribute.
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

support ... is supported

Can we change one of these words to something else to improve the writing style?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, perhaps using s/a/the/ would be more grammatically correct.

Comment on lines 91 to 92
For :ref:`setuptools` users, another way to achieve this is using the ``python_requires`` parameter
in the call to ``setup`` within your :file:`setup.py` script.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this a bit more accurate:

Suggested change
For :ref:`setuptools` users, another way to achieve this is using the ``python_requires`` parameter
in the call to ``setup`` within your :file:`setup.py` script.
For :ref:`setuptools` users, another way to achieve this is using the ``python_requires`` parameter in your :file:`setup.cfg` config or the :file:`setup.py` script.
``setuptools < 61`` does not support declaring the package metadata in :file:`pyproject.toml`.



For :ref:`setuptools` users, another way to achieve this is using the ``python_requires`` parameter
in the call to ``setup`` within your :file:`setup.py` script.

.. code-block:: python
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we demonstrate using a declarative config instead of a script here?

Suggested change
.. code-block:: python
.. code-block:: ini
# setup.cfg
[options]
python_requires = >= 3.8

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, setuptools now has comprehensive examples in the docs. See:

So perhaps linking them instead of having a tool-specific example spelled out, would be a good option.

)

It is warned against adding upper bounds to the version ranges, e. g. ``">= 3.8 < 3.10"``. This can cause different errors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add an admonition here? Like .. caution::? https://pradyunsg.me/furo/reference/admonitions/#caution

3. Validating the Metadata before publishing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

This file is generated by :ref:`distutils` or :ref:`setuptools` when it generates the source package.
The file contains a set of keys and values, the list of keys is part of the PyPa standard metadata format.
This file is generated by the build backend when it generates the source package.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you link the build backend term?


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

.. code-block:: bash

tar xfO dist/my-package-1.0.0.tar.gz my-package-1.0.0/PKG-INFO
tar xf dist/my-package-1.0.0.tar.gz my-package-1.0.0/PKG-INFO -O
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

``Requires-Python`` should be amended. Of course this also depends on whether the project needs to be stable and
well-covered for a wider range of users.

Each version compatibility change should have an own release.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Each version compatibility change should have an own release.
Each version compatibility change should have its own release.

Comment on lines 142 to 144
For example, you published version 1.0.0 of your package with ``Requires-Python: ">= 2.7"`` metadata.

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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I agree with this at all. It's absolutely orthogonal to SemVer. The dependency resolvers will always select a runtime-compatible version for as long as this information is present in the package metadata.

Dropping a runtime support is not a feature change. And in SemVer, the major version release is for breaking APIs a project provides to the end-users. This metadata change may happen anytime and is a subject to different considerations that are dependent on the conventions of specific projects.

Let's not overload this guide with assumptions based on one specific schema for communicating API changes, that is known to be problematic anyway.

The maintainers can choose to synchronize dropping a runtime with a versioning scheme of their choice but that's not something that is mandatory for changing a metadata field value.

I think @jaraco mentioned this too somewhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed on not making assumptions about versions schemes.

It's been my instinct that dropping a platform isn't a breaking change because of the reasons described (it doesn't break anyone who's likely to download it).


It must be done in this order for the automated fallback to work.
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this advice makes sense anymore. It could be a patch release too. The idea here was that before Requires-Python became a thing, many projects were released without this bit of metadata. And this would cause the dependency resolver to treat the old releases as supporting any Python runtime. So if people were to add a high minimum Python version right away, the resolver would backtrack to the one immediately preceding release.

So this is a good advice for old project that never had this metadata field set. Once they start using it, they can update it anytime, regardless of any other pieces of the metadata.

1. The publisher is using the latest version of :ref:`setuptools`,
2. The latest version of :ref:`twine` is used to upload the package,
3. The user installing the package has at least Pip 9.0, or a client that supports the Metadata 1.2 specification.
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.

Dealing with the universal wheels
Copy link
Member

@webknjaz webknjaz Dec 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chrysle this paragraph is specifically talking about setuptools, bdist_wheel as a setuptools' command that invokes the wheel project APIs internally and a CLI option (in the tip block below) that is supposed to be passed to the direct CLI invocation of setup.py, which is also discouraged.

So while you're on it, could to add clarifications that it's solely about the setuptools' mechanisms and maybe drop (or rephrase) the suggestions to use the CLI flag?


For example, you published the Requires-Python: ">=2.7" as version 1.0.0 of your package.
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's put this into an admonition like .. hint:: or .. tip::.

Co-authored-by: Sviatoslav Sydorenko <wk.cvs.github@sydorenko.org.ua>
Co-authored-by: Jean Abou-Samra <37271310+jeanas@users.noreply.github.com>
@chrysle
Copy link
Contributor Author

chrysle commented Jan 1, 2024

Thank you for your comments! I addressed them.

Copy link
Contributor

@jeanas jeanas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the lack of explicit approval here. (I'm also going to resolve my comments. Edit: In fact I don't have the permissions to resolve them.)

@chrysle
Copy link
Contributor Author

chrysle commented Jan 26, 2024

(I'm also going to resolve my comments. Edit: In fact I don't have the permissions to resolve them.)

I did that now, thank you for your review!

@chrysle chrysle requested a review from webknjaz January 29, 2024 14:26
Requires-Python: ">=3"
Requires-Python: ">2.7,!=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
Requires-Python: ">= 3"
Requires-Python: ">= 2.7, != 3.0.*, != 3.1.*, != 3.2.*, != 3.3.*"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this example be updated to use newer Python versions? I don't think most people reading this guide would be interested in supporting Python 2.7 or 3.4-3.7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants