Vue d'ensemble

Python 3.13, publié le 7 octobre 2024, est une version historique qui introduit deux fonctionnalités expérimentales majeures : le mode free-threaded (sans GIL) et un compilateur JIT. Le mode free-threaded permet pour la première fois d'exécuter des threads Python en vrai parallèle sur plusieurs cœurs, tandis que le compilateur JIT pose les bases de futures optimisations de performance. Cette version apporte également un REPL interactif considérablement amélioré et supprime de nombreux modules obsolètes.

Nouveautés majeures

Mode free-threaded (PEP 703)

Le mode free-threaded désactive complètement le GIL, permettant aux threads Python de s'exécuter en vrai parallèle. C'est un build séparé de CPython, installé via python3.13t (le suffixe t indique threaded). Cette fonctionnalité est marquée comme expérimentale : certaines extensions C ne sont pas encore compatibles, et les performances mono-thread peuvent être légèrement inférieures.

python
# Installation du build free-threaded
# Sur Linux/macOS : compiler avec --disable-gil
# ./configure --disable-gil && make && make install
#
# Ou utiliser python3.13t si disponible
# python3.13t mon_script.py

import threading
import time

compteur_global = 0
verrou = threading.Lock()

def calcul_intensif(identifiant, iterations):
    """Calcul CPU-bound qui bénéficie du free-threading."""
    total = 0
    for i in range(iterations):
        total += (i * i) % 997
    with verrou:
        global compteur_global
        compteur_global += 1
    return total

debut = time.perf_counter()

threads = []
for t_id in range(4):
    t = threading.Thread(
        target=calcul_intensif,
        args=(t_id, 5_000_000)
    )
    threads.append(t)
    t.start()

for t in threads:
    t.join()

duree = time.perf_counter() - debut
print(f"Terminé en {duree:.2f}s avec {compteur_global} threads")
# Avec GIL    : ~4.0s (séquentiel)
# Sans GIL (t): ~1.2s (vrai parallélisme sur 4 cœurs)

Compilateur JIT (PEP 744)

Python 3.13 intègre un compilateur JIT expérimental basé sur la technique copy-and-patch. Plutôt que de générer du code machine depuis zéro, cette approche copie des blocs de code machine précompilés et les adapte au contexte d'exécution. Le JIT est désactivé par défaut et doit être activé à la compilation. Les gains de performance sont modestes pour l'instant, mais ce mécanisme servira de fondation pour des optimisations futures plus agressives.

python
# Activer le JIT à la compilation de CPython
# ./configure --enable-experimental-jit && make

# Le JIT optimise les boucles chaudes et les fonctions
# fréquemment appelées. Exemple de code en bénéficiant :

import time

def suite_fibonacci_iterative(n):
    """Calcule les n premiers termes de Fibonacci."""
    resultat = []
    a, b = 0, 1
    for _ in range(n):
        resultat.append(a)
        a, b = b, a + b
    return resultat

def compter_premiers(limite):
    """Compte les nombres premiers jusqu'à la limite."""
    compteur = 0
    for n in range(2, limite):
        est_premier = True
        for d in range(2, int(n ** 0.5) + 1):
            if n % d == 0:
                est_premier = False
                break
        if est_premier:
            compteur += 1
    return compteur

debut = time.perf_counter()
nb = compter_premiers(200_000)
duree = time.perf_counter() - debut
print(f"{nb} nombres premiers trouvés en {duree:.2f}s")
# Le JIT accélère ce type de boucle numérique

REPL interactif amélioré

Le REPL (Read-Eval-Print Loop) de Python 3.13 est entièrement repensé. Il supporte l'édition multi-lignes, la coloration syntaxique, le mode collage pour les blocs de code copiés, et un historique amélioré. Le nouveau REPL utilise la bibliothèque _pyrepl au lieu de readline.

python
# Nouvelles fonctionnalités du REPL Python 3.13 :

# 1. Édition multi-lignes : flèche haut pour remonter
#    dans un bloc et le modifier en entier

# 2. Coloration syntaxique en temps réel
#    >>> def factorielle(n):
#    ...     if n <= 1:
#    ...         return 1
#    ...     return n * factorielle(n - 1)
#    (les mots-clés apparaissent en couleur)

# 3. Mode collage : coller un bloc de code
#    complet depuis un éditeur sans problèmes
#    d'indentation

# 4. Commandes spéciales
#    >>> exit    # fonctionne directement (plus besoin de exit())
#    >>> help    # accès direct à l'aide

# 5. Historique persistant entre les sessions
#    Stockage dans ~/.python_history
#    Recherche avec Ctrl+R

Suppression de modules obsolètes

Python 3.13 supprime de nombreux modules dépréciés depuis Python 3.11. Cette vague de nettoyage concerne principalement des modules peu utilisés ou remplacés par des alternatives modernes.

python
# Modules supprimés dans Python 3.13 et leurs remplacements

# aifc -> utiliser le paquet 'soundfile' (pip install soundfile)
# audioop -> utiliser 'miniaudio' ou 'pydub'
# cgi -> utiliser 'urllib.parse' pour le parsing
#         et un framework web pour les requêtes
# cgitb -> utiliser le module 'traceback' ou 'logging'
# chunk -> utiliser 'struct' pour le parsing binaire
# imghdr -> utiliser 'filetype' (pip install filetype)
# mailcap -> utiliser 'mimetypes'
# msilib -> utiliser 'WiX Toolset' pour les installeurs
# nis -> aucun remplacement (protocole obsolète)
# nntplib -> utiliser une bibliothèque tierce
# ossaudiodev -> utiliser 'sounddevice'
# pipes -> utiliser 'subprocess'
# sndhdr -> utiliser 'filetype'
# spwd -> utiliser 'pwd' ou accès fichier direct
# sunau -> utiliser 'soundfile'
# telnetlib -> utiliser 'telnetlib3' (pip)
# uu -> utiliser 'base64'
# xdrlib -> utiliser 'struct' ou 'msgpack'

Améliorations mineures

  • Le module dbm utilise dbm.sqlite3 comme backend par défaut.
  • Le module argparse déprécie les préfixes d'option abrégés par défaut.
  • Les performances de copy.deepcopy() sont améliorées pour les types courants.
  • Le module random ajoute la méthode CommandLine pour l'utilisation en ligne de commande.
  • Le ramasse-miettes est plus performant grâce à un algorithme incrémental.

Dépréciations et suppressions

Les changements notables dans cette catégorie :

  • Vingt modules obsolètes sont supprimés (aifc, cgi, cgitb, imghdr, etc.).
  • Le module tkinter.tix est supprimé.
  • Les classes locale.resetlocale() et d'autres fonctions dépréciées sont retirées.
  • Le type typing.ByteString est supprimé.

Sources