fix(tooling,#12722): strip metadata.papermill perime cable dans tous les executeurs non-Papermill - #12724
Conversation
…les executeurs non-Papermill Le correctif #11146 vivait uniquement dans dotnet_executor : chaque executeur de kernel (notebook_helpers save/write, exec_single_cell, exec_dotnet_persist, execute_qcpy_docker) reecrivait les sorties en laissant le bloc de la passe papermill anterieure — 11 PRs bloquees par le ratchet STALE_BLOCK (#11155). Co-Authored-By: Claude-Code <noreply@anthropic.com>
jsboige
left a comment
There was a problem hiding this comment.
[Hermes] — COMMENT favorable, tests reproduits firsthand (contrainte token : COMMENT only sur PR jsboige)
Reproduit scripts/tests/test_papermill_meta_strip.py au head SHA 4143d3ec50 (fetch raw + venv uv + pytest + ipykernel) : 6 passed — dont les 2 tests subprocess réels sur kernel python3 (dotnet_executor.py --kernel python3, exec_single_cell.py --index 0), exécution kernel effective (~40-53 s sur ma machine).
Points vérifiés dans le diff :
- Extraction fidèle :
strip_stale_papermill_metadataest byte-identique à l'ancienne_strip_stale_papermill_metadatadedotnet_executor.py(docstring et sémantiquemetadata.papermill+metadata.execution.papermillconservées) — le test dotnet_executor devient le test de non-régression de l'extraction. - Câblage complet des 5 points d'écriture :
NotebookHelper.save()+write_notebook()(helper générique),exec_single_cell.pyavant lejson.dump,exec_dotnet_persist.pyetexecute_qcpy_docker.pyvia_save_executedextrait — chaque extraction est justifiée par la testabilité sans .NET/Docker. - Exclusions correctes :
batch_reexecute.pyetwsl_papermill.pydélèguent à Papermill qui réécrit son propre bloc — frais par construction, ne pas les câbler est le bon appel. - Test par exécuteur = la bonne granularité : le défaut était précisément un correctif posé sur un seul jumeau (#11146) et jamais propagé.
La donnée complémentaire (blocs cell.metadata.papermill hors périmètre du garde et de cette fonction) est correctement documentée pour arbitrage dans #12722 — ne bloque pas ce correctif minimal.
…less runners Two failure classes from CI run 32681713419 (4 failed, 9292 passed): - test_dotnet_executor.py still called dotnet_executor._strip_stale_papermill_metadata, renamed when the strip moved to _papermill_meta.py (see #12722) — now calls the canonical dotnet_executor.strip_stale_papermill_metadata re-export. - the two subprocess integration tests start a real python3 kernel; the GitHub runner registers none (NoSuchKernel before any tested code runs). They now skip via KernelSpecManager().find_kernel_specs() membership; the unit write-path tests above still cover the strip wiring on every runner. Local: scripts/tests/test_papermill_meta_strip.py + scripts/notebook_tools/tests/test_dotnet_executor.py -> 35 passed, 0 skipped (subprocess tests executed for real, kernel present here). Refs #12724
|
Reprise des 4 echecs CI (run 32681713419), deux classes distinctes, corrigees en 015ff26 :
Validation locale post-fix : |
Grain: MED/tooling — lane myia-po-2024:CoursIA — prev: MED/notebook-python #12561
Closes #12722
Summary
Le strip du bloc
metadata.papermillpérimé vivait uniquement dansdotnet_executor.py(#11146) : grep\.pop("papermill"= 2 hits, 1 fichier. Chaque autre exécuteur non-Papermill qui réécrit un notebook laissait le bloc de la passe Papermill antérieure à côté de sorties fraîches — exactement la signature STALE_BLOCK du ratchet (#11155), 11 PRs bloquées au 2026-08-24 (mesure #12722).Correctif structurel, pas une relance du ratchet ni un retrait manuel en masse (les deux explicitly exclus par l'issue) :
_papermill_meta.py(nouveau) :strip_stale_papermill_metadata(nb)extraite dedotnet_executor.py:70-87sans changer son comportement — docstring et justification dotnet_executor laisse un metadata.papermill perime qui date un autre run #11146 conservées.dotnet_executor.pynotebook_helpers.pyNotebookHelper.save()+write_notebook()— l'exécuteur de kernel générique (MCP Jupyter cell-by-cell, transplant)exec_single_cell.pyjson.dumpde sortieexec_dotnet_persist.py_save_executed(nb, path)execute_qcpy_docker.py_save_executed(nb, nb_path)Non câblés à dessein :
batch_reexecute.py(délègue à Papermill subprocess, qui réécrit son propre bloc — frais par construction) ;wsl_papermill.py(idem).Validation
Tests : un par exécuteur (
scripts/tests/test_papermill_meta_strip.py, 6 tests). Chaque test écrit un notebook factice portant un bloc papermill périmé (end_time 2026-05-31), le passe au point d'écriture de cet exécuteur, et vérifie la disparition du bloc :dotnet_executor(déjà câblé sur main par dotnet_executor laisse un metadata.papermill perime qui date un autre run #11146 : c'est son test de non-régression à l'extraction, il échouerait si l'extraction changeait le comportement).python3(dotnet_executor.py --kernel python3,exec_single_cell.py --index 0), preuve bout-en-bout du câblage sans exiger .NET/Docker..NET, Docker/quantbook) sont testés sur leur point d'écriture extrait_save_executed— c'est le câblage qui manquait, il vit là.Non-régression :
test_notebook_tools_pure.py75 passed (parité notebook_helpers),test_check_papermill_ratchet.py15 passed (le garde lui-même, non desserré).Donnée complémentaire (versée dans le DM de réponse)
Les blocs
papermillpar cellule (cell.metadata.papermill, mêmes dates périmées) ne sont couverts ni par le garde (papermill_block()l.110 compare le bloc notebook-level) ni par cette fonction. Non traités ici — geste minimal du dispatch (retrait du bloc notebook-level, « rien d'autre ») ; à arbitrer dans #12722 si la classe doit être fermée complètement.Scope
7 fichiers : 1 nouveau module + 5 exécuteurs câblés + 1 fichier de tests. Aucun notebook touché, catalogue byte-identique.