3.12 released 2 October 2023, latest 3.12.14.
Python 3.12 is currently supported. Active support is scheduled to end on 2 April 2025. It reaches end of life on 31 October 2028.
What changed
Python 3.12 adds language-level generic type parameters and the type statement, making common generic classes, functions, and type aliases less dependent on TypeVar boilerplate. F-string parsing is now defined by the regular parser, which removes several former expression restrictions. Comprehensions are inlined in many cases, reducing function-call overhead and changing some implementation details visible to profilers and debuggers. The release also introduces the low-overhead sys.monitoring instrumentation API, support for implementing the buffer protocol in pure Python, and interpreter configuration that can give separate subinterpreters separate GILs. Separate subinterpreter GILs are not the same as the later free-threaded runtime model. At the packaging and extension boundary, distutils has been removed from the standard library, and some long-deprecated APIs and C-API internals are no longer available.
What staying costs
Python 3.12 remains within its supported window, so staying on it does not create an immediate loss of upstream maintenance. The main cost is opportunity cost: later Python lines may provide runtime, tooling, typing, and concurrency improvements that can matter for particular workloads. Dependency maintainers increasingly test and publish wheels for newer interpreters first, so a team that delays can eventually face a larger combined upgrade involving Python, build tooling, and application dependencies. Projects using native extensions have additional exposure because removed C-API internals and packaging changes can surface only when rebuilding or updating an extension. The risk is generally manageable while 3.12 is supported, but it rises if the team stops exercising a newer target in CI and allows compatibility work to accumulate.
What to do
Keep 3.12 patched through the normal maintenance process, and add the intended newer Python line to CI before making it the production default. Run the full test suite, type checking, packaging builds, and representative performance tests on both interpreters; treat changes in profiling, tracing, or debugging output as tooling compatibility work rather than necessarily application defects. Inventory dependencies, especially packages with native extensions, and confirm that compatible wheels or source builds are available for the newer interpreter and target platforms. Replace any direct use of distutils with supported packaging tooling, and update internal build scripts that depend on removed or deprecated APIs. If evaluating subinterpreters, test extension compatibility and isolation explicitly, and do not assume that subinterpreter support gives a single interpreter free-threaded execution. Plan the production rollout with a rollback path and monitor startup failures, extension imports, background workers, and latency-sensitive paths.
We can tell you what moving off Python 3.12 involves.
What it takes to move off Python 3.12 depends on what you built on it — the version you are on, how much depends on it, and how much of the work is mechanical. Leave your email with this version and we can tell you what that looks like for you.
Not sure yet? Get my plan
