Python 3.14 is here.

If you haven’t done so, it’s time to update your projects to test against 3.14.

The following procedure is what I’m following for a handful of projects. Your process of course may be different if you use different tools.

Honestly, I’m partly writing this down so I don’t have to remember it all in a year when 3.15 rolls around.

Grab a local version of Python 3.14

Installing with uv

  • uv self update
  • uv python install 3.14

While it’s true that creating a virtual environment with uv venv .venv --python 3.14 will install 3.14 if it isn’t already there, you still gotta run uv self update. So I just usually install it while I’m at it.

Installing with the python.org installer

If you’re not on the uv bandwagon yet, it’s still hard to beat downloading and installing from python.org.

Make sure you’re code is the latest and greatest

  • git status - check to see if anything is currently modified from the repo.
    • If it is, you can do a quick git stash -u to save that work for later.
    • Or toss it with git reset --hard HEAD
    • Or check it in if you’re on a branch and want to save your work.
  • git checkout main
  • git pull

Set up a branch to do the mods

  • git checkout -b update-to-3.14

Add “py314” to tox.ini

Example:

  • old: envlist = py39,py310,py311,py312,py313
  • new: envlist = py39,py310,py311,py312,py313,py314

Add 3.14 to trove classifier list

In pyproject.toml:

  • Add 'Programming Language :: Python :: 3.14', line

If you aren’t already listing it here, I recommend it. It let’s people viewing your package on PyPI know you’ve at least thought about 3.14

Note about troml

troml is a fun tool that you can run in your project directory that can suggest trove classifiers.

It’s fun. But when I use it, I notice two changes I like to make:

  1. I reorder the Python versions, and put 3.9 before 3.10. troml will aphabetically sort them, putting 3.9 after 3.14, since 1 < 4.
  2. Make sure 3.15 isn’t added, unless you’re really sure about it. troml keeps adding 3.15 for me. Not sure why.

Add “3.14” to CI test matrix

For most of my projects, that means modifying .github/workflows/main.yml.

  • old: python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
  • new: python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]

(Optional) Deprecate old versions

I generally don’t test 3.8 anymore, for example. So I’m usually yanking 3.8 support out of all the places I just added 3.14 in previous sections.

One additional change. In pyproject.toml, change the requires-python line.

Example:

  • old: requires-python = ">=3.8"
  • new: requires-python = ">=3.9"

Bump version

Since I want to push changes all the way to PyPI, this requires a version bump. My rule of thumb:

  • If I’m just adding support for a new Python version, a bugfix bump is fine. (Ex: 1.1.0 -> 1.1.1)
  • If I’m also removing support for an old Python version, a minor bump seems appropriate. (Ex: 1.1.0 -> 1.2.0)

Add an entry to the changelog

In (usually for me) changelog.md

Add a new entry with something like “Add testing for Python 3.14”. Also note removal of old versions, if removing support. Such as “No longer testing against Python 3.8”.

Test on all local versions

  • Run tox

Fix anything that might have broken

Of course, if the tox run fails, fix it.

Update dependencies

If any dependencies are pinned, now is a great time to try updating those and retesting. It’s good to keep dependencies up to date, and this is a good time to check that.

Be sure to re-run tox

Update changelog (again)

If bug fixing or dependency updates are significant, it’s probably a good idea to make some notes in the changelog.

Commit & push

Honestly, I’ve probably done several commits already in the past steps, but whatever is left now, go ahead and commit and push this 3.14 branch.

Create a merge request in CI

  • Create a merge from the branch to main.
  • Pay attention to CI test results.

Merge

Tests good? Squash and Merge.

Deploy!

However, you are publishing to PyPI, do so now.

I’ve been using the trusted publisher thing.
So mostly, for me, deploying means:

  • git checkout main
  • git pull to grab the changes I just merged on the server
  • git tag -a 1.2.3 -m 'added testing for Python 3.14'
  • git push --tags
  • Head over to CI and watch deployment to make sure it finishes fine

Also, since all of my projects are not on the same process yet, I’ve taken to writing a small .deployment.md file and saving that in the .github directory. GH ignores it and it’s not intrusive to users of the code.

Should you publish a version even if you have no code changes?

A lot of projects don’t. They’ll add tests, maybe, and push to main. But if there are no code changes, why publish a new version?

Well. For me, publishing a new version is a way to communicate to users that “Yes, I’ve tested aginst 3.14 and it works.”.

Putting 3.14 in the trove classifiers makes 3.14 show up in the list in PyPI.

Also, since Python versions come out yearly, you’re at least bumping the version once per year.

Touching the code gets you an opportunity to examine any pinned dependencies and update those.

Having a last release date fairly recently tells users the project isn’t abandoned.

So my answer is YES, puplish a version.
Even if there are no code changes, I think it’s worth it to say:

  • Yes, my project supports Python 3.14
  • Yes, my project is still alive

It’s fine to also say “it already does what it’s supposed to do, so there aren’t any code changes” if you want, alongside the “yep, tested on 3.14 and it works fine”.

Feedback

If you have a different process, I’d love to hear about it, let me know.