Skip to content

What's New in Python 3.14

New in 3.14

Python 3.14 was officially released in October 2025. The headline features are continued progress on the free-threaded interpreter, a bunch of quality-of-life improvements to the standard library, and some notable semantics fixes that have been on the backlog for years.

This page covers what's most useful to application developers. For the full change log, see the official changelog.


Summary of Major Changes

Category Change
Language locals() semantics made consistent (PEP 667)
Language Template strings (t"...") — PEP 750
Standard Library annotationlib — new module for evaluating annotations
Standard Library ast improvements for string interpolation
CPython Free-threaded mode improvements (GIL disabled builds)
CPython str.replace() micro-optimizations

PEP 750 — Template Strings (t"...")

This is the big new syntax addition. Template strings (t-strings) look like f-strings but instead of producing a str, they produce a Template object that your code can process before rendering. This is especially useful for safely building SQL queries, HTML, shell commands, or any context where you need to sanitize interpolated values.

# Regular f-string — produces a str immediately
name = "Alice'; DROP TABLE users; --"
query = f"SELECT * FROM users WHERE name = '{name}'"
# ^ Dangerous! SQL injection waiting to happen.

# t-string — produces a Template object
from string.templatelib import Template  # hypothetical import

name = "Alice'; DROP TABLE users; --"
query = t"SELECT * FROM users WHERE name = '{name}'"
# query is a Template, not a str
# Your SQL library can safely parameterize it

Not for general use yet

Template strings are a framework author feature. If you write application code, you'll benefit from libraries built on top of t-strings (e.g., safe templating engines, logging formatters). You probably won't write Template processors yourself unless you maintain a library.


PEP 667 — Consistent locals() Semantics

If you've ever been confused about why modifying the dict returned by locals() inside a function doesn't actually change the local variables, this one's for you.

Before 3.14, locals() returned a snapshot dict. After 3.14 in certain scopes it returns a live view — but the behavior is now defined, not implementation-specific. This mostly matters for debuggers and introspection tools.

def demo():
    x = 10
    locs = locals()
    print(locs["x"])  # 10 — consistent in 3.14+

annotationlib — New Standard Library Module

Python 3.14 ships annotationlib, which provides utilities for working with annotations — especially for handling from __future__ import annotations style deferred evaluation.

import annotationlib

def greet(name: str) -> str:
    return f"Hello, {name}"

# Get annotations with deferred evaluation handled correctly
annotations = annotationlib.get_annotations(greet)
print(annotations)  # {'name': str, 'return': str}

This replaces the ad-hoc typing.get_type_hints() for most use cases.


Free-Threaded CPython (Continued Progress)

The experimental free-threaded build (GIL disabled) from 3.13 is maturing. In 3.14:

  • More extensions have been ported to be thread-safe
  • Performance regressions in single-threaded code have been reduced
  • The PYTHON_GIL=0 environment variable continues to control it

To check if your Python build supports free threading:

import sys
print(sys._is_gil_enabled())  # True in normal build, False in free-threaded

Should you care?

If you write web servers or data processing pipelines that use threading, free-threaded Python will eventually let you run CPU-bound work in multiple threads without the GIL bottleneck. It's not production-ready for most workloads yet, but it's worth following.


Deprecations and Removals

Removed in 3.14

  • cgi and cgitb modules — removed (deprecated since 3.11)
  • aifc, audioop, chunk, crypt, imghdr, mailcap, msilib, nis, nntplib, ossaudiodev, pipes, sndhdr, spwd, sunau, telnetlib, uu, xdrlib — all removed (deprecated since 3.11/3.12)

If you use any of these, you need to either find a third-party alternative or vendor the old code.

Deprecated in 3.14

  • pkgutil.find_loader() — use importlib.util.find_spec()
  • typing.io and typing.re sub-modules

Migration from 3.13

For most codebases, upgrading from 3.13 to 3.14 is low-risk. The main things to check:

  1. Removed modules: Run python -m py_compile or your test suite to catch import errors from removed modules.
  2. locals() behavior: If you modify locals() dict in a function and rely on that affecting local variables (which was never guaranteed), test carefully.
  3. Annotation evaluation: If you use typing.get_type_hints(), verify behavior with the new annotationlib if annotations behave oddly.