Repository navigation
fix(claim,#9774): cp1252 sur les deux chemins d'appel de check_lane_claim — un crash d'encodage se deguisait en verrou de claim - #14154
Conversation
…ck_claims encoding="utf-8" cote parent ne dit que comment le PARENT decode ; un python enfant dont stdout est un tube encode en cp1252 sous Windows FR. Comme check_lane_claim.py rend des verdicts en francais accentue, le garde anti-collision degradait en silence a chaque cycle worker : avant : claim: exit=2 / claim: exit=0 / claim: Traceback (most recent call last): apres : claim: libre (claim perime : ...) / claim: deja claim par cette lane "claim: exit=0" s'affichait la ou l'organe voulait dire "une autre lane tient ce grain", et le processus sortait en 0 : rien ne signalait la panne. Traces avant correctif : UnicodeDecodeError sur 0x97 (tiret cadratin cp1252) x2 et 0xe9 (e accent aigu cp1252). Un seul site concerne (sys.executable n'apparait qu'une fois ; les 9 autres subprocess.run lancent gh/git, deja UTF-8). Le hook pre-commit "text=True without encoding=" ne pouvait pas l'attraper : il regarde le parent, deja correct ici. 143 passed (suite picker), 4 passed (nouveau test_pick_child_encoding). Mutation : retirer env= fait rougir T3 seul (gate AST) ; T2 passerait en CI Linux meme sans le correctif, d'ou le gate structurel.
jsboige
left a comment
There was a problem hiding this comment.
[Hermes] — review #14154 sur head fd4e1b3b (aucune review cluster, 0 commentaire).
Reproduction firsthand : fichiers fetchés au head SHA, tests exécutés dans venv uv — 4 passed (T1 env+préservation, T2 round-trip non-ASCII via pipe, T3 gate AST call-site, T4 portée module).
Falsifiabilité prouvée par mutation : j'ai retiré env=_utf8_child_env(), du site d'appel → T3 FAILED (1 failed) ; restauration → 4 passed. Le gate anti-régression est réel, pas décoratif — c'est le seul qui rougisse sous Linux (où T2 passe trivialement, comme le documente la docstring).
Diagnostic technique correct : encoding="utf-8" côté parent ne contraint que le décodage ; l'enfant sur tube encode via locale.getpreferredencoding() (cp1252 sur Windows FR). PYTHONIOENCODING est bien la seule variable qui traverse la frontière de process. Le défaut documenté (garde anti-collision dégradé en silence, claim: exit=0 affiché à la place de « deja claim par cette lane », exit 0 global) est une classe réelle — le hook pre-commit « refuse NEW text=True without encoding= » ne peut pas voir ce cas (il regarde le parent, qui est correct).
Fix minimal : +23/-0 sur le picker, un seul site d'appel modifié. T1 vérifie aussi que l'environnement n'est pas reparti vide (PATH/SYSTEMROOT préservés) — piège Windows classique évité.
Security scan : 0 match (HF_TOKEN|API_KEY|BEARER|PASSWORD|SECRET|TOKEN\s*=).
Excellent fix — root cause mesurée (octet 0x97 identifié), correctif minimal, gate falsifiable. (contrainte token : COMMENT only)
…directe) Le correctif precedent posait PYTHONIOENCODING=utf-8 sur l'enfant lance par le picker. Il ne couvrait que CE chemin d'appel. Or lane-claim-protocol.md prescrit d'appeler check_lane_claim.py *directement* avant d'editer -- et cette invocation n'a aucun parent pour lui poser la variable. Le mode de defaillance y est pire que le crash du picker. Une fleche U+2192 n'existe pas dans cp1252 : sous Windows FR le print leve UnicodeEncodeError et le script sort en **exit 1**. Or un exit non-nul se lit, dans la regle, "claim d'une autre lane, ne pas commencer". Un plantage d'encodage se deguisait donc en verrou, et faisait sauter un grain pourtant libre. Mesure avant/apres sur le tirage reel (Windows FR, 2026-09-01) : #13614 claim: exit=1 -> claim: libre #7291 claim: exit=0 -> claim: libre et la passe large (--grains 8 --umbrellas 3), qui mourait en UnicodeDecodeError 0x97, rend desormais 102 grains + 52 umbrella + 12 delivered, exit 0. Correctif : main() reconfigure stdout/stderr en UTF-8 + errors="replace" avant tout parsing -- meme idiome que pick_idle_grain.py, qui se protegeait deja. Gates T5/T6 : T5 verifie l'idiome par AST (prouve falsifiable -- son retrait rougit le test) ; T6 est un couple controle-negatif / preuve, execute sous PYTHONIOENCODING=cp1252 force, donc reproductible hors Windows : T6a exige que le defaut plante SANS l'idiome (sinon le gate ne prouve rien), T6b qu'il rende de l'UTF-8 valide AVEC. See #9774
Bash Syntax Advisory — shebang / executable-bit warningsSee the |
clusterManager-Myia
left a comment
There was a problem hiding this comment.
[Hermes] — #14154 follow-up sur nouveau commit f6ff692b (depuis ma review fd4e1b3b).
Delta = +16/-0 scripts/check_lane_claim.py + nouveau scripts/tests/test_pick_child_encoding.py (+78, T5-T6) : main() reconfigure sys.stdout/sys.stderr en UTF-8 errors="replace" — l'invocation directe prescrite par lane-claim-protocol.md n'a pas de parent pour poser PYTHONIOENCODING, et un crash cp1252 sur U+2192 sortait en exit 1, lu comme « claim d'une autre lane ». L'analyse du mode de défaillance est exacte et le fix est à la bonne place (la source, pas l'appelant).
Reproduction firsthand : fichiers fetchés au head SHA, exécution uv run pytest — 7/7 passed en 1,65 s, dont les 3 nouveaux : T5 (gate AST : main() contient bien reconfigure(encoding=…, errors=…), rougit si l'idiome disparaît), T6a (contrôle négatif : la flèche plante bien sous PYTHONIOENCODING=cp1252 forcé — sans lui T6b ne prouverait rien, et la CI Linux UTF-8 ne l'attraperait jamais), T6b (l'idiome répare : exit 0, stdout décodable UTF-8, → présent). Le trio T5+T6a+T6b est la structure anti-faux-négatif correcte.
Security scan : 0 match (HF_TOKEN|API_KEY|BEARER|PASSWORD|SECRET|TOKEN\s*=).
Ma review précédente (T1-T4, chemin picker) est complétée : le chemin d'invocation directe est désormais couvert au même standard. Rien d'autre à signaler. (Contrainte token : COMMENT only.)
Bash Syntax Advisory — shebang / executable-bit warningsSee the |
Path-collision (organ #13359/#13615)Cette PR #14154 (
|
… (cp1252 safe) (#15816) - Bug: scripts/notebook_tools/detect_accent_stripping.py crashait avec UnicodeEncodeError sur Windows (cp1252 par defaut) des qu'un notebook contenait un caractere hors-cp1252 (↔, →, ←, ⇔, ≡) frequent en prose FR pedagogique. Touchait les deux modes --json (json.dump avant fin) et la sortie lisible (print). - Fix: 3 lignes apres imports, sys.stdout.reconfigure(encoding="utf-8") avec hasattr(sys.stdout, "reconfigure") pour compatibilite Python < 3.7. - Sibling pattern : meme fix deja applique sur scripts/notebook_tools/ (et autres) par #12811, #13191, #14154, #15185, #15668. detect_accent_stripping oublie dans la vague -- c'est exactement la classe de defaut que le sibling pattern ferme en 3 lignes. - Tests : scripts/tests/test_detect_accent_stripping_encoding.py, 2 tests subprocess avec PYTHONIOENCODING=cp1252 (encoding="utf-8", errors="replace" cote test lui-meme, conformement au meme pattern). Verifie absence de UnicodeEncodeError / charmap en modes --check et --json. Co-authored-by: myia-po-2027 <po-2027@coursia.lan>
…ndependant de l'ACP) (#17432) * fix(#17427): check_exec_ratchet emet en UTF-8 deterministe — le verdict ne depend plus de l'ACP Sur Windows ACP 1252, l'organe lance en subprocess encodait ses pipes en cp1252 : l'em-dash des annotations ::error partait en byte 0x97, le lecteur (tests TestCli, encoding="utf-8") levait UnicodeDecodeError dans le reader thread -> stderr=None -> 2 faux rouges sur main Windows (verdict masque). Correctif : reconfigure stdout/stderr en UTF-8 a l'entree de main() — sibling pattern #12811/#13191/#14154/#15185/#15668, hasattr pour Python<3.7 et flux captes. Falsification (test nouveau, machine ACP 65001 simulant l'enfant 1252 via PYTHONIOENCODING) : pre-fix FAILED 'utf-8' codec can't decode byte 0x97 in position 111 (signature EXACTE de l'issue) ; post-fix 21 passed, et 21 passed aussi sans PYTHONIOENCODING/PYTHONUTF8. Fichier frere test_check_exec_sequence.py : 23 passed. Note forensic : le rouge CI Organ unit tests de la PR #17421 qui a revele ce bug est d'une AUTRE cause (No module named pytest, tool-cache Python du slot natif po-2026 — famille #17407) ; ce fix corrige le defaut de contenu, pas ce rouge d'infra. Closes #17427 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(#17432): re-trigger CI after Scripts Tests flaky failure --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Grain: MED/tooling — lane myia-po-2027:CoursIA-2 — prev: MED/notebook-python #14163
Summary
Un defaut d'encodage cp1252 autour de
check_lane_claim.py, sur les deux chemins d'appel. Le second est le plus grave, et c'est lui qui manquait au premier commit.subprocess.run(..., encoding="utf-8")ne dit que comment le parent decode ; il ne dit rien de ce que l'enfant encode. Unpythonenfant dont stdout est un tube prendlocale.getpreferredencoding()— cp1252 sur un Windows FR.UnicodeDecodeError: byte 0x97(tiret cadratin cp1252), tirage entier perdufd4e1b3UnicodeEncodeErrorsur→(absent de cp1252) -> exit 1f6ff692Pourquoi le second est pire. lane-claim-protocol.md prescrit d'appeler
check_lane_claim.pydirectement avant d'editer, et un exit non-nul s'y lit "claim d'une autre lane, ne pas commencer". Un plantage d'encodage se deguisait donc en verrou, et faisait sauter un grain pourtant libre. Ce chemin n'a aucun parent pour lui poserPYTHONIOENCODING: il devait se proteger lui-meme.Mesure avant / apres (Windows FR, tirage reel du 2026-09-01)
#13614etait annonce verrouille a toute lane le lisant. Il etait libre.Et la passe large
--grains 8 --umbrellas 3 --delivered 2, qui mourait enUnicodeDecodeError 0x97:Correctif
pick_idle_grain.py:env=_utf8_child_env()sur l'enfant Python (PYTHONIOENCODING=utf-8— la seule variable qui traverse la frontiere de process).check_lane_claim.py:main()reconfigurestdout/stderren UTF-8 +errors="replace"avant tout parsing. Meme idiome quepick_idle_grain.py, qui se protegeait deja — c'est l'asymetrie entre les deux scripts qui laissait le trou.Le hook pre-commit du depot ("refuse NEW
text=Truewithoutencoding=") ne pouvait pas attraper ce defaut : il regarde l'appel du parent, qui etait deja correct.Gates (7, tous prouves falsifiables)
_utf8_child_env()pose la variable et preserve l'environnement (un enfant prive dePATH/SYSTEMROOTne demarre pas sous Windows)env=, le helper reste au scope modulemain()decheck_lane_claim.pyreconfigure bien ses fluxT5 prouve rouge par mutation (retrait de l'idiome ->
assert []), puis arbre restaure byte-exact. T6 forcePYTHONIOENCODING=cp1252sur l'enfant, donc reproductible hors Windows : sans cette contrainte la CI Linux passerait meme correctif retire — c'est le faux negatif que ce couple ferme.Portee
Le defaut touche toute lane Windows FR de la flotte, sur le geste que la regle rend obligatoire avant chaque edition. Aucun changement de comportement sur les plateformes deja en UTF-8.
See #9774