mgedmin / check-python-versions

Check that supported Python versions in a setup.py match tox.ini, .travis.yml and a bunch of other files
https://pypi.org/project/check-python-versions/
GNU General Public License v3.0
21 stars 12 forks source link

check-python-versions

.. image:: https://img.shields.io/pypi/v/check-python-versions.svg :target: https://pypi.org/project/check-python-versions/ :alt: Latest release

.. image:: https://img.shields.io/pypi/pyversions/check-python-versions.svg :target: https://pypi.org/project/check-python-versions/ :alt: Supported Python versions

.. image:: https://github.com/mgedmin/check-python-versions/workflows/build/badge.svg?branch=master :target: https://github.com/mgedmin/check-python-versions/actions :alt: Build status

.. image:: https://coveralls.io/repos/mgedmin/check-python-versions/badge.svg?branch=master :target: https://coveralls.io/r/mgedmin/check-python-versions :alt: Test coverage

This is a tool for Python package maintainers who want to explicitly state which Python versions they support.

The problem: to properly support e.g. Python 2.7 and 3.6+ you have to run tests with these Pythons. This means

Keeping all these lists consistent is a pain.

The solution: check-python-versions will compare these lists and warn you if they don't match ::

$ check-python-versions ~/projects/*
/home/mg/projects/check-manifest:

setup.py says:              2.7, 3.6, 3.7, 3.8, 3.9, PyPy
- python_requires says:     2.7, 3.6, 3.7, 3.8, 3.9
tox.ini says:               2.7, 3.6, 3.7, 3.8, 3.9, PyPy, PyPy3
.travis.yml says:           2.7, 3.6, 3.7, 3.8, 3.9, PyPy, PyPy3
appveyor.yml says:          2.7, 3.6, 3.7, 3.8, 3.9

/home/mg/projects/dozer:

setup.py says:              2.7, 3.6, 3.7, 3.8, 3.9
tox.ini says:               2.7, 3.6, 3.7, 3.8, 3.9
.travis.yml says:           2.7, 3.6, 3.7, 3.8, 3.9
appveyor.yml says:          2.7, 3.6, 3.7, 3.8, 3.9

/home/mg/projects/eazysvn:

setup.py says:              2.7, 3.6, 3.7, 3.8, 3.9, PyPy
tox.ini says:               2.7, 3.6, 3.7, 3.8, 3.9, PyPy, PyPy3
.travis.yml says:           2.7, 3.6, 3.7, 3.8, 3.9, PyPy, PyPy3
appveyor.yml says:          2.7, 3.6, 3.7, 3.8, 3.9

...

all ok!

Installation

You need Python 3.6 or newer (f-strings!) to run check-python-versions. Install it with ::

python3 -m pip install check-python-versions

Usage

::

$ check-python-versions --help
usage: check-python-versions [-h] [--version] [--expect VERSIONS]
                             [--skip-non-packages] [--only FILES]
                             [--add VERSIONS] [--drop VERSIONS]
                             [--update VERSIONS] [--diff] [--dry-run]
                             [where [where ...]]

verify that supported Python versions are the same in setup.py, tox.ini,
.travis.yml and appveyor.yml

positional arguments:
  where                directory where a Python package with a setup.py and
                       other files is located

optional arguments:
  -h, --help           show this help message and exit
  --version            show program's version number and exit
  --expect VERSIONS    expect these versions to be supported, e.g. --expect
                       2.7,3.5-3.8
  --skip-non-packages  skip arguments that are not Python packages without
                       warning about them
  --only FILES         check only the specified files (comma-separated list,
                       e.g. --only tox.ini,appveyor.yml)

updating supported version lists (EXPERIMENTAL):
  --add VERSIONS       add these versions to supported ones, e.g --add 3.9
  --drop VERSIONS      drop these versions from supported ones, e.g --drop
                       2.6,3.4
  --update VERSIONS    update the set of supported versions, e.g. --update
                       2.7,3.5-3.9
  --diff               show a diff of proposed changes
  --dry-run            verify proposed changes without writing them to disk

If run without any arguments, check-python-versions will look for a setup.py in the current working directory.

Exit status is 0 if all Python packages had consistent version numbers (and, if --expect is specified, those numbers match your stated expectations).

If you specify multiple directories on the command line, then all packages that failed a check will be listed at the end of the run, separated with spaces, for easier copying and pasting onto shell command lines. This is helpful when, e.g. you want to run ::

check-python-versions ~/src/zopefoundation/*

to check all 380+ packages, and then want re-run the checks only on the failed ones, for a faster turnabout.

There's also experimental support for updating supported Python versions so you can do things like ::

check-python-versions ~/projects/* --add 3.9 --dry-run --expect 2.7,3.6-3.9
check-python-versions ~/projects/* --drop 3.4 --diff
check-python-versions ~/projects/* --update 2.7,3.6- --dry-run --diff
check-python-versions ~/projects/* --add 3.9 --drop=-2.6,-3.5

(the last one will show a diff for each file and ask for interactive confirmation before making any changes.)

Programmatically updating human-writable files is difficult, so expect bugs (and please file issues).

Files

setup.py or pyproject.toml is the only required file; if any of the others are missing, they'll be ignored (and this will not be considered a failure).

Python versions

In addition to CPython X.Y, check-python-versions will recognize PyPy and PyPy3 in some of the files:

Upcoming Python releases (such as 3.12 in setup.py or 3.12-dev in a .travis.yml) are also shown but do not cause mismatch errors.

In addition, python_requires in setup.py or requires-python in pyproject.toml usually has a lower limit, but no upper limit. check-python-versions will assume this means support up to whatever's the latest Python 3.x release mentioned in other data sources, or the current 3.x release (3.11 at the moment), whichever is lower. This means that new Python 3 releases don't suddenly cause all your lint checks to fail if you use python_requires '>= 3.6' and such.

When you're specifying Python version ranges for --expect, --add, --drop or --update, you can use

or a comma-separated list of the above (e.g. --expect 2.7,3.5-, --drop -2.6,-3.4).

--expect/--add/--drop/--update currently do not allow specifying alternative implementations (such as pypy).

pre-commit integration

With pre-commit <https://pre-commit.com>_, check-python-versions can be part of your git-workflow. Add the following snippet to your .pre-commit-config.yaml.

.. code-block:: yaml

repos:
-   repo: https://github.com/mgedmin/check-python-versions
    rev: "0.22.0"
    hooks:
    -   id: check-python-versions