Spaces:
Running
Running
Download code/bucket.py from ArthurZ/transformers-triage: direct link, hf CLI and curl.
- Browser
- Download file 3.5 kB
-
https://huggingface.co/spaces/ArthurZ/transformers-triage/resolve/main/code/bucket.py
- Command line
-
hf download hf://spaces/ArthurZ/transformers-triage/code/bucket.py
-
curl -L -o bucket.py https://huggingface.co/spaces/ArthurZ/transformers-triage/resolve/main/code/bucket.py
3.5 kB
| import json, re, subprocess, sys | |
| from collections import Counter | |
| from datetime import datetime, timezone | |
| prs = json.load(open(sys.argv[1])) | |
| closed = set(int(l.split()[0]) for l in open("close_fail.log")) if False else set() | |
| done = set(int(m) for m in re.findall(r"close (\d+)", open("cmds.sh").read())) | |
| main = set(subprocess.run(["git", "-C", "/Users/arthurzucker/Work/transformers", "ls-tree", "-r", "--name-only", "origin/main"], | |
| capture_output=True, text=True).stdout.split()) | |
| NOW = datetime(2026, 10, 20, tzinfo=timezone.utc) | |
| age = lambda s: (NOW - datetime.fromisoformat(s.replace("Z", "+00:00"))).days | |
| PHIL = [(re.compile(r"modeling_(tf|flax)_|_tf_utils|_flax_utils|/tf_|/flax_"), "TF/Flax code (removed in v5)"), | |
| (re.compile(r"^examples/research_projects/|^examples/legacy/|^templates/|^examples/(tensorflow|flax)/"), "removed/legacy examples or templates"), | |
| (re.compile(r"^src/transformers/models/deprecated/"), "deprecated model"), | |
| (re.compile(r"^src/transformers/(benchmark|onnx|commands/(pt_to_tf|convert))/"), "removed subsystem (benchmark/onnx/pt_to_tf)")] | |
| out = [] | |
| for p in prs: | |
| if p["number"] in done: continue | |
| files = [f["path"] for f in p["files"]["nodes"]] | |
| last_commit = age(p["commits"]["nodes"][0]["commit"]["committedDate"]) if p["commits"]["nodes"] else 9999 | |
| upd = age(p["updatedAt"]) | |
| # new modeling files added count as present only if PR adds them; missing = existing-path edits that vanished | |
| missing = [f for f in files if f not in main and not re.search(r"models/[^/]+/(modeling|modular|configuration|processing|image_processing|tokenization|convert)_|^tests/models/|^docs/", f)] | |
| reasons, cats = [], set() | |
| if p["baseRefName"] != "main": | |
| cats.add("old_branch"); reasons.append(f"base branch is `{p['baseRefName']}`") | |
| if files and len(missing) / len(files) >= 0.5: | |
| cats.add("old_branch"); reasons.append(f"{len(missing)}/{len(files)} touched files no longer exist on main") | |
| for rx, why in PHIL: | |
| hits = [f for f in files if rx.search(f)] | |
| if hits: cats.add("philosophy"); reasons.append(f"{why}: {hits[0]}" + (f" (+{len(hits)-1})" if len(hits) > 1 else "")) | |
| if last_commit > 365 and upd > 90: | |
| cats.add("outdated"); reasons.append(f"last commit {last_commit}d ago, last activity {upd}d ago") | |
| elif p["mergeable"] == "CONFLICTING" and last_commit > 180 and upd > 60: | |
| cats.add("outdated"); reasons.append(f"merge conflicts, last commit {last_commit}d ago") | |
| if cats: | |
| out.append({"number": p["number"], "title": p["title"], "author": (p["author"] or {}).get("login"), | |
| "assoc": p["authorAssociation"], "draft": p["isDraft"], "base": p["baseRefName"], | |
| "mergeable": p["mergeable"], "review": p["reviewDecision"], "created": p["createdAt"][:10], | |
| "last_commit_days": last_commit, "updated_days": upd, "labels": [l["name"] for l in p["labels"]["nodes"]], | |
| "files": files[:15], "nfiles": p["files"]["totalCount"], "cats": sorted(cats), "signals": reasons, | |
| "last_comments": [{"by": (c["author"] or {}).get("login"), "assoc": c["authorAssociation"], "at": c["createdAt"][:10], "text": c["body"][:300]} for c in p["comments"]["nodes"]]}) | |
| json.dump(out, open(sys.argv[2], "w"), indent=1) | |
| print(len(prs), "open PRs ->", len(out), "flagged;", Counter(c for o in out for c in o["cats"])) | |
| print("assoc:", Counter(o["assoc"] for o in out)) | |