Multiple Python Versions With Tox
I generally like to code in Python when doing my own projects not really sure why, I think it’s just different from my day job as a Java Developer. However when I do develop with Python I like to ensure that what do write works on multiple Python versions. The main reason being is that most of my stuff runs on single board computers and users might not have new versions of Python and I don’t like to restrict things. This is why I use pyenv to handle the installation of multiple versions of Python and then use tox to build all versions at once with tests and coverage. These tests and coverage results are also used when pushed to GitHub to ensure that everything is ok 😄
Setting up Pyenv
I feel it makes sense to first install pyenv and have that configured. We need to first set up the machine to be able to compile and install various Python versions, this is because pyenv goes to get the source for Python and builds it locally.
|
|
The next step is to update my bash profile so that pyenv is on the path and initialised. Adding the following to the end of the profile is enough.
|
|
Then the profile needs to be reloaded. Then check the versions.
|
|
Installing Python Versions
The next step is actually install the various Python versions, there’s a lot of choice which can be displayed with pyenv install –list. However I like to keep things simple and install the latest version of 3.9 -> 3.11 with the following.
|
|
This command will take a while depending on your machine, as it has to download and compile each version so go get a cup of tea. Once done it’s time to set what the default Python version is, in my case I set it to 3.10.12.
|
|
That should be all for pyenv, you can see what versions are installed at any time by running the following.
|
|
Setting up Tox
Before installing Tox I need to ensure that I have PIP installed globally, this is the tool that installs Python packages and will be used to install Tox globally as well. I recommend installing Pip and Tox globally because when running builds tox will create it’s own virtual environments for each of the Python versions. If tox was installed within a virtual environment it would only use the version of Python present in the virtual environment which is not what I want.
|
|
Now that tox is installed I need to add yet another line at the end of my bash profile. Then reload it.
|
|
This should be all the configuration needed for getting tox with multiple versions of python set up. If you don’t have a project already set up for tox you can use this one. Clone this repository down, go into the root of the project and simply run tox, if you have the same versions of python configured as I have above it should run multiple builds one after the other with a code coverage report for each.
GitHub Action
The final step which isn’t really setting up multiple python versions with tox, but it’s somewhat related is to have the same thing happen on GitHub Actions. This allows tests and code coverage for each of the python versions I installed earlier to be triggered.
|
|
In the above I’m creating a matrix of python versions, similar to the versions that I created using pyenv. The first step is to check out the codebase. The second step is to setup Python on the runner, the version is set to the matrix defined earlier, this will make GitHub create runners for each of the versions of Python defined resulting in concurrent builds. An added option here is to cache the pip results, this results in faster builds later on, as the downloaded dependencies are saved locally to the runner and don’t have to be downloaded each time.
Once the runner has been set up, pip is used to install tox and run with the python version of the given environment. The final step is optional which is to take the code coverage report and publish it to coveralls which is great if you’re not aware of it.