tulip-control / dd

Binary Decision Diagrams (BDDs) in pure Python and Cython wrappers of CUDD, Sylvan, and BuDDy
https://pypi.org/project/dd
Other
182 stars 39 forks source link

REL: specify Python version using `Requires-Python`, not Trove classifiers for second numeric component #88

Closed johnyf closed 1 year ago

johnyf commented 1 year ago

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 of dd == 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 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:

and also:

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 version

Given the above reasons, dd releases will list Trove classifiers for the first component of the Python version(s) supported. Example:

PYTHON_REQUIRES = '>=3.11'
...
CLASSIFIERS = [
    ...
    'Programming Language :: Cython',
    'Programming Language :: Python :: 3 :: Only',
    'Topic :: Scientific/Engineering',
    ...]

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 only main.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:

johnyf commented 1 year ago

Implemented as of cc86df663fdc52a482a2fbf39e7ecb6c4a1730b6.