Repository navigation
feat(ci,#17361): dotnet_preload_packages.py -- workaround #r nuget: en assemblies locales - #17828
Conversation
Le 2e `#r "nuget:"` d'une session dotnet-interactive 1.0.617701 peut lever `PackageRestoreResult..ctor ArgumentException` (mesure c.760, non deterministe), ce qui tue la cellule sans contournement runtime. Le seul chemin defensif est de ne plus appeler `#r "nuget:"` du tout, et de referencer des assembly locales : `#r "./_deps/QuikGraph.dll"`. `scripts/ci/dotnet_preload_packages.py` (livrable 2 du RFC `docs/reference/dotnet-restore-rfc-17361.md`) resout le cache NuGet global ou le peuple par un `dotnet restore` de projet jetable (`PackageDownload`, sans contrainte de TFM), copie les DLL a plat dans `_deps/` et emet `.NET-packages.json` avec les lignes `#r` pretes a coller. - `scripts/tests/test_dotnet_preload_packages.py` : 41 cas, `dotnet` jamais invoque (restorer injecte). - `.gitignore` : `_deps/` generalise (seul `scripts/notebook_tools/probes/` etait couvert) -- le helper ecrit a cote du notebook. - RFC : le TODO d'esquisse et la mention « en attendant le helper » sont remplaces par l'usage reel. See #17361
|
G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour, toutes categories LIGHT confondues -- un RATIO, pas un plafond plat ; le cap calcule du jour est dans le tally ci-dessus. G-VAR-3 interdit deux genres LIGHT consecutifs. Les signaux ci-dessus rendent le fait VISIBLE (labels |
…esure
Pilot sur le notebook du depot le plus expose au bug (CSP-1-Fundamentals-CSharp,
3 restores NuGet dans une seule cellule), kernel .net-csharp, pin cluster
1.0.617701, po-2024. Trois bras :
bras 0 -- 3 x #r "nuget:" (original) : 19/19 OK, 14,1 s
bras A -- 3 x #r local via le helper : 16/19, "Could not locate
ikvm home path"
bras C -- IKVM local + 2 packages image nuget : 15/19, MSB4036 "Tache
IkvmResolveNearestRuntimeIdentifier
introuvable"
Le bras C explique les deux autres : les #r "nuget:" ne sont pas de simples
references, ce sont eux qui font restaurer l'arbre IKVM complet -- IKVM.MSBuild
fournit la tache MSBuild que IKVM.Image.targets invoque, et l'image any/any +
win-x64 fournit le home que IKVM.Runtime cherche au premier type java.*.
Consequences ecrites dans le RFC : livrable 3 refute pour la famille IKVM ;
IKVM.Image / IKVM.Image.runtime.win-x64 non exprimables en #r local (lib/<tfm>/_._) ;
et _deps/ etant gitignore, convertir un notebook pedagogique echangerait un bug
non deterministe contre une panne deterministe pour tout clone.
Le helper reste un outil de reparation a la demande. Bras 0 = 4e non-reproduction
du bug (corrobore c.803/c.807).
See #17361
Path-collision (organ #13359/#13615)Cette PR #17828 (
Le verdict terminal (#15578) signale qu'un cote de la paire est deja sur |
|
[ADJOINT PREFLIGHT] Premier dossier sur cette PR (jamais tamponnee). Verifications propres : b0 sonde en direct (check_unaddressed_nits rc=0, aucun nit non leve, aucun commentaire non evalue) ; pliage 43 jambes / 29 noms au head 654bc11, zero jambe non-verte apres deduplication latest-wins (14 jambes supersedees ecartees) ; mergeStateStatus CLEAN, MERGEABLE. |
Grain: DEEP/tooling — lane myia-po-2024:CoursIA-2 — prev: DEEP/notebook-python #17763
Ce que fait cette PR
Implémente le livrable 2 du RFC
docs/reference/dotnet-restore-rfc-17361.md: le helper qui rend praticable la workaround du bug#r "nuget:".Sur dotnet-interactive 1.0.617701 (pin cluster), le 2e
#r "nuget:"d'une session kernel peut leverPackageRestoreResult..ctor ArgumentException— le bug est non déterministe (3 repros sur 3 le 2026-09-22, plus aucune sur les 2 re-tentatives du 2026-09-23, à cache chaud comme à cache froid). Quand il tombe, il tue la cellule sans contournement runtime : le seul chemin défensif est de ne plus appeler#r "nuget:"du tout et de référencer des assemblies locales.scripts/ci/dotnet_preload_packages.py:NUGET_PACKAGES, sinon~/.nuget/packages) — hors ligne si le cache est déjà peuplé ;dotnet restorede projet jetable utilisantPackageDownloadet nonPackageReference— c'est l'item NuGet prévu pour télécharger sans contrainte de compatibilité de framework, là où unPackageReferenceéchouerait en NU1202 sur tout package ne ciblant pas le TFM du projet (rien n'est compilé ici) ;net9.0→netstandard2.0) ;_deps/et émet_deps/.NET-packages.jsonavec les lignes#rprêtes à coller.Deux points que l'esquisse du RFC disait autrement
_deps/, et non.dotnet_packages/<pkg>/<ver>/:#rest résolu au parse-time et exige un littéral relatif au notebook, dont la forme mesurée (c.790/c.803) est./_deps/<Dll>.dll. Le RFC est corrigé dans le même commit._deps/et masquerait ce qui est réellement référencé.Validation
Tests unitaires — 41/41 (
python -m pytest scripts/tests/test_dotnet_preload_packages.py) :dotnetn'est jamais invoqué par la suite (lerestorerest injecté) : aucun réseau, aucun SDK requis en CI. Couvreparse_spec, le tri SemVer, la résolution de cache, la sélection de TFM, les chemins de sortie, et les cinq formes d'échec derestore_via_dotnet.Deux bugs réels attrapés par les tests pendant l'écriture (et corrigés) :
_version_key1.0.0-rc1triait au-dessus de1.0.0, donc unNomnon épinglé pouvait résoudre vers une RC0 if pre else 1dotnet restoresur le mauvais flux-v quietécrit ses erreurs sur stdout ; le message rendait(stderr vide)— inutilisableExécutions réelles sur la machine (pas seulement des mocks) :
Le dernier cas est la preuve du correctif de diagnostic :
dotnetémet ses erreurs en français accentué, ce qui a aussi motivé le passage àencoding="utf-8", errors="replace"sur lesubprocess.run— sans quoi un hôte cp1252 lèveUnicodeDecodeErrorsur ce payload (classe #13140/#12811). Le hookcheck-subprocess-encodingpasse (rc=0).Périmètre
scripts/ci/dotnet_preload_packages.pyscripts/tests/test_dotnet_preload_packages.py.gitignore_deps/généralisé (seulscripts/notebook_tools/probes/_deps/était couvert ; le helper écrit à côté du notebook)docs/reference/dotnet-restore-rfc-17361.mdTODO: à implémenteret la mention « en attendant le helper » remplacés par l'usage réelPas de
Closes:See #17361. Le livrable 3 du RFC n'est pas livré — il est réfuté par le second commit (voir plus bas) : il n'y a donc pas de conversion de masse à faire, et rien ne doit laisser croire que l'issue entière est résolue par un outil.Réserve connue, dite plutôt que tue
scripts/testsen suite complète sur ce worktree :6942 passed, 3 failed— les 3 échecs sont danstest_prune_merged_worktrees.py::TestEndToEnd(tests d'intégration qui créent de vrais worktrees et appellentgh).test_json_includes_required_keys, l'un des trois, repasse seul dans le même arbre (1 passed in 132.91s). Ces tests sont sensibles à l'état de la machine et à l'ordonnancement de la suite ; ce diff est purement additif (un module isolé, un fichier de test isolé), aucun de ces tests ne l'importe. Je le signale comme friction observée, pas comme régression imputée à cette PR.Second commit : le livrable 3 du RFC est réfuté par la mesure
Le RFC prévoyait (livrable 3) de convertir tous les notebooks
.net-csharpen#rlocal. Le pilot du 2026-09-25 montre que les deux formes ne sont pas interchangeables — donc ce livrable partait d'une prémisse fausse.Notebook choisi parce que c'est le plus exposé du dépôt au bug :
Search/Part2-CSP/CSP-1-Fundamentals-CSharp.ipynbfait 3 restores NuGet dans une seule cellule (cellule 3 :IKVM,IKVM.Image,IKVM.Image.runtime.win-x64) — exactement le déclencheur observé en c.760 (« 2ᵉ restore de la session »). Kernel.net-csharp, pin cluster1.0.617701, po-2024.#r "nuget:"#r "./_deps/…"(le helper de cette PR)IKVM.Runtime.InternalException: Could not locate ikvm home pathIKVMlocal + les 2 packages image ennuget:IKVM.Image.targets(45,9): error MSB4036: Tâche "IkvmResolveNearestRuntimeIdentifier" introuvableLe bras C est celui qui explique les deux autres : les
#r "nuget:"ne sont pas de simples références, ce sont eux qui font restaurer àMicrosoft.DotNet.Interactive.PackageManagementl'arbre IKVM complet.IKVM.MSBuildfournit la tâche MSBuild queIKVM.Image.targetsinvoque, et l'imageany/any+win-x64fournit le home queIKVM.Runtimecherche au premier typejava.*. Scinder les#rcasse ce graphe : le bras C tombe dès la cellule 3 sur la tâche manquante ; le bras A va plus loin et tombe au premier appel Java, faute de home.Trois faits sortis de la mesure, tous versés dans le RFC :
IKVM.ImageetIKVM.Image.runtime.win-x64ne sont pas exprimables en#rlocal : leurslib/<tfm>/ne contiennent qu'un_._, la convention NuGet « TFM compatible, aucune assembly ». Le helper le dit correctement (aucune assembly dans …/lib) — ce n'est pas un défaut de l'outil, c'est la limite du remplacement._deps/étant gitignore, committer un notebook pédagogique converti échangerait un bug non déterministe contre une panne déterministe (« fichier introuvable ») pour tout clone.Décision écrite dans le RFC : le helper reste un outil de réparation à la demande — à invoquer quand l'exception se produit, sur le notebook concerné — et pas une convention à généraliser. Le geste de masse est retiré des livrables.
Sous-produit : le bras 0 est une 4ᵉ non-reproduction du bug (3 restores dans une cellule, tous réussis), qui corrobore c.803 (cache chaud) et c.807 (cache froid) après les 3 repros de c.760.
Aucune exécution de notebook n'est committée : le pilot a tourné sur une copie (
._probe17361.ipynb), supprimée depuis, et le notebook d'origine est resté byte-identique (git diffvide surSearch/Part2-CSP/).