Overview
Python 3.13, released on October 7, 2024, is a historic release that introduces two major experimental features: the free-threaded mode (no GIL) and a JIT compiler. The free-threaded mode allows, for the first time, Python threads to run in true parallelism on multiple cores, while the JIT compiler lays the groundwork for future performance optimizations. This release also brings a significantly improved interactive REPL and removes many obsolete modules.
Major Features
Free-threaded mode (PEP 703)
The free-threaded mode completely disables the GIL, allowing Python threads to run in true parallelism. It is a separate CPython build, installed via python3.13t (the t suffix stands for threaded). This feature is marked as experimental: some C extensions are not yet compatible, and single-threaded performance may be slightly lower.
# Installing the free-threaded build
# On Linux/macOS: compile with --disable-gil
# ./configure --disable-gil && make && make install
#
# Or use python3.13t if available
# python3.13t my_script.py
import threading
import time
global_counter = 0
lock = threading.Lock()
def cpu_bound_work(worker_id, iterations):
"""CPU-bound computation that benefits from free-threading."""
total = 0
for i in range(iterations):
total += (i * i) % 997
with lock:
global global_counter
global_counter += 1
return total
start = time.perf_counter()
threads = []
for t_id in range(4):
t = threading.Thread(
target=cpu_bound_work,
args=(t_id, 5_000_000)
)
threads.append(t)
t.start()
for t in threads:
t.join()
duration = time.perf_counter() - start
print(f"Done in {duration:.2f}s with {global_counter} threads")
# With GIL : ~4.0s (sequential)
# Without GIL (t): ~1.2s (true parallelism on 4 cores)
JIT compiler (PEP 744)
Python 3.13 integrates an experimental JIT compiler based on the copy-and-patch technique. Rather than generating machine code from scratch, this approach copies precompiled machine code blocks and adapts them to the execution context. The JIT is disabled by default and must be enabled at build time. Performance gains are modest for now, but this mechanism will serve as the foundation for more aggressive future optimizations.
# Enable the JIT when building CPython
# ./configure --enable-experimental-jit && make
# The JIT optimizes hot loops and frequently called
# functions. Example of code that benefits:
import time
def iterative_fibonacci(n):
"""Compute the first n Fibonacci numbers."""
result = []
a, b = 0, 1
for _ in range(n):
result.append(a)
a, b = b, a + b
return result
def count_primes(limit):
"""Count prime numbers up to the limit."""
count = 0
for n in range(2, limit):
is_prime = True
for d in range(2, int(n ** 0.5) + 1):
if n % d == 0:
is_prime = False
break
if is_prime:
count += 1
return count
start = time.perf_counter()
nb = count_primes(200_000)
duration = time.perf_counter() - start
print(f"{nb} primes found in {duration:.2f}s")
# The JIT accelerates this kind of numeric loop
Improved interactive REPL
The Python 3.13 REPL (Read-Eval-Print Loop) has been completely redesigned. It supports multi-line editing, syntax highlighting, a paste mode for copied code blocks, and improved history. The new REPL uses the _pyrepl library instead of readline.
# New features in the Python 3.13 REPL:
# 1. Multi-line editing: arrow up to go back into
# a block and modify it entirely
# 2. Real-time syntax highlighting
# >>> def factorial(n):
# ... if n <= 1:
# ... return 1
# ... return n * factorial(n - 1)
# (keywords appear in color)
# 3. Paste mode: paste a complete code block
# from an editor without indentation issues
# 4. Special commands
# >>> exit # works directly (no more exit() needed)
# >>> help # direct access to help
# 5. Persistent history across sessions
# Stored in ~/.python_history
# Search with Ctrl+R
Removal of obsolete modules
Python 3.13 removes many modules deprecated since Python 3.11. This cleanup wave mainly affects rarely used modules or those replaced by modern alternatives.
# Modules removed in Python 3.13 and their replacements
# aifc -> use the 'soundfile' package (pip install soundfile)
# audioop -> use 'miniaudio' or 'pydub'
# cgi -> use 'urllib.parse' for parsing
# and a web framework for request handling
# cgitb -> use the 'traceback' or 'logging' module
# chunk -> use 'struct' for binary parsing
# imghdr -> use 'filetype' (pip install filetype)
# mailcap -> use 'mimetypes'
# msilib -> use 'WiX Toolset' for installers
# nis -> no replacement (obsolete protocol)
# nntplib -> use a third-party library
# ossaudiodev -> use 'sounddevice'
# pipes -> use 'subprocess'
# sndhdr -> use 'filetype'
# spwd -> use 'pwd' or direct file access
# sunau -> use 'soundfile'
# telnetlib -> use 'telnetlib3' (pip)
# uu -> use 'base64'
# xdrlib -> use 'struct' or 'msgpack'
Minor Improvements
- The
dbmmodule usesdbm.sqlite3as the default backend. - The
argparsemodule deprecates abbreviated option prefixes by default. - Performance of
copy.deepcopy()is improved for common types. - The
randommodule adds aCommandLinemethod for command-line usage. - The garbage collector is faster thanks to an incremental algorithm.
Deprecations and Removals
Notable changes in this category:
- Twenty obsolete modules are removed (
aifc,cgi,cgitb,imghdr, etc.). - The
tkinter.tixmodule is removed. locale.resetlocale()and other deprecated functions are removed.- The
typing.ByteStringtype is removed.
