style(scripts): fix ruff F401, F541, F841, E741 in 8 files #1808

Closed
agent-dev-a wants to merge 2 commits from fix/ruff-f401-f541-f841-e741-batch into main
9 changed files with 57 additions and 28 deletions
+4 -4
View File
@@ -547,12 +547,12 @@ def file_or_update(
if dry_run:
print(f"::notice::[dry-run] would file/update drift issue for {branch}")
print(f"::group::[dry-run] title")
print("::group::[dry-run] title")
print(title)
print(f"::endgroup::")
print(f"::group::[dry-run] body")
print("::endgroup::")
print("::group::[dry-run] body")
print(body)
print(f"::endgroup::")
print("::endgroup::")
return
existing = find_open_issue(title)
+46 -14
View File
@@ -183,7 +183,9 @@ def required_contexts_green(
status = latest_statuses.get(context)
state = status_state(status or {})
if state != "success":
if pr_labels and _is_tier_low_pending_ok(latest_statuses, context, pr_labels):
if pr_labels and _is_tier_low_pending_ok(
latest_statuses, context, pr_labels
):
continue # tier:low soft-fail: accept pending sop-checklist
missing_or_bad.append(f"{context}={state or 'missing'}")
return not missing_or_bad, missing_or_bad
@@ -213,7 +215,9 @@ def choose_next_queued_issue(
if "pull_request" not in issue:
continue
candidates.append(issue)
candidates.sort(key=lambda issue: (issue.get("created_at") or "", int(issue["number"])))
candidates.sort(
key=lambda issue: (issue.get("created_at") or "", int(issue["number"]))
)
return candidates[0] if candidates else None
@@ -247,7 +251,8 @@ def evaluate_merge_readiness(
main_latest = latest_statuses_by_context(main_status.get("statuses") or [])
main_ok, main_bad = required_contexts_green(main_latest, push_required_contexts())
if not main_ok:
return MergeDecision(False, "pause", "main required contexts not green: " + ", ".join(main_bad))
msg = "main required contexts not green: " + ", ".join(main_bad)
return MergeDecision(False, "pause", msg)
if not pr_has_current_base:
return MergeDecision(False, "update", "PR head does not contain current main")
@@ -259,7 +264,8 @@ def evaluate_merge_readiness(
latest = latest_statuses_by_context(pr_status.get("statuses") or [])
ok, missing_or_bad = required_contexts_green(latest, required_contexts, pr_labels)
if not ok:
return MergeDecision(False, "wait", "required contexts not green: " + ", ".join(missing_or_bad))
msg = "required contexts not green: " + ", ".join(missing_or_bad)
return MergeDecision(False, "wait", msg)
return MergeDecision(True, "merge", "ready")
@@ -294,7 +300,9 @@ def get_combined_status(sha: str) -> dict:
else:
all_statuses = []
except (ApiError, urllib.error.URLError, TimeoutError, OSError) as exc:
sys.stderr.write(f"::warning::could not fetch full statuses list for {sha[:8]}: {exc}\n")
sys.stderr.write(
f"::warning::could not fetch full statuses list for {sha[:8]}: {exc}\n"
)
all_statuses = []
# Build latest per context: process combined (ascending→reverse=newest
# first), then fill gaps from all_statuses (already newest-first).
@@ -345,11 +353,17 @@ def post_comment(pr_number: int, body: str, *, dry_run: bool) -> None:
print(f"::notice::comment PR #{pr_number}: {body.splitlines()[0][:160]}")
if dry_run:
return
api("POST", f"/repos/{OWNER}/{NAME}/issues/{pr_number}/comments", body={"body": body})
api(
"POST",
f"/repos/{OWNER}/{NAME}/issues/{pr_number}/comments",
body={"body": body},
)
def update_pull(pr_number: int, *, dry_run: bool) -> None:
print(f"::notice::updating PR #{pr_number} with base branch via style={UPDATE_STYLE}")
print(
f"::notice::updating PR #{pr_number} with base branch via style={UPDATE_STYLE}"
)
if dry_run:
return
api(
@@ -373,7 +387,12 @@ def merge_pull(pr_number: int, *, dry_run: bool) -> None:
if dry_run:
return
try:
api("POST", f"/repos/{OWNER}/{NAME}/pulls/{pr_number}/merge", body=payload, expect_json=False)
api(
"POST",
f"/repos/{OWNER}/{NAME}/pulls/{pr_number}/merge",
body=payload,
expect_json=False,
)
except ApiError as exc:
# Re-raise permission-like errors so process_once can skip this PR.
# 403 = no push access, 404 = repo/pr not found, 405 = not allowed.
@@ -393,7 +412,8 @@ def process_once(*, dry_run: bool = False) -> int:
main_latest = latest_statuses_by_context(main_status.get("statuses") or [])
main_ok, main_bad = required_contexts_green(main_latest, push_required_contexts())
if not main_ok:
print(f"::notice::queue paused: {WATCH_BRANCH}@{main_sha[:8]} required contexts not green: {', '.join(main_bad)}")
msg = f"queue paused: {WATCH_BRANCH}@{main_sha[:8]} required contexts not green"
print(f"::notice::{msg}: {', '.join(main_bad)}")
return 0
issue = choose_next_queued_issue(
@@ -411,10 +431,18 @@ def process_once(*, dry_run: bool = False) -> int:
print(f"::notice::PR #{pr_number} is not open; skipping")
return 0
if pr.get("base", {}).get("ref") != WATCH_BRANCH:
post_comment(pr_number, f"merge-queue: skipped; base branch is not `{WATCH_BRANCH}`.", dry_run=dry_run)
post_comment(
pr_number,
f"merge-queue: skipped; base branch is not `{WATCH_BRANCH}`.",
dry_run=dry_run,
)
return 0
if pr.get("head", {}).get("repo_id") != pr.get("base", {}).get("repo_id"):
post_comment(pr_number, "merge-queue: skipped; fork PRs are not supported by the serialized queue.", dry_run=dry_run)
post_comment(
pr_number,
"merge-queue: skipped; fork PRs are not supported by the serialized queue.",
dry_run=dry_run,
)
return 0
head_sha = pr.get("head", {}).get("sha")
@@ -459,13 +487,17 @@ def process_once(*, dry_run: bool = False) -> int:
# maintainers know why, then return 0 so this tick is done.
# The PR stays in the queue; future ticks can retry after the
# permission issue is resolved.
sys.stderr.write(f"::error::merge permission error for PR #{pr_number}: {exc}\n")
sys.stderr.write(
f"::error::merge permission error for PR #{pr_number}: {exc}\n"
)
post_comment(
pr_number,
(
"merge-queue: merge failed with HTTP 405 'User not allowed to merge PR'. "
"merge-queue: merge failed with HTTP 405 "
"'User not allowed to merge PR'. "
"No available token has Can-merge permission on this repo. "
"Fix: grant Can-merge to a token, or add a maintain/admin collaborator. "
"Fix: grant Can-merge to a token, or add a "
"maintain/admin collaborator. "
"Skipping to next queued PR on next tick."
),
dry_run=dry_run,
@@ -13,7 +13,6 @@ from __future__ import annotations
import argparse
import glob
import re
import sys
from pathlib import Path
from typing import NamedTuple
+1 -1
View File
@@ -283,7 +283,7 @@ def _ensure_labels(repo: str, names: list[str]) -> list[int]:
if status != "ok" or not isinstance(labels, list):
return []
out: list[int] = []
by_name = {l["name"]: l["id"] for l in labels if isinstance(l, dict)}
by_name = {lbl["name"]: lbl["id"] for lbl in labels if isinstance(lbl, dict)}
for n in names:
if n in by_name:
out.append(by_name[n])
@@ -82,7 +82,7 @@ import sys
import urllib.error
import urllib.parse
import urllib.request
from datetime import datetime, timedelta, timezone
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
+3 -3
View File
@@ -338,7 +338,7 @@ def compute_ack_state(
# Filter out self-acks and unknown slugs.
ackers_per_slug: dict[str, list[str]] = {s: [] for s in items_by_slug}
rejected_self: dict[str, list[str]] = {s: [] for s in items_by_slug}
rejected_unknown: dict[str, list[str]] = {s: [] for s in items_by_slug}
_rejected_unknown: dict[str, list[str]] = {s: [] for s in items_by_slug}
pending_team_check: dict[str, list[str]] = {s: [] for s in items_by_slug}
for (user, slug), kind in latest_directive.items():
@@ -842,7 +842,7 @@ def render_status(
def get_tier_mode(pr: dict[str, Any], cfg: dict[str, Any]) -> str:
"""Read tier label, return 'hard' or 'soft' per cfg.tier_failure_mode."""
labels = pr.get("labels") or []
tier_labels = [l.get("name", "") for l in labels if (l.get("name", "") or "").startswith("tier:")]
tier_labels = [lbl.get("name", "") for lbl in labels if (lbl.get("name", "") or "").startswith("tier:")]
mode_map = cfg.get("tier_failure_mode") or {}
default_mode = cfg.get("default_mode", "hard")
for tl in tier_labels:
@@ -865,7 +865,7 @@ def is_high_risk(pr: dict[str, Any], cfg: dict[str, Any]) -> bool:
Governance fix for internal#442 — closes the inconsistency between
sop-tier-check (tier-aware) and sop-checklist (was tier-blind).
"""
label_set = {(l.get("name") or "") for l in (pr.get("labels") or [])}
label_set = {(lbl.get("name") or "") for lbl in (pr.get("labels") or [])}
if "tier:high" in label_set:
return True
high_risk_labels = set(cfg.get("high_risk_labels") or [])
@@ -81,7 +81,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
# GET /repos/{owner}/{name}/pulls/{pr_number}
m = re.match(r"^/api/v1/repos/([^/]+)/([^/]+)/pulls/(\d+)$", path)
if m:
owner, name, pr_num = m.group(1), m.group(2), m.group(3)
_owner, _name, pr_num = m.group(1), m.group(2), m.group(3)
if sc == "T2_pr_closed":
return self._json(200, {
"number": int(pr_num),
@@ -151,7 +151,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
# GET /teams/{team_id}/members/{username}
m = re.match(r"^/api/v1/teams/(\d+)/members/([^/]+)$", path)
if m:
team_id, login = m.group(1), m.group(2)
_team_id, login = m.group(1), m.group(2)
if sc == "T8_team_not_member":
return self._empty(404)
if sc == "T9_team_403":
@@ -15,7 +15,6 @@ Mirrors the pattern in scripts/ops/test_check_migration_collisions.py
from __future__ import annotations
import importlib.util
import os
import sys
import unittest
from pathlib import Path
@@ -22,7 +22,6 @@ from __future__ import annotations
import os
import sys
import tempfile
import unittest
# Resolve sibling script regardless of where pytest is invoked from.