#!/usr/bin/env python3 """Bump all pinned versions in requirements*.txt to latest from PyPI.""" import json import re import urllib.request from pathlib import Path REQS = sorted(Path().glob("requirements*.txt")) PYPI = "https://pypi.org/pypi/{}/json" def latest_version(package: str) -> str | None: url = PYPI.format(package) try: with urllib.request.urlopen(url, timeout=10) as resp: data = json.load(resp) return data["info"]["version"] except Exception: return None def bump_file(path: Path): lines = path.read_text().splitlines() changed = [] for line in lines: m = re.match(r"^([\w-]+(?:\[[\w-]+])?)==[\w.]+$", line) if m: pkg = m.group(1) latest = latest_version(pkg) if latest: changed.append(f"{pkg}=={latest}") if f"{pkg}=={latest}" != line: print(f" {pkg}: {line.split('==')[1]} -> {latest}") else: changed.append(line) print(f" {pkg}: failed to fetch, keeping current") else: changed.append(line) path.write_text("\n".join(changed) + "\n") def main(): for req in REQS: print(f"\n{req}:") bump_file(req) if __name__ == "__main__": main()