VVersions.dev

Upgrade to Python 3.14

Python 3.14 is the current stable release. From a recent 3.x the upgrade is mostly low-risk, but lazy-by-default annotations (PEP 649/749) can break code that reads __annotations__ directly, and the free-threaded/no-GIL build (now officially supported) changes assumptions for C extensions.

Version upgradeDifficulty: moderateEffort: 0.5–3 days from a recent Python 3.xmedium risk

Last verified · Updated May 22, 2026

Python 3.14 (3.14.0 on 2025-10-07) is the recommended target. For code already on 3.12/3.13 the move is routine; the watch items are lazy-by-default annotations (PEP 649/749), the cumulative removals across 3.13 (PEP 594 "dead batteries", 2to3) and 3.14, and — if you opt in — the now officially supported free-threaded (no-GIL) build.

Who should upgrade

  • Projects on Python 3.12, now in security-only maintenance, that want active bugfix support again.
  • Teams that want the faster CPython, the new color/auto-completing REPL, and t-strings (PEP 750).
  • Workloads that are CPU-bound and thread-parallel — the free-threaded build is now officially supported (PEP 779).

Who should wait

  • Apps depending on a C extension or framework without a Python 3.14 wheel yet — 3.13 is the safe fallback.
  • Code that introspects annotations heavily and is not yet ported to annotationlib.
  • Teams that cannot tolerate the experimental JIT or free-threaded ABI — both are opt-in, so most can simply leave them off.

What changed (3.13 → 3.14)

  • Annotations are evaluated lazily by default (PEP 649/749); read them via annotationlib.get_annotations() with VALUE/FORWARDREF/STRING formats.
  • Free-threaded (no-GIL) build is officially supported (PEP 779); single-threaded overhead is now ~5–10%, down from ~40% in 3.13.
  • The experimental JIT (PEP 744) now ships in official Windows and macOS binaries; still gated behind PYTHON_JIT and off by default.
  • Template strings / t-strings (PEP 750) add a safe, structured alternative to f-strings for HTML/SQL/logging.
  • New stdlib: annotationlib, compression.zstd (PEP 784), and concurrent.interpreters (PEP 734).
  • More deprecated APIs removed across argparse, asyncio, email, importlib, pathlib, urllib and others.

What changed earlier (3.12 → 3.13)

  • PEP 594 removed 19 "dead battery" stdlib modules (cgi, telnetlib, nntplib, crypt, imghdr, sndhdr, pipes, aifc, audioop, and more).
  • The 2to3 tool and lib2to3 module were removed, along with tkinter.tix.
  • A new interactive REPL (multiline editing, colored tracebacks) and improved error messages landed.
  • Free threading (PEP 703) and the JIT (PEP 744) debuted as experimental in 3.13.

⚠ Lazy annotations can change runtime behavior

In 3.14 annotations are not evaluated at definition time. Code that reads cls.annotations or relies on eager NameErrors may behave differently. Port introspection to annotationlib.get_annotations(obj, format=...) and test type-driven libraries (pydantic, dataclasses, attrs) against 3.14 before shipping.

Diagnostic commands

Fail fast on removed-module and deprecation usage

# Recreate the env on 3.14 and surface removed-module/deprecation usage as errors
python3.14 -m venv .venv && . .venv/bin/activate
pip install -e .
python -W error::DeprecationWarning -m pytest -q

# Optional: try the officially supported free-threaded build separately
# python3.14t -c "import sys; print(sys._is_gil_enabled())"

Compatibility matrix

ConcernPython 3.12Python 3.14
AnnotationsEager by defaultLazy by default (PEP 649/749)
Free threadingNot availableOfficially supported build (python3.14t)
JITNot presentExperimental, in official Win/macOS binaries
t-stringsNot availableAvailable (PEP 750)
cgi / telnetlib / nntplibAvailableRemoved in 3.13 (PEP 594)
2to3 / lib2to3AvailableRemoved in 3.13

AI-assisted upgrade workflow

Upgrade this project from its current Python 3.x to Python 3.14. First inspect for: imports of PEP 594 modules removed in 3.13 (cgi, cgitb, telnetlib, nntplib, crypt, imghdr, sndhdr, pipes, aifc, audioop, chunk, mailcap, msilib, nis, ossaudiodev, spwd, sunau, uu, xdrlib), use of 2to3/lib2to3, and any code that reads __annotations__ or get_type_hints directly. Then recreate the venv on 3.14, install, and run the test suite with -W error::DeprecationWarning. Replace removed modules with their documented stdlib or PyPI alternatives, port annotation introspection to annotationlib, and resolve pip resolver conflicts. Run pip check and tests after each step and report before continuing. Do not enable the free-threaded build or JIT unless explicitly asked.

Safety: Incremental edits only. Treat free-threading and the JIT as opt-in; do not switch them on as part of a routine upgrade.

PR review checklist

  • Project installs and tests pass on 3.14 in a clean venv
  • No imports of PEP 594-removed modules or 2to3/lib2to3 remain
  • Annotation introspection uses annotationlib, not raw annotations, where 3.14 semantics differ
  • Dependencies publish 3.14 wheels (or 3.13 fallback is documented)
  • pip check passes and no new DeprecationWarnings appear in tests

Rollback strategy

  • Keep the venv recreation, module replacements, and annotation porting in separate commits.
  • Pin the prior interpreter (3.12/3.13) and dependency set so the old environment can be rebuilt.
  • Hold the upgrade behind a branch until the full suite is green on 3.14, including any type-driven libraries.

Common errors

  • ModuleNotFoundError: No module named 'cgi' (or telnetlib/nntplib) — module removed in 3.13; use the documented replacement.
  • NameError or empty annotations at runtime — lazy annotations; switch to annotationlib.get_annotations().
  • ResolutionImpossible from pip — a dependency lacks a 3.14 wheel; pin a compatible version or fall back to 3.13.

Official sources

Copy-ready AI prompts

Structured prompts for an AI coding assistant. Inspect first, then execute incrementally, and keep a human in the review loop.

Repo inspection: Repo inspection prompt

You are helping migrate a Python codebase from Python 3.x to Python 3.14.

Do not edit files yet. First inspect the repository and report:
1. The exact Python version requirement in setup.py / pyproject.toml / tox.ini / CI config, and the interpreter the project runs on.
2. Python 2-only syntax: print statements, integer-division reliance, except Foo, e: syntax, dict.iteritems/iterkeys/itervalues, xrange, and unicode/str/bytes confusion.
3. Removed/deprecated module usage: distutils, imp, and deprecated collections ABC aliases (collections.Mapping etc.).
4. The dependency manifest (requirements.txt vs lock vs pyproject), any C-extension builds, and pinned versions.
5. The test runner, virtualenv/venv setup, and the install/build/test commands.

Return: a migration risk summary, the files most likely to break, a suggested migration order, the commands to run before editing, and any questions that need human confirmation.

Safety: Inspection only. The agent must not modify files in this step.

Works with Claude Code, Cursor, GitHub Copilot.

Migration execution: Migration execution prompt

Migrate this codebase from Python 3.x to Python 3.14, one concern at a time.

Work in this order and pause for review after each: (1) create and activate a fresh virtualenv/venv on the target interpreter, (2) run an automated pass with python -m future.utilities futurize (or 2to3) and review the diff, (3) replace removed/deprecated modules (distutils -> setuptools/pyproject, imp -> importlib, collections ABC aliases), (4) fix unicode/bytes boundaries explicitly, (5) reinstall dependencies and resolve pip resolver conflicts.

After each step run pip check and the project's lint and tests, and report results before continuing. Do not refactor unrelated code.

Safety: Apply changes incrementally and keep each step reviewable. Never bundle unrelated refactors.

Works with Claude Code, Cursor, GitHub Copilot.

Test plan

Commands

  • python -m venv .venv && . .venv/bin/activate
  • pip install -e .
  • pip check
  • python -m pytest -q

Manual checks

  • Text/bytes: confirm file and network I/O encode/decode explicitly and round-trips.
  • Division: verify code that relied on Python 2 integer division still produces expected results.
  • C extensions: confirm any compiled dependencies build against the target interpreter.

Regression risks

  • Silent behavior change from true division replacing integer division.
  • Bytes/str mix-ups surfacing only at runtime on non-ASCII input.
  • C-extension dependencies without wheels for the target interpreter.

Acceptance criteria

  • pip check reports no broken requirements and pytest passes on the target version.
  • No imports of distutils, imp, or deprecated collections ABC aliases remain.
  • All dependencies resolve to versions supporting the target Python.

Frequently asked questions

Is the free-threaded (no-GIL) build production-ready in 3.14?

Free threading is officially supported as of Python 3.14 (PEP 779), with single-threaded overhead down to roughly 5–10%. It is still a separate build (python3.14t) you opt into, and many C extensions need rebuilding or fixes for thread safety — so adopt it deliberately, not as a side effect of upgrading.

Will lazy annotations break my code?

Most code is unaffected, but anything that reads annotations directly or depends on annotations being evaluated at definition time can change behavior under PEP 649/749. Use annotationlib.get_annotations() and test type-driven libraries (pydantic, dataclasses, attrs) on 3.14.

Should I jump to 3.14 or stop at 3.13?

Target 3.14 for the longest support window (security through 2030-10) and the newest features. Choose 3.13 only if a critical dependency does not yet ship 3.14 wheels; 3.13 is fully supported with bugfixes until 2026-10.