Skip to content

Commit 911807d

Browse files
committed
fix(cli_audit): filter pre-release Python versions from Atom feed
- Add pre-release filtering for Python in Atom feed fallback - Filter out alpha, beta, rc versions (e.g., v3.15.0a1, v3.14.0rc3) - Pick highest stable version by semantic version comparison - Fixes issue where Python 3.15.0a1 (alpha) was detected as latest - Now correctly identifies 3.14.0 as latest stable version The Atom feed fallback is used when GitHub API is rate-limited. Without this fix, pre-release versions would be treated as stable upgrades, prompting users to install alpha/beta Python versions.
1 parent e45af68 commit 911807d

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

cli_audit.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,14 +2134,40 @@ def latest_github(owner: str, repo: str) -> tuple[str, str]:
21342134
pass
21352135
try:
21362136
atom = http_get(f"https://github.com/{owner}/{repo}/releases.atom").decode("utf-8", "ignore")
2137-
m = re.search(r"/releases/tag/([^<\"]+)", atom)
2138-
if m:
2139-
tag = normalize_version_tag(m.group(1).strip())
2140-
if tag and tag.lower() not in ("releases", "latest"):
2141-
result = (tag, extract_version_number(tag))
2137+
# For Python, filter out pre-release tags (alpha, beta, rc) from atom feed
2138+
if owner == "python" and repo == "cpython":
2139+
# Find all stable tags in atom feed and pick the highest version
2140+
best: tuple[tuple[int, ...], str, str] | None = None
2141+
for match in re.finditer(r"/releases/tag/([^<\"]+)", atom):
2142+
tag = normalize_version_tag(match.group(1).strip())
2143+
# Accept only stable final release tags like v3.14.0 or v3.12.7
2144+
# Exclude rc, alpha, beta, a, b suffixes
2145+
if tag and re.match(r"^v\d+\.\d+\.\d+$", tag):
2146+
ver = extract_version_number(tag)
2147+
if ver:
2148+
try:
2149+
nums = tuple(int(x) for x in ver.split("."))
2150+
tup = (nums, tag, ver)
2151+
if best is None or tup[0] > best[0]:
2152+
best = tup
2153+
except Exception:
2154+
continue
2155+
if best is not None:
2156+
_, tag, ver = best
2157+
result = (tag, ver)
21422158
set_manual_latest(repo, tag)
2143-
set_hint(f"gh:{owner}/{repo}", "atom")
2159+
set_hint(f"gh:{owner}/{repo}", "atom_filtered")
21442160
return result
2161+
else:
2162+
# For other repos, take first tag from atom feed
2163+
m = re.search(r"/releases/tag/([^<\"]+)", atom)
2164+
if m:
2165+
tag = normalize_version_tag(m.group(1).strip())
2166+
if tag and tag.lower() not in ("releases", "latest"):
2167+
result = (tag, extract_version_number(tag))
2168+
set_manual_latest(repo, tag)
2169+
set_hint(f"gh:{owner}/{repo}", "atom")
2170+
return result
21452171
except Exception:
21462172
pass
21472173
return "", ""

0 commit comments

Comments
 (0)