Retour à la leçon·Leçon 3 sur 8·La même réponse deux fois
Ça marche sur ma machine, et c'est le rapport de bogue
Le même diaporama que les téléchargements, rendu sous forme de page. Lancez le diaporama pour le présenter en plein écran — les flèches ou un clic avancent d'une diapositive, Échap quitte.
Ce que couvre cette leçon
- Ce que l'ordinateur d'un collègue fait différemment
- Python :
uv - R :
renv - Pourquoi un fichier de verrouillage et non
requirements.txt - Ce que cette plateforme fige, et pourquoi un verrou est inhabituel
- Les conteneurs, et quand ils en valent la peine
- Le test qui le prouve
- Rapportez-le en entier
- La suite
Notes du présentateur
Le même script, les mêmes données et une autre version de pandas produisent d'autres nombres. Un fichier de verrouillage est ce qui transforme « ça marche sur ma machine » d'une défense en une affirmation vérifiable, et cela coûte une commande.Ce que l'ordinateur d'un collègue fait différemment
Ce qui diffère Ce que cela change Version de paquet Un argument par défaut, une règle d'arrondi, un ordre de tri Version du langage Ordre des dictionnaires, division entière, traitement des chaînes Système d'exploitation Fins de ligne, ordre des fichiers, séparateurs de chemin, locale Locale 1,234interprété comme 1234 ou comme 1,234Ce qui est déjà installé Une bibliothèque que votre script importe sans jamais la déclarer Notes du présentateur
Vous envoyez un script et un CSV. Il l'exécute. Le nombre diffère.Ce que l'ordinateur d'un collègue fait différemment
- Rien de tout cela n'est dans votre dépôt — raison pour laquelle un code identique ne suffit pas
Notes du présentateur
Rien de tout cela n'est dans votre dépôt, raison pour laquelle un code identique ne suffit pas. Un fichier de verrouillage est la moitié manquante de l'analyse.Python :
uv— Shelluv init # creates pyproject.toml uv add pandas matplotlib # records the dependency and resolves it uv run python run.py # runs inside the pinned environmentPython :
uv- Deux fichiers, et les deux sont commités —
pyproject.tomldit ce que vous avez demandé —pandas>=2.0— etuv.lock… - Un collègue lance
uv syncet dispose de votre environnement — sur son système, sans que vous sachiez ce qu'il avait… - Figez aussi la version du langage
Notes du présentateur
Deux fichiers, et les deux sont commités.pyproject.tomldit ce que vous avez demandé —pandas>=2.0— etuv.lockdit exactement ce que vous avez obtenu, jusqu'à l'empreinte de chaque paquet de l'arbre. Un collègue lanceuv syncet dispose de votre environnement, sur son système, sans que vous sachiez ce qu'il avait installé auparavant. Figez aussi la version du langage.- Deux fichiers, et les deux sont commités —
Python :
uv- Une plage de versions, non une version unique — Figer à
3.12.4exactement signifie qu'un collègue en3.12.7ne peut…
Notes du présentateur
Une plage de versions, non une version unique. Figer à3.12.4exactement signifie qu'un collègue en3.12.7ne peut pas l'exécuter du tout, ce qui est un échec pire que celui qu'on prévenait.- Une plage de versions, non une version unique — Figer à
R :
renv— En Rrenv::init() # snapshots the project library renv::snapshot() # after adding a package renv::restore() # on the colleague's machineR :
renvrenv.lockest l'artefact équivalent et il est commité — Il enregistre chaque paquet, sa version et le dépôt d'où il…- Enregistrez la version de R, ce que
renvfait automatiquement — et vérifiez-la dans le script là où une différence…
Notes du présentateur
renv.lockest l'artefact équivalent et il est commité. Il enregistre chaque paquet, sa version et le dépôt d'où il vient, etrenv::restore()le reconstruit. Enregistrez la version de R, ce querenvfait automatiquement, et vérifiez-la dans le script là où une différence compterait.R :
renv— En Rif (getRversion() < "4.3.0") stop("This analysis requires R >= 4.3.0")R :
renv— En Python# The Python equivalent, at the top of the entry point. import sys assert sys.version_info >= (3, 12), "This analysis requires Python 3.12+"Pourquoi un fichier de verrouillage et non
requirements.txt— Exemplepandas>=2.0 matplotlibPourquoi un fichier de verrouillage et non
requirements.txt- Ce fichier ne dit presque rien — Il se résout en versions différentes selon les jours et ne mentionne pas les cinquante…
Notes du présentateur
Ce fichier ne dit presque rien. Il se résout en versions différentes selon les jours et ne mentionne pas les cinquante paquets que ces deux-là entraînent. Une installation en mars et une en juillet depuis le mêmerequirements.txtsont deux environnements différents.Pourquoi un fichier de verrouillage et non
requirements.txtDéclare Reproduit requirements.txtL'intention Non requirements.txtavec des==Une couche En partie — les dépendances transitives flottent uv.lock/renv.lockL'arbre entier Oui Pourquoi un fichier de verrouillage et non
requirements.txt- Commitez l'intention et le verrou — Le fichier d'intention est ce qu'un humain édite ; le verrou est ce depuis quoi une…
Notes du présentateur
Commitez l'intention et le verrou. Le fichier d'intention est ce qu'un humain édite ; le verrou est ce depuis quoi une machine reproduit, et aucun ne remplace l'autre.Ce que cette plateforme fige, et pourquoi un verrou est inhabituel — Exemple
{ "packageManager": "pnpm@11.9.0", "engines": { "node": ">=22" }, "devDependencies": { "typescript": "^6.0.3" } }Ce que cette plateforme fige, et pourquoi un verrou est inhabituel
- Le gestionnaire de paquets lui-même est figé — parce qu'un pnpm différent résout le fichier de verrouillage…
- TypeScript est maintenu en 6.x délibérément — TypeScript 7 — le compilateur natif — n'expose pas encore l'API…
- C'est la forme que devrait avoir un verrou — Une contrainte de version sans commentaire est une contrainte que personne…
Notes du présentateur
Le gestionnaire de paquets lui-même est figé, parce qu'un pnpm différent résout le fichier de verrouillage différemment, et c'est la couche en dessous de celle que la plupart des projets figent. TypeScript est maintenu en 6.x délibérément. TypeScript 7 — le compilateur natif — n'expose pas encore l'API programmatique dont dépendastro check, si bien quepnpm typecheckéchoue purement et simplement en 7. Le verrou a une raison, la raison est écrite, et elle nomme la condition de sa levée. C'est la forme que devrait avoir un verrou. Une contrainte de version sans commentaire est une contrainte que personne n'osera retirer et que personne ne peut justifier de garder.Ce que cette plateforme fige, et pourquoi un verrou est inhabituel — Exemple
# pandas is pinned below 3.0 because the copy-on-write default changes the # behaviour of the recode in src/clean.py:88. Revisit when that is rewritten. pandas = ">=2.1,<3.0"Les conteneurs, et quand ils en valent la peine
- Ils en valent la peine quand — l'analyse a des dépendances hors Python ou hors R — GDAL, une distribution TeX, un…
- Ils n'en valent pas la peine quand — un fichier de verrouillage reproduit déjà le résultat et que le public est deux…
Notes du présentateur
Un conteneur fige aussi le système d'exploitation, la seule couche qu'un fichier de verrouillage ne peut pas atteindre. Ils en valent la peine quand l'analyse a des dépendances hors Python ou hors R — GDAL, une distribution TeX, un client de base de données —, ou quand elle doit tourner sans surveillance sur un serveur, ou quand le constat sera réexaminé des années plus tard. Ils n'en valent pas la peine quand un fichier de verrouillage reproduit déjà le résultat et que le public est deux collègues avec des ordinateurs portables. Un conteneur ajoute une étape de construction, un registre et une compétence qu'une petite équipe de suivi-évaluation peut ne pas avoir, et le coût est réel.Les conteneurs, et quand ils en valent la peine — Exemple
FROM python:3.12-slim COPY pyproject.toml uv.lock ./ RUN pip install uv && uv sync --frozen COPY . . CMD ["uv", "run", "python", "run.py"]Les conteneurs, et quand ils en valent la peine
- Commencez par le fichier de verrouillage — Passez au conteneur quand vous pouvez nommer la dépendance qu'il fige et que…
Notes du présentateur
Commencez par le fichier de verrouillage. Passez au conteneur quand vous pouvez nommer la dépendance qu'il fige et que le verrou ne peut pas.Le test qui le prouve
- Reproduisez votre propre résultat sur une machine qui n'a jamais vu le projet — Un clone neuf dans un répertoire…
Notes du présentateur
Reproduisez votre propre résultat sur une machine qui n'a jamais vu le projet. Un clone neuf dans un répertoire temporaire en fait l'essentiel.Le test qui le prouve — Shell
git clone <repo> /tmp/check && cd /tmp/check uv sync uv run python run.py diff -r outputs/ ~/project/outputs/Le test qui le prouve
- Si vous ne pouvez pas le faire, « c'est reproductible » n'est pas testé — L'ordinateur d'un collègue vaut mieux et un…
Notes du présentateur
Si vous ne pouvez pas le faire, « c'est reproductible » n'est pas testé. L'ordinateur d'un collègue vaut mieux et un exécuteur d'intégration continue vaut mieux encore, parce que c'est une machine propre à chaque fois et qu'il s'exécute que quiconque y pense ou non.Rapportez-le en entier — Exemple
Computational environment Python 3.12, dependencies pinned in uv.lock (committed). Reproduce with: uv sync && uv run python run.py pandas is held below 3.0 because the copy-on-write default changes the recode in src/clean.py; this is revisited when that function is rewritten. The pipeline runs on every push in CI on a clean machine, so the claim that a fresh checkout reproduces these outputs is tested rather than asserted. Analysis run on 2026-03-14 with commit a3f9c21.Rapportez-le en entier
- La dernière ligne est celle qui rend le reste utilisable un an plus tard — Un résultat sans le commit qui l'a produit…
Notes du présentateur
La dernière ligne est celle qui rend le reste utilisable un an plus tard. Un résultat sans le commit qui l'a produit se reproduit approximativement ; avec lui, exactement.La suite
- Un environnement figé produit encore une réponse différente à la seconde exécution si le code lit l'horloge, tire un nombre aléatoire, ou se fie à l'ordre dans lequel les fichiers reviennent.
Notes du présentateur
Un environnement figé produit encore une réponse différente à la seconde exécution si le code lit l'horloge, tire un nombre aléatoire, ou se fie à l'ordre dans lequel les fichiers reviennent. La leçon suivante trouve les quatre.