Trove classifiers are part of the interface specification of Python packages. They include specifying the versions of Python that a package supports.
Currently, the second component of Python's version is incremented yearly (PEP 602).
Wheel files that are specific to the second component of Python's version (e.g., different wheels for Python 3.11 than Python 3.10) require new files to be uploaded to the Python Package Index (PyPI).
dd wheel files include binaries compiled for specific CPython versions, so new wheel files are needed yearly on PyPI.
Which PyPI release the wheel file goes to
When no source code changes are needed to create the wheel file for the new CPython version, then the file can be uploaded to the package's latest PyPI release.
However, doing so is implicit with respect to the contract defined by the Trove classifiers of the already released version. This is due to Trove classifiers enumerating Python versions, instead of describing them with a formula (i.e., a Boolean-valued expression).
The package metadata field Requires-Python (PEP 566) is a formula. So it can describe infinitely many Python versions.
Uploading a wheel file for dd == 0.5.6 for CPython 3.10 would work, but not be reflected in the Trove classifiers of dd == 0.5.6, because those classifiers were defined when dd == 0.5.6 was released (which was before CPython 3.10 was released).
Requires-Python implies Trove classifiers
So to change Trove classifiers that mention the second component of Python's version, new releases of dd are required. Creating a new release requires incrementing the version number of dd.
But:
Trove classifiers are already implied by the metadata field Requires-Python
Requires-Pythonis information used by pip during installation.
Trove classifiers are not used by pip during installation.
and also:
Trove classifiers and Requires-Python can get out of sync, which is an inconsistency in package code.
Trove classifiers and Requires-Python can diverge.
Trove classifiers can be inconsistent, because it seems they are not checked for satisfiability.
For example, listing the Trove classifiers:
Programming Language :: Python :: 2 and
Programming Language :: Python :: 3 :: Only
together, raises no error when packaging a distribution.
In contrast, Requires-Pythonis checked for satisfiability.
For example, defining:
Requires-Python: >=3.11,<3.11
raises the error:
ERROR: Package 'dd' requires a different Python: 3.11.0 not in '<3.11,>=3.11'
when running pip install .
Trove classifiers being enumerative implies that unlisted future Python releases that happen to be supported by the package, will be missing from the classifiers.
In contrast, Requires-Python can include future Python releases. In principle, a Python package that uses only Python syntax that is expected to never change in Python's grammar, can thus declare support for all future Python releases.
Besides, creating a new release for only adding a version-related Trove classifier:
Consumes a version number.
Suggests checking the changelog for changes, when there are none in package functionality.
Would unnecessarily add to the changelog (or cause confusion, if omitted from the changelog).
Solution: Use Requires-Python, and Trove classifiers for first component of Python version
Given the above reasons, dd releases will list Trove classifiers for the first component of the Python version(s) supported. Example:
The second component of Python's version is not specified in Trove classifiers. PyPI lists Requires-Python on the package's entry, when the package's metadata defines it.
With this change, wheels of dd for new CPython releases can be uploaded to PyPI without the need for incrementing the version number of dd.
If there are changes to dd that are to be released, then a new version of dd will be created.
But in absence of such changes, uploading a new wheel file to PyPI will suffice, and be in accord with the contract defined by the existing metadata (Requires-Python and Trove classifiers of Python version up to second numeric component).
When uploading a new wheel file, the continuous-integration tests (currently using GitHub Actions) in the repository of dd will need adding the new Python version.
This involves one git commit, to the file .github/workflows/main.yml. The commit will be described as, e.g., CI: test using CPython 3.12, not REL: support Python 3.12.
The CI configuration file .github/workflows/main.yml is not part of code in the package dd. So no new release of dd is needed when changing onlymain.yml.
The new wheel file uploaded to PyPI will be created from the tag of that release, not branch main. Since branch main and the tagged tree differ by only changes to main.yml, the resulting wheel file is the same.
In other words, using Requires-Python as the specification, enables:
Uploading wheels for new yearly Python releases, to the same dd release.
Testing in CI using these new Python releases, without changing the source code of dd.
Wheel files need updating
Trove classifiers are part of the interface specification of Python packages. They include specifying the versions of Python that a package supports.
Currently, the second component of Python's version is incremented yearly (PEP 602).
Wheel files that are specific to the second component of Python's version (e.g., different wheels for Python 3.11 than Python 3.10) require new files to be uploaded to the Python Package Index (PyPI).
dd
wheel files include binaries compiled for specific CPython versions, so new wheel files are needed yearly on PyPI.Which PyPI release the wheel file goes to
When no source code changes are needed to create the wheel file for the new CPython version, then the file can be uploaded to the package's latest PyPI release.
However, doing so is implicit with respect to the contract defined by the Trove classifiers of the already released version. This is due to Trove classifiers enumerating Python versions, instead of describing them with a formula (i.e., a Boolean-valued expression).
The package metadata field
Requires-Python
(PEP 566) is a formula. So it can describe infinitely many Python versions.Example
For example, wheels of
dd == 0.5.6
can be compiled for both CPython 3.9 and CPython 3.10. However, the Trove classifiers ofdd == 0.5.6
do not list Python 3.10.Uploading a wheel file for
dd == 0.5.6
for CPython 3.10 would work, but not be reflected in the Trove classifiers ofdd == 0.5.6
, because those classifiers were defined whendd == 0.5.6
was released (which was before CPython 3.10 was released).Requires-Python
implies Trove classifiersSo to change Trove classifiers that mention the second component of Python's version, new releases of
dd
are required. Creating a new release requires incrementing the version number ofdd
.But:
Requires-Python
Requires-Python
is information used bypip
during installation.pip
during installation.and also:
Requires-Python
can get out of sync, which is an inconsistency in package code.Requires-Python
can diverge.Trove classifiers can be inconsistent, because it seems they are not checked for satisfiability. For example, listing the Trove classifiers:
Programming Language :: Python :: 2
andProgramming Language :: Python :: 3 :: Only
together, raises no error when packaging a distribution.
In contrast,
Requires-Python
is checked for satisfiability. For example, defining:raises the error:
when running
pip install .
Trove classifiers being enumerative implies that unlisted future Python releases that happen to be supported by the package, will be missing from the classifiers.
In contrast,
Requires-Python
can include future Python releases. In principle, a Python package that uses only Python syntax that is expected to never change in Python's grammar, can thus declare support for all future Python releases.Besides, creating a new release for only adding a version-related Trove classifier:
Solution: Use
Requires-Python
, and Trove classifiers for first component of Python versionGiven the above reasons,
dd
releases will list Trove classifiers for the first component of the Python version(s) supported. Example:The second component of Python's version is not specified in Trove classifiers. PyPI lists
Requires-Python
on the package's entry, when the package's metadata defines it.With this change, wheels of
dd
for new CPython releases can be uploaded to PyPI without the need for incrementing the version number ofdd
.If there are changes to
dd
that are to be released, then a new version ofdd
will be created.But in absence of such changes, uploading a new wheel file to PyPI will suffice, and be in accord with the contract defined by the existing metadata (
Requires-Python
and Trove classifiers of Python version up to second numeric component).When uploading a new wheel file, the continuous-integration tests (currently using GitHub Actions) in the repository of
dd
will need adding the new Python version.This involves one
git
commit, to the file.github/workflows/main.yml
. The commit will be described as, e.g.,CI: test using CPython 3.12
, notREL: support Python 3.12
.The CI configuration file
.github/workflows/main.yml
is not part of code in the packagedd
. So no new release ofdd
is needed when changing onlymain.yml
.The new wheel file uploaded to PyPI will be created from the tag of that release, not branch
main
. Since branchmain
and the tagged tree differ by only changes tomain.yml
, the resulting wheel file is the same.In other words, using
Requires-Python
as the specification, enables:dd
release.dd
.