What Is New in Python 3.13
Python 3.13 is a landmark release on two fronts: it ships the first official experimental free-threaded build (no GIL), and an experimental JIT compiler -- both opt-in. For everyday users, the REPL gets a complete rewrite with multiline editing and color, the PEP 594 "dead batteries" are removed en masse, and import startup times improve across many stdlib modules.
| Category | Change | PEP / Reference |
|---|---|---|
| Concurrency | Experimental free-threaded build (no GIL) via python3.13t |
PEP 703 |
| Performance | Experimental JIT compiler (copy-and-patch) -- --enable-experimental-jit |
PEP 744 |
| REPL | Rewritten interactive interpreter: multiline editing, color, history, F1/F2 shortcuts | -- |
| Removals | PEP 594 "dead batteries": aifc, cgi, crypt, imghdr, telnetlib, uu, and 14 more |
PEP 594 |
| Platform | Official Tier 3 support for iOS and Android | PEP 730, 738 |
| Language | Type parameter defaults: [T = int] in generic definitions |
PEP 696 |
| Language | locals() semantics defined precisely -- snapshot, no live mutation |
PEP 667 |
| Standard Library | itertools.batched(strict=True); dbm defaults to SQLite backend |
-- |
| Performance | Faster import startup: typing, enum, functools, threading, email.utils |
-- |
What Is the Free-Threaded Build and Should You Use It?
The free-threaded build (python3.13t or python3.13 --disable-gil) removes the Global Interpreter Lock, allowing Python threads to run truly in parallel on multiple cores. For CPU-bound code using threading, this can deliver genuine multi-core speedups without spawning multiple processes.
# Check if running in free-threaded mode
import sys
print(sys._is_gil_enabled()) # False in free-threaded build
The catch: C extensions must explicitly declare themselves thread-safe with Py_mod_gil = Py_MOD_GIL_NOT_USED or they run with a per-module lock. Many popular extensions (NumPy, cryptography) added support quickly, but the ecosystem is still stabilizing. For production CPU-bound workloads, multiprocessing remains the safe choice until the ecosystem catches up.
How Does the Experimental JIT Work in Python 3.13?
The JIT uses a "copy-and-patch" technique: pre-compiled code templates are copied and patched with runtime values rather than running a full code generation pipeline. This keeps compile latency low while still generating native machine code for hot micro-operations ("uops").
Enable at compile time with --enable-experimental-jit, then at runtime with python -X jit. Early benchmarks show modest 2-9% speedups on the pyperformance suite -- the JIT is still in early stages and targets specific opcode patterns. It is not yet competitive with PyPy's JIT but represents CPython's first foray into native code generation.
What Improved in the Interactive Interpreter (REPL)?
The REPL was rewritten to use a PyPy-inspired implementation with genuine multiline editing -- you can navigate and edit across multiple input lines before executing, just like a text editor. Color highlights keywords, strings, numbers, and tracebacks. Keyboard shortcuts include F1 for help, F2 for paste mode (strips prompts), and F3 to toggle multiline mode.
History is preserved across sessions. Turn off all color with PYTHON_COLORS=0 or NO_COLOR=1. The new REPL requires no changes to existing code and handles all existing input formats correctly.
Which Modules Were Removed by PEP 594 in Python 3.13?
PEP 594 ("Remove dead batteries") removed 19 stdlib modules that had been deprecated since Python 3.11:
aifc,audioop,chunk,cgi,cgitb-- old audio/CGI handlingcrypt-- usehashlibor thecryptographypackage (PyPI)imghdr,sndhdr-- format detection; usefiletype(PyPI)mailcap,msilib,nis,nntplib-- obsolete protocolsossaudiodev,pipes,spwd,sunau-- OS-specific audio/Unixtelnetlib-- useasyncioorTelnetfrom PyPIuu,xdrlib-- encoding/data formats with no modern use
What Language and Typing Changes Landed in 3.13?
- Type parameter defaults (PEP 696):
class Container[T = int]:-- type checkers useintwhen T is not specified, enabling Optional-like behavior withoutUnion. - locals() semantics (PEP 667):
locals()in optimized scopes (functions) now consistently returns a snapshot. Mutations to the returned dict do not affect actual local variables. This was previously implementation-defined. - typing.deprecated(): Decorator to mark functions/classes as deprecated; type checkers and runtime tools emit warnings when deprecated items are used.
- typing.ReadOnly: Marks
TypedDictfields as read-only for type checkers without affecting runtime behavior.
FAQ
Is the free-threaded build production-ready in Python 3.13?
Not generally. It is labeled experimental -- the CPython team explicitly recommends testing and feedback, not production deployment. The GIL removal changes the thread safety assumptions of many C extensions that were tolerant of the GIL's protection. Until major extensions formally declare GIL-safety and the toolchain stabilizes, use multiprocessing for CPU parallelism in production.
Will the JIT eventually replace the adaptive interpreter?
No -- they complement each other. The adaptive interpreter does profiling and specialization at the opcode level. The JIT compiles hot sequences of specialized opcodes ("uop traces") to native machine code. The JIT sits on top of the specialization layer, not alongside it.
Can I use crypt-equivalent functionality after Python 3.13 removes the crypt module?
Yes. The hashlib module handles password hashing via hashlib.scrypt() and hashlib.pbkdf2_hmac(). For bcrypt and Argon2, use the bcrypt and argon2-cffi packages from PyPI. These are more secure choices than the legacy crypt module anyway.
Does the locals() change in 3.13 break any real code?
It can. Code that relied on modifying locals() to affect local variable values -- a pattern sometimes used in debugging or code generation -- will silently stop working. The fix is to use an explicit dict namespace with exec(code, globals_dict, local_dict) instead of relying on locals() mutations.
What is the difference between the iOS/Android Tier 3 support added in 3.13 and a production mobile deployment?
Tier 3 means the platform is tested in CI and CPython compiles and runs basic tests there. It does not mean the stdlib works completely -- modules with platform-specific dependencies (audio, GUI, some networking) may not function on mobile. Projects like BeeWare and Kivy handle the additional platform integration work needed for real mobile app deployment.