Mes collègues Python vont bientôt recevoir un truc qu'on ne remarque même plus depuis PHP 5.3 : du code qui ne se charge que quand on y touche. Python 3.15 débarque le 1er octobre avec la PEP 810, les imports paresseux explicites, et en lisant la spec j'ai eu l'impression de feuilleter les photos de bébé de Composer. Alors je pose ma thèse tout de suite : le nouveau mot-clé sera très bien, l'interrupteur global fera mal à quelqu'un, et la différence entre les deux tient à une règle que notre écosystème a intégrée il y a si longtemps qu'on a oublié que c'en était une.
python -X importtime -c "import pandas"La mécanique d'abord. Le steering council a accepté la PEP 810 à l'unanimité le 3 novembre 2025, quatre voix avec le co-auteur Pablo Galindo Salgado qui s'est abstenu, et la release candidate 2 est sortie le 1er septembre. Tu écris lazy import pandas ou lazy from json import dumps, le nom reçoit un placeholder, et Python n'effectue le vrai import qu'à la première utilisation de ce placeholder. N'importe quel développeur PHP reconnaît la silhouette au premier coup d'œil. C'est spl_autoload_register déguisé en soft keyword.
Voici pourquoi l'autoloading ne nous a jamais mordus comme il aurait théoriquement pu le faire. PSR-4 est arrivé avec une règle compagne non écrite : un fichier qui définit une classe ne fait rien d'autre. Aucun effet de bord, juste une déclaration. Un tel fichier peut être chargé maintenant ou dans dix minutes, le programme ne verra pas la différence. Les modules Python, c'est l'inverse par conception. En importer un l'exécute de haut en bas, et les bibliothèques matures s'appuient sur ce moment pour enregistrer des plugins ou faire du monkey-patching. Diffère ces chargements et tu viens de réordonner des effets de bord dans tout le processus.
Les auteurs de la PEP 810 comprennent clairement le problème, d'où un mot-clé sévèrement clôturé : niveau module uniquement, interdit dans les fonctions, les corps de classe, les blocs try et import *. L'interdiction du bloc try est la plus douloureuse, parce qu'elle exclut la danse classique de la dépendance optionnelle où tu tentes d'importer pyarrow, tu attrapes l'ImportError et tu retombes sur une sentinelle None. Avec le différé, l'échec surgirait à la première utilisation, bien après que la clause except environnante a fini de ne rien faire, donc cette interdiction est de l'ingénierie honnête. Les lots de consolation sont corrects aussi : quand un import différé explose, la chaîne d'exceptions pointe à la fois vers le site de déclaration et vers l'accès qui l'a déclenché, et un chargement raté est retenté au contact suivant.
Sur les gains promis, garde ton scepticisme au chaud. La PEP cite des réductions de démarrage de 50 à 70 pour cent et des économies mémoire de 30 à 40 pour cent sans rattacher aucun de ces chiffres à un codebase nommé ; le seul cas attribué, le travail de Christian Tismer sur PySide, atterrit entre 10 et 20 pour cent. Instagram chez Meta et Hudson River Trading sont cités comme utilisateurs en production, sans le moindre chiffre. La matière première est bien réelle, cela dit. Sur CPython 3.11, un import pandas à chaud coûte environ 250 millisecondes, NumPy seul à peu près 64, et un interpréteur vide démarre en moins de 3. Qu'un quart de seconde compte ou non dépend entièrement de la durée de vie du processus. Dans un CLI que quelqu'un lance toute la journée, ça compte énormément. Dans un worker qui boote une fois et mâche une queue pendant une semaine, ça s'évapore, pour la même raison que Laravel Octane rend le coût de boot du framework négligeable en le payant exactement une fois.
Maintenant la partie qui mérite un ticket de revue de changement. La PEP 810 livre trois modes, normal, all et none, réglables via sys.set_lazy_imports(), le drapeau -X lazy_imports ou la variable d'environnement PYTHON_LAZY_IMPORTS, plus un hook de filtrage dans sys.set_lazy_imports_filter() et un ensemble sys.lazy_modules qui suit les noms pas encore matérialisés. Le mode all diffère chaque import du processus, y compris ceux à l'intérieur de dépendances dont les mainteneurs n'ont jamais testé le différé et qui, dans certains cas, dépendent carrément de l'exécution au moment de l'import. La PEP explique à ces mainteneurs comment corriger : arrêter le travail d'enregistrement à l'import, exposer une fonction d'init explicite à la place. C'est précisément la discipline que PHP a mis des années et un gestionnaire de paquets à rendre universelle, et Python la réclame rétroactivement tout en tendant à chaque équipe ops une seule variable qui suppose le travail déjà fait.
Voilà donc où j'atterris, après avoir concédé les parties vraiment bonnes. Le mot-clé opt-in est bien conçu, et marquer les imports lourds en tête d'un point d'entrée CLI, puis vérifier le delta avec -X importtime, c'est de l'argent gratuit que tu devrais ramasser. Mais traite le mode all comme tu traiterais le remplacement de l'autoloader dans une boutique en production, et garde-le loin de tout job qui écrit des données. Un import eager qui échoue tue le processus avant que le moindre travail commence, un redémarrage propre. Un import différé peut échouer après que des lignes sont déjà parties, et aucun graphe de cold start ne justifie d'hériter de ce ménage.
Ce qui m'amène à toi. Imagine qu'on reçoive l'image miroir demain : une seule variable d'env qui rend paresseux chaque require dans vendor/, effets de bord ou pas. Tu l'activerais sur une machine de prod pour un boot plus rapide ? Si ta réponse est non, je veux savoir quelle preuve te ferait changer d'avis, parce que quelque part dans ta boîte, une équipe Python s'apprête à faire exactement ce pari.




Commentaires
Pas encore de commentaire — écris le premier.
Lance la discussion
Pas de compte ni de mot de passe — saisis simplement ton adresse e-mail et nous t’envoyons un lien de connexion à usage unique. Première visite ? Tout se met en place automatiquement.
Ton évaluation sera appliquée automatiquement après ta connexion.
Vérifie ta boîte mail
Nous avons envoyé un lien de connexion à …. Ouvre-le sur cet appareil — cet onglet te connectera automatiquement.
Rien reçu ? Vérifiez le dossier spam — et marquez le message « Non spam » pour qu'il arrive directement la prochaine fois.