fix(ci): make no-new-getattr guard stable in shallow PR checkouts (#38480)

Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2026-07-08 06:22:59 +00:00
1 parent af4538e942
commit 98f67e9c82
4 files changed
+196 -100

No files matched your search

+15 -14
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Block net-new getattr() usage in changed Python hunks."""
"""Block net-new getattr() usage in staged changes or against an explicit base revision."""
from __future__ import annotations
@@ -58,8 +58,16 @@ class Violation:
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--mode", choices=("pre-commit", "ci"), required=True)
parser.add_argument("--merge-target", default="main")
diff_source_group = parser.add_mutually_exclusive_group(required=True)
diff_source_group.add_argument(
"--staged",
action="store_true",
help="Inspect staged changes against HEAD, for pre-commit style usage.",
)
diff_source_group.add_argument(
"--base-rev",
help="Inspect changes between the provided git revision and HEAD.",
)
return parser.parse_args()
@@ -86,21 +94,15 @@ def git_output(*args: str, allow_missing: bool = False) -> str:
raise RuntimeError(completed.stderr.strip() or completed.stdout.strip() or "git command failed")
def resolve_ci_base(merge_target: str) -> str:
merge_base = git_output("merge-base", merge_target, "HEAD", allow_missing=True).strip()
return merge_base or merge_target
def collect_diff_text(args: argparse.Namespace) -> str:
if args.mode == "pre-commit":
if args.staged:
return git_output("diff", "--cached", "--unified=0", "--diff-filter=AM", "--no-ext-diff")
compare_base = resolve_ci_base(args.merge_target)
return git_output(
"diff",
"--unified=0",
"--diff-filter=AM",
"--no-ext-diff",
f"{compare_base}..HEAD",
f"{args.base_rev}..HEAD",
)
@@ -145,15 +147,14 @@ def is_python_source_path(path: str) -> bool:
def load_file_versions(path: str, args: argparse.Namespace) -> tuple[str, str]:
if args.mode == "pre-commit":
if args.staged:
return (
git_output("show", f"HEAD:{path}", allow_missing=True),
git_output("show", f":{path}"),
)
compare_base = resolve_ci_base(args.merge_target)
return (
git_output("show", f"{compare_base}:{path}", allow_missing=True),
git_output("show", f"{args.base_rev}:{path}", allow_missing=True),
git_output("show", f"HEAD:{path}"),
)