Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions scripts/check_lane_claim.py
Original file line number Diff line number Diff line change
Expand Up @@ -2409,11 +2409,14 @@ def _run_check(payload: dict, my_lane: str, stale_threshold=None,
# (`check_lane_claim.py N --lane L --paths p`) silently skipped the guard
# and printed `free_paths` -- a list that describes the CLAIM scope, never
# the open-PR space -- reading as an all-clear on an occupied file.
# #18341 -- the leg now uses `my_scope` (--paths U paths: du claim propre)
# so a lane that has already declared `paths:` on its active claim gets
# the OPEN-PR check without having to pass `--paths` on the call.
open_pr_collisions: list[PathCollision] = []
if check_open_pr_paths and my_paths:
if check_open_pr_paths and my_scope:
try:
open_pr_collisions, _own = _compute_open_pr_collisions(
my_paths, my_lane)
my_scope, my_lane)
except RuntimeError as exc:
print(
f"WARN: la jambe PR-ouverte n'a pas pu tourner sur "
Expand Down
79 changes: 79 additions & 0 deletions scripts/tests/test_check_lane_claim.py
Original file line number Diff line number Diff line change
Expand Up @@ -6159,6 +6159,85 @@ def test_open_pr_leg_shares_one_reader_with_paths_mode(monkeypatch):
assert cols[0].lane == "other:CoursIA"


# --- #18341 : la jambe PR-ouverte doit lire `my_scope`, pas `my_paths` --------
# Defaut mesure : `check_lane_claim.py N --lane L` (SANS `--paths`) lisait
# `my_paths`, qui est None quand le caller n'a pas passe `--paths`. Le resultat
# etait un CLEAR sans que les PRs OUVERTES des autres lanes sur les chemins du
# claim propre (`paths:`) aient ete regardees. Cout : doublons non detectes
# (#18230/#18293 doublon de #18180 ; #18196/#18304 doublon de #18281).

_MY_PATHS_FILE = "scripts/notebook_tools/wsl_papermill.py"


def test_18341_claim_with_paths_runs_open_pr_leg_without_cli_paths(
monkeypatch, tmp_path, capsys):
"""CONTROLE POSITIF #18341 -- claim propre `paths: p` + PR ouverte d'une
autre lane sur `p` + appel SANS `--paths` -> rc 2, PR nommee.

Avant ce fix : rc 0, CLEAR silencieux (defaut #18341).
"""
source = _write_payload(payload(comment(
"[CLAIMED] lane myia-po-2027:CoursIA-2 -- paths: " + _MY_PATHS_FILE,
"2026-09-29T00:00:00Z",
), number=18305), tmp_path)
monkeypatch.setattr(clc, "_compute_open_pr_collisions", lambda paths, my_lane, prs=None: (
[clc.PathCollision(
pr=_collision_pr(18304, "myia-po-2023:CoursIA-2", [_MY_PATHS_FILE]),
lane="myia-po-2023:CoursIA-2",
files=[_MY_PATHS_FILE])],
[]))
rc = clc.main([
"18305", "--lane", "myia-po-2027:CoursIA-2", "--from-json", source,
"--no-stale",
])
captured = capsys.readouterr()
summary = json.loads(captured.out.split("\n\n", 1)[0])
assert rc == 2, captured.err
assert [c["number"] for c in summary["open_pr_collisions"]] == [18304]
assert summary["open_pr_collisions"][0]["lane"] == "myia-po-2023:CoursIA-2"
assert "18304" in captured.err and "myia-po-2023:CoursIA-2" in captured.err


def test_18341_no_scope_declared_leg_not_called(monkeypatch, tmp_path, capsys):
"""CONTROLE NEGATIF #18341 -- ni `--paths` ni claim a `paths:` -> jambe
PR-ouverte NON appelee (legacy : aucun perimetre declare, rien a
intersecter). Avant comme apres le fix : la jambe reste gatee sur
`my_scope is not None`.
"""
source = _write_payload(payload(comment(
"[RELEASED] lane other:CoursIA-2", "2026-09-29T00:00:00Z",
), number=18305), tmp_path)
called = []
monkeypatch.setattr(clc, "_compute_open_pr_collisions",
lambda paths, my_lane, prs=None: called.append(1) or ([], []))
rc = clc.main([
"18305", "--lane", "myia-po-2027:CoursIA-2", "--from-json", source,
"--no-stale",
])
assert rc == 0
assert called == [] # jambe non appelee


def test_18341_pre_fix_code_renders_clear(monkeypatch, tmp_path, capsys):
"""CONTROLE DE REGRESSION #18341 -- avec le code d'avant le fix
(`my_paths` au lieu de `my_scope` dans la condition), la jambe ne tourne
pas et le verdict reste CLEAR. Ce test pin l'evidence que le fix est
necessaire : il reussit contre le code d'avant, et echoue contre le code
d'apres -- mais comme nous sommes sur le code d'apres, on simule la
regression en monkeypatchant la condition. La regle est : si on lit
`my_paths` au lieu de `my_scope`, on a le defaut #18341.
"""
# On verifie directement la CONTRACTION : `my_scope` doit etre lu.
# Lecture directe du source, pas d'execution : assert que le mot
# `my_paths` n'apparait PAS dans la condition de la jambe PR-ouverte.
src = Path("scripts/check_lane_claim.py").read_text(encoding="utf-8")
# La jambe PR-ouverte (apres #18341) lit my_scope, pas my_paths
assert "if check_open_pr_paths and my_scope:" in src, \
"leg #16570 doit lire my_scope (et non my_paths) apres #18341"
assert "if check_open_pr_paths and my_paths:" not in src, \
"leg #16570 lit my_paths = defaut #18341"


# --- #12811 : gh/git émettent de l'UTF-8, l'encodage doit être épinglé --------


Expand Down
Loading