Python 3.12 End of Life: Dates and How to Upgrade
Python 3.12 reaches end of life on 31 October 2028 and gets security fixes only now. What that means, when to move, and what breaks going to 3.13 or 3.14.
Python 3.12 reaches end of life on 31 October 2028. Until then it receives security fixes only. Its bugfix support ended on 2 April 2025 (the last regular bugfix release, 3.12.10, followed on 8 April), and when the date passes the core team stops releasing fixes of any kind.
The full table for every version is on the Python end-of-life dates page; if you are still on an older version, see Python 3.10 end of life. This guide covers what the 3.12 date means in practice and how to move off it.
Python 3.12 dates
| Milestone | Date |
|---|---|
| Released | 2 October 2023 |
| Bugfix support ended | 2 April 2025 |
| End of life | 31 October 2028 |
| Latest release (3.12.16) | 25 October 2026 |
These dates come from endoflife.date, which tracks the Python Developer’s Guide. Every feature release gets about five years of support: roughly two of bugfix releases, then security fixes only. There is no separate long-term-support version.
What “security fixes only” means
For Python itself, very little changes day to day. New 3.12 releases still arrive, but they contain security patches rather than bug fixes. A bug that isn’t a vulnerability will be fixed in newer versions and not in 3.12.
The practical pressure comes from outside: libraries drop old Python versions on their own schedule. Pillow 13, for example, dropped Python 3.10 (see the Pillow security guide). Expect the same to happen to 3.12 well before 2028.
Which version to move to
| Target | Supported until | Notes |
|---|---|---|
| 3.13 | October 2029 | Smallest jump from 3.12 |
| 3.14 | October 2030 | A good default target: a year old, with a long support window |
| 3.15 | October 2031 | Released 9 October 2026; start on 3.15.2 or later, see below |
For most projects, 3.14 is the sensible target. Python 3.15 is worth considering for new work, but libraries often need weeks or months to publish wheels for a new release. See what’s new in Python 3.15 and porting to Python 3.15.
What breaks going from 3.12 to 3.13
The Python 3.13 release notes list the changes. The ones most likely to break an upgrade:
- Removed standard library modules (PEP 594). Nineteen “dead batteries” are gone, including
cgi,cgitb,crypt,imghdr,pipes,telnetlib,uuandxdrlib. An import of any of them raisesImportError. The release notes name replacements:shlex.quote()forpipes.quote,email.message.EmailMessageforcgi.parse_header(), andbase64foruu. - Other removals:
lib2to3and2to3,tkinter.tix,locale.resetlocale(), and thetyping.ioandtyping.renamespaces. locals()semantics (PEP 667). In a function, each call tolocals()now returns an independent snapshot, so code that expected earlier results to update will break.pathlib.Path.glob(). A pattern ending in**now returns files as well as directories. Add a trailing slash to keep the old behaviour.functools.partialas a method now emits aFutureWarning; wrap it instaticmethod()to keep the old behaviour.
What breaks going from 3.13 to 3.14
- Removed APIs: the
asynciochild watcher classes,ast.Num,ast.Strand related aliases,pkgutil.get_loader(),urllib.request.URLopener, and theimportlib.abcresource classes (useimportlib.resources.abc). asyncio.get_event_loop()raisesRuntimeErrorwhen there is no current loop instead of creating one. Useasyncio.run().- Deferred annotations (PEP 649). Annotations are no longer evaluated eagerly. Code that reads
__annotations__directly may behave differently; the newannotationlibmodule lets you choose a format. - Multiprocessing default. On Unix other than macOS, the default start method is now
forkserverrather thanfork. Code that relies on forked children inheriting globals will break.
A safe way to upgrade
- Run your tests on the new version first, with warnings turned on:
python -W error -m pytest. Deprecation warnings on 3.12 are removals on 3.13 and 3.14. - Search for removed imports before you start. A quick
grepforimport cgi,telnetlibandpipesfinds most of the standard library fallout. - Check your dependencies publish wheels for the target version. Packages with compiled extensions are the usual blockers.
- Move one minor version at a time if the codebase is large, so a failure points at one set of changes.
- Rebuild anything pinned to 3.12: CI images, containers and lockfiles. A tool like uv can install the new interpreter and create the environment in one step.
Frequently Asked Questions
When does Python 3.12 reach end of life?
31 October 2028. Python 3.12 was released on 2 October 2023, had bugfix support until 2 April 2025, and now receives security fixes only until that date.
Is Python 3.12 still supported?
Yes, but only for security fixes. The last regular bugfix release, 3.12.10, came out on 8 April 2025. The latest 3.12 release at the time of writing is 3.12.16, from 25 October 2026.
Do I have to upgrade from Python 3.12 now?
No. You have until October 2028 before 3.12 stops receiving security fixes. Plan the move within that window, and sooner if a dependency drops 3.12 or you want a newer feature.
Which Python version should I move to from 3.12?
Python 3.14 is the safer target for most projects: it is a full release behind the newest version and supported until October 2030. Python 3.13 is supported until October 2029. Python 3.15, released in October 2026, is supported until October 2031, but give your dependencies a few months to catch up.
What breaks when upgrading from Python 3.12 to 3.13?
Mostly removed standard library modules, such as cgi, telnetlib, imghdr and pipes (PEP 594), plus lib2to3, tkinter.tix and a few typing and locale helpers. Python 3.13 also changed locals() so that each call in a function returns an independent snapshot.
What breaks when upgrading from Python 3.13 to 3.14?
Removed APIs including the old asyncio child watchers, ast.Num and ast.Str, pkgutil.get_loader and urllib.request.URLopener. Annotations are also evaluated lazily, and on Linux the default multiprocessing start method changed from fork to forkserver.