Retour au blog
  • 4 min de lecture

Les nouveautés de Python 3.15

Python 3.15 est sorti : UTF-8 par défaut, "lazy imports", profileur Tachyon, JIT plus rapide, frozendict et sentinel. Tour des nouveautés marquantes.

Python 3.15 est sorti le 9 octobre 2026. Selon l'annonce officielle, cette version rassemble 5 643 commits de 1 012 contributeurs. Elle apporte de nouvelles constructions du langage, un démarrage plus rapide grâce aux "lazy imports", de meilleurs outils d'observation et un changement de comportement par défaut sur l'encodage des fichiers.

Voici les nouveautés de Python 3.15 les plus marquantes, classées par thème. La liste complète est dans le What's New officiel.

Les nouveautés du langage

frozendict intégré

La PEP 814 ajoute un dictionnaire immuable et hachable aux types natifs. Il convient bien à la configuration, aux valeurs par défaut partagées ou aux clés de cache. Ce n'est pas une sous-classe de dict : un test isinstance(x, dict) le rejette. La documentation recommande isinstance(x, (dict, frozendict)) ou collections.abc.Mapping.

sentinel intégré

La PEP 661 ajoute un type sentinel pour créer des valeurs uniques qui signifient « argument absent » quand None est une valeur légitime. Ces valeurs sentinel s'affichent lisiblement, conservent leur identité à la copie, se combinent avec | dans les annotations de type et se sérialisent avec pickle.

"Unpacking" dans les compréhensions

Avec la PEP 798, les compréhensions de listes, d'ensembles et de dictionnaires acceptent * et **, tout comme les expressions génératrices :

python
lists = [[1, 2], [3, 4], [5]]
flat = [*L for L in lists]  # [1, 2, 3, 4, 5]
 
dicts = [{"a": 1}, {"b": 2}, {"a": 3}]
merged = {**d for d in dicts}  # {'a': 3, 'b': 2}

Cette syntaxe remplace la double boucle [x for L in lists for x in L], souvent mal lue.

Typage

Trois ajouts concernent surtout les auteurs de bibliothèques et d'outils : les éléments supplémentaires typés dans TypedDict (PEP 728), l'annotation des formes de type avec TypeForm (PEP 747) et les bases disjointes dans le système de types (PEP 800).

Le démarrage : "lazy imports"

Les "lazy imports" explicites (PEP 810) chargent un module à sa première utilisation, pas au démarrage du programme :

python
lazy import json
lazy from pathlib import Path

Le mot-clé lazy n'est autorisé qu'au niveau du module : dans une fonction, une classe ou un bloc try, il lève une SyntaxError. Le gain porte sur le temps de démarrage des outils en ligne de commande, des workers relancés souvent et des fonctions serverless, qui importent beaucoup de modules sans tous les utiliser.

L'observabilité : Tachyon et "frame pointers"

Le nouveau paquet profiling regroupe les profileurs de la bibliothèque standard. Il intègre Tachyon (PEP 799), un "sampling profiler" qui monte jusqu'à 1 MHz : il observe un programme sans l'instrumenter, ce qui le rend utilisable sur un service en production. L'ancien module profile devient profiling.tracing ; profile est déprécié et sera retiré en 3.17.

Les "frame pointers" sont désormais activés par défaut à la compilation de CPython (PEP 831). Les outils système comme perf reconstruisent ainsi les piles d'appels de façon plus fiable.

La performance : un JIT qui progresse

Le compilateur JIT reste expérimental, mais il progresse nettement. D'après la documentation, la suite pyperformance mesure en moyenne géométrique 7 à 8 % de gain sur Linux x86-64 par rapport à l'interpréteur standard, et 11 à 12 % sur macOS AArch64. L'écart varie beaucoup d'un benchmark à l'autre, d'environ 15 % de ralentissement à plus de 100 % d'accélération : seule une mesure sur sa propre charge dit ce qu'il apporte. Quand un besoin de performance tient à l'architecture plutôt qu'à l'interpréteur, d'autres options existent, comme Rust pour une application critique.

Parmi les optimisations ciblées, base64 encode deux fois plus vite et décode trois fois plus vite.

Le "free-threading"

Les builds sans GIL disposent désormais d'une ABI stable dédiée, abi3t (PEP 803, avec les PEP 793 et 820). Une extension C qui cible cette ABI stable devient compatible avec les builds "free-threaded", sans recompilation propre à chaque version. Les installateurs officiels pour macOS installent aussi le support "free-threading" par défaut.

Compatibilité : UTF-8 par défaut et autres changements

Le changement le plus large touche l'encodage. Avec la PEP 686, Python utilise UTF-8 par défaut, quel que soit l'environnement : un open() sans paramètre encoding lit et écrit en UTF-8 même si la locale du système est différente. Sous Linux, cela ne change généralement rien ; sous Windows ou avec une locale non UTF-8, l'ancien mode se rétablit avec PYTHONUTF8=0 ou -X utf8=0. La documentation recommande de toujours passer encoding explicitement.

Autres points à connaître avant de mettre à jour :

  • le "garbage collector" incrémental livré de 3.14.0 à 3.14.4 est retiré au profit du GC générationnel de 3.13 ;
  • tous les paramètres de sqlite3.connect(), sauf database, deviennent nommés uniquement ;
  • les modules sre_compile, sre_constants et sre_parse, les méthodes load_module() d'importlib et CGIHTTPRequestHandler sont supprimés.

Durée de support de Python 3.15

Selon la PEP 790, Python 3.15 recevra des versions correctives environ tous les deux mois pendant deux ans, puis des correctifs de sécurité, publiés sous forme de sources uniquement, jusqu'à environ octobre 2031.


Python 3.15 combine des ajouts visibles au quotidien (frozendict, sentinel, "unpacking" dans les compréhensions), des outils de production ("lazy imports", Tachyon) et un JIT encore expérimental. Pour concevoir ou faire évoluer une application sur cette base, voir l'offre de développement Python et Rust.

Un sujet à creuser pour votre projet ?

Discutons de votre contexte technique et de vos enjeux.

Parlons de votre projet