Python 3.15 : ce qui change vraiment pour un service backend
Python 3.15 est sorti le 9 octobre 2026. Le What’s New officiel est long, et la majorité des entrées ne concernent pas un service qui tourne derrière un reverse proxy. Quatre changements méritent une heure de votre temps : l’encodage par défaut, les imports paresseux, frozendict et le nouveau profileur. Le reste peut attendre la 3.16.
L’encodage par défaut devient UTF-8 (PEP 686)
open("facture.csv") sans argument encoding lisait jusqu’ici l’encodage de la locale. En 3.15, c’est UTF-8, sans condition. Sur un conteneur en LANG=C, Python lisait en ASCII et refusait les accents ; il les accepte désormais. Sur une machine en fr_FR.ISO-8859-1, c’est l’inverse : les fichiers produits par un vieux script interne ne se relisent plus de la même façon.
La migration est mécanique. Passez -X warn_default_encoding (ou PYTHONWARNDEFAULTENCODING=1) sur la CI, puis corrigez chaque EncodingWarning. Le garde-fou -X utf8=0 existe encore, à traiter comme un pansement et non comme une solution. Un open() sans encoding explicite reste une dette, même quand la valeur par défaut vous convient.
Les imports paresseux (PEP 810)
lazy import et lazy from ... import ... déplacent l’exécution du module au premier accès à un nom qu’il fournit. Sur une fonction Lambda ou un python -m qui démarre en 400 ms, la différence se mesure. Sur un worker gunicorn qui tourne trois jours, elle ne se voit pas du tout.
Deux pièges. Un import paresseux placé dans un try/except ImportError ne lève rien au démarrage : la détection d’une dépendance optionnelle arrive plus tard, parfois en pleine requête. Et l’ordre des effets de bord (enregistrement de plugins, par exemple) n’est plus celui du fichier. Si votre application compte dessus, gardez un import classique.
frozendict pour la configuration (PEP 814)
frozendict est un type natif immuable, et hachable dès que ses valeurs le sont. Concrètement, la configuration chargée au démarrage peut devenir argument de functools.lru_cache, ce qu’un dict interdisait. Elle peut aussi vivre dans un attribut de classe sans qu’un module voisin la modifie par accident.
Ce n’est pas MappingProxyType. Le proxy reste une vue sur un dictionnaire mutable, alors que frozendict est une copie figée. Si votre configuration est rechargée à chaud, il faut remplacer l’objet, pas le muter. C’est d’ailleurs le comportement souhaitable : un rechargement qui échoue à mi-parcours laisse l’ancienne config intacte.
Le profilage par échantillonnage (PEP 799)
Le module profiling entre dans la bibliothèque standard avec Tachyon, un profileur statistique. Il échantillonne la pile à intervalle régulier au lieu d’instrumenter chaque appel. Le coût sur un service en charge reste faible, là où cProfile ralentit souvent d’un facteur 2 à 5 sur du code qui appelle beaucoup de petites fonctions.
Un profileur statistique ne compte pas les appels. Il montre où le temps passe, pas combien de fois une fonction est invoquée. Pour une fuite mémoire ou un nombre d’appels anormal, il faut autre chose. Et la fréquence d’échantillonnage se règle : trop basse, elle rate les pics ; trop haute, elle coûte.
Quand ne pas migrer
Si votre service tourne sur une image python:3.12-slim épinglée et que rien ne vous presse, la 3.15 n’apporte pas d’argument décisif. L’encodage UTF-8 corrige un comportement, il n’accélère rien. Les imports paresseux ne servent à rien sur un process qui démarre une fois par déploiement. frozendict se remplace par une convention d’équipe et une revue de code attentive.
Le vrai coût d’une migration reste ailleurs : les roues binaires. Vérifiez que numpy, psycopg et cryptography publient des wheels cp315 avant de toucher au Dockerfile. Compiler ces trois-là depuis les sources sur une image -slim vous prendra une après-midi, et vous la passerez à installer gcc plutôt qu’à profiter des nouveautés.
Dernière limite, plus générale : Tachyon ne remplace pas les métriques. Un profileur dit où le CPU part, pas ce que le client voit en p99. Les deux outils répondent à des questions différentes, et la 3.15 ne change rien à ça.