Have you updated your Python recently?

MP 88: It's never too late to start a good updating habit.

I'll be the first to admit, I don't stay on top of updates nearly as well as I should. The libraries and tools I use most often have gotten good enough that I can usually coast on older versions for a long time without noticing any issues.

That said, I've been aware for a long time that I should be updating my tools more often. I'm writing this post partly to encourage you to update your installed version of Python if you haven't recently, and partly to document my own updating process.

Why update Python?

Most people seem to be aware of significant new releases of Python as they become available. For example, the latest version is 3.12. Most of the people I talk to who are still using 3.11 are doing so by choice, not because they're unaware that 3.12 is available.

It's a perfectly reasonable choice to wait a little while before upgrading from a version like 3.11 to 3.12. You might not need the newest features, or you might be working on a project where someone else is in charge of the decision about when to upgrade. Your users might be on a variety of older versions, and you might not be able to use 3.12-only features, even if you wanted to.

A great tool for deciding when you need to upgrade is Python's Status page. That page shows the support status for all versions of Python that have been released, and the next version that's going to be released. Here's the chart from that page:

The status of all significant Python releases, as of 3/19/2024. Python 3.8 is about to stop getting security fixes, so you should upgrade from that by October of this year if you're still using it. Python 3.13 will be released in October of this year.

If you're interested in learning more about how Python is developed and maintained, the Development cycle page is an excellent resource as well.

What many people are less aware of is the availability of point releases. The point releases are the incremental updates such as 3.12.1, 3.12.2, and so forth. Quick quiz: What version are you using on your system, and what is the latest available point release of that version? If you're not sure, you might want to check whether your installed version is fully up to date.

I do most of my daily work using Python 3.11. More specifically, I'm using 3.11.5 at the moment:

$ python -V         
Python 3.11.5

I'm on 3.11.5, but the most recent version is 3.11.8. There have been three point releases since I last updated.

Python's point releases include security updates and bug fixes. If you want to see how much goes into each new point release, take a look at your version's changelog. For example, here's the changelog for Python 3.11. There's a long list of changes between 3.11.5 and 3.11.8! I can't possibly keep up with all those changes, and sort out which ones might affect me or my users.

While there are many good reasons to stay on a slightly older, but still maintained version like 3.11 instead of moving right away to 3.12, there's no good reason to stay on older point releases. Even if you haven't run into any problems with your installed version, it's a good idea to update to the latest point release as soon as it comes out.

Updating Python using the official installer

If you only have one version of Python installed on your system, and you used the official installer, updating should be pretty straightforward:

  • Go to the Downloads page on python.org.
  • Scroll down to the Looking for a specific release? section, and click the Download link for the most recent point release of the version you're using.
  • Run the installer.
  • Run python -V, or your system's equivalent command, to make sure the new version is active. (You may need to close any open terminals or editors for the update to take effect.)
The Downloads page at python.org has a list of installers for all available point releases. You can find the latest point release for the version you're using here.

Remember to rebuild any virtual environments you're currently using. More on that in a moment.

Using pyenv to manage multiple versions of Python

For a long time I only ever used one version of Python at a time. When I started maintaining a wider variety of projects, I needed to have multiple versions of Python available. pyenv is a great tool for managing that kind of need.

Once pyenv is installed, you can use it to install multiple versions of Python and switch between them. You can see all the versions that are available for installation:

$ pyenv install --list
Available versions:
  2.1.3
  ...
  3.10.13
  ...
  3.11.8
  ...
  3.12.2
  3.13.0a3
  3.13-dev
  ...

I already have 3.11.5 installed, and updating is as simple as installing the latest point release available through pyenv:

% pyenv install 3.11.8
...
Downloading Python-3.11.8.tar.xz...
Installing Python-3.11.8...
...
Installed Python-3.11.8 to /Users/eric/.pyenv/versions/3.11.8

Now I can see which versions I have installed, and switch to this latest version:

$ pyenv versions
  system
  3.11.2
* 3.11.5 (set by /Users/eric/.pyenv/version)
  3.11.8
  3.12.0rc2
$ pyenv global 3.11.8
$ python -V
Python 3.11.8

You can see that I've only been updating every three point releases or so (3.11.2 -> 3.11.5 -> 3.11.8). After writing this post I should be more consistent about updating as soon as each point release becomes available.

I won't show it all here, but I'm going to update my installed version of 3.12 to a stable release. I installed a pre-release version of 3.12 for testing, but haven't used it for any projects yet. I'm also going to install an early release candidate of 3.13 for some testing.

I'm going to take a moment to remove the point releases I'll never use again:

$ pyenv uninstall 3.11.2 3.11.5 3.12.0rc2
pyenv: remove /Users/eric/.pyenv/versions/3.11.2? [y|N] y
pyenv: 3.11.2 uninstalled
pyenv: remove /Users/eric/.pyenv/versions/3.11.5? [y|N] y
pyenv: 3.11.5 uninstalled
pyenv: remove /Users/eric/.pyenv/versions/3.12.0rc2? [y|N] y
pyenv: 3.12.0rc2 uninstalled
$ pyenv versions
  system
* 3.11.8 (set by /Users/eric/.pyenv/version)
  3.12.2
  3.13.0a3

Now I have the version of Python that came with my system, the latest point releases of 3.11 and 3.12, and a pre-release version of 3.13. This feels good!

Rebuild your virtual environments

When you update a version of Python that was previously installed, you'll need to rebuild any virtual environments that were originally built with that version of Python.

For example, here's what happens if I try to run a project I've been working on recently, that uses a virtual environment built with Python 3.11.5:

ghost-codeblock-parser$ source .venv/bin/activate
ghost-codeblock-parser$ python highlight_post.py --help
Traceback (most recent call last):
  ...
    import jwt
ModuleNotFoundError: No module named 'jwt'
(.venv) ghost-codeblock-parser$ pip freeze
...bad interpreter: .../.venv/bin/python:
no such file or directory

I can still activate the virtual environment, but the project's dependencies aren't available.

This isn't a problem; it's one of the features of virtual environments. They're supposed to be easy to destroy and rebuild whenever you need a fresh version of the environment:

(.venv) ghost-codeblock-parser$ deactivate 
ghost-codeblock-parser$ rm -rf .venv 
ghost-codeblock-parser$ python -m venv .venv
ghost-codeblock-parser$ source .venv/bin/activate
(.venv) ghost-codeblock-parser$ pip install -r requirements.txt 
Collecting beautifulsoup4==4.12.3
...
Successfully installed PyJWT-2.8.0 ...urllib3-2.2.1
(.venv) ghost-codeblock-parser$ python highlight_post.py --help
usage: highlight_post.py [-h] [--source-file SOURCE_FILE] [-v]

options:
  -h, --help            show this help message and exit
  --source-file SOURCE_FILE
  -v, --verbose
(.venv) ghost-codeblock-parser$ python highlight_post.py 
(.venv) ghost-codeblock-parser$

Here we deactivate and remove the outdated environment. We then build a new one, activate it, and install the project's requirements. After this, the project runs once again.

Conclusions

If you're like me and have avoided keeping your version of Python fully up to date, consider establishing a better updating habit by installing each new point release as it comes out. Document your workflow so you don't have to rethink the process every time. A great way to do this is to open an issue in one of your projects called Update Python version, and write down everything you do to update Python for that project. The next time you need to update, which should be in just a few months, you'll almost certainly be able to find that issue.

If you're not sure how to update your version of Python, and you don't have a better place to ask, feel free to leave a comment. Describe briefly how you installed Python, and I'll try to help you get it updated.