Table of Contents
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.
Installing Python 3.14
Installing with uv
uv self updateuv 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.
A more detailed overview of both processes can be found in the Installing Python 3.14 on Mac or Windows post.
Add support for 3.14
Workflow and modifications for Python 3.14.
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 -uto 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.
- If it is, you can do a quick
git checkout maingit 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:
- I reorder the Python versions, and put 3.9 before 3.10.
tromlwill aphabetically sort them, putting 3.9 after 3.14, since 1 < 4. - Make sure 3.15 isn’t added, unless you’re really sure about it.
tromlkeeps 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 locally
- 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
Release / Deploy
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!
Whatever method yuo are using to publish to PyPI, do so now.
I’ve been using the trusted publisher thing.
So mostly, for me, deploying means:
git checkout maingit pullto grab the changes I just merged on the servergit 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”.
Supporting 3.14t : Free-threaded Python
Let’s go ahead and test for free-threading enabled Python 3.14.
Mostly, this means using “3.14t” also, wherever we had “3.14”
- Branch
- Add
3.14ttotox.ini- old:
envlist = py39,py310,py311,py312,py313 - old:
envlist = py39,py310,py311,py312,py313,py314,3.14t
- old:
- Add
"3.14t"to.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", "3.14t"]
- old:
- Add “Free Threading” trove classifiers to
pyproject.toml"Programming Language :: Python :: Free Threading","Programming Language :: Python :: Free Threading :: 3 - Stable",- The status of your “Free Threading” support can be announced with one of:
"Programming Language :: Python :: Free Threading :: 1 - Unstable","Programming Language :: Python :: Free Threading :: 2 - Beta","Programming Language :: Python :: Free Threading :: 3 - Stable","Programming Language :: Python :: Free Threading :: 4 - Resilient",
- Run tests locally
toxortox -e py314t
- Update changelog
- Bump version
- Commit and push
- Merge request in CI
- Publish
Thanks to Christian Clauss for reminding me to cover Free Threading
Feedback
If you have a different process, I’d love to hear about it, let me know.