import argparse import re import sys import tomllib from pathlib import Path class ValidationError(Exception): pass def check(github_ref: str | None) -> None: pyproject = Path(__file__).parent.parent / "pyproject.toml" if not pyproject.exists(): raise ValidationError("pyproject.toml not found") with pyproject.open("rb") as f: data = tomllib.load(f) pyproject_version = data["project"]["version"] if github_ref is not None and github_ref.startswith("refs/tags/"): version = github_ref.removeprefix("refs/tags/") if version != pyproject_version: raise ValidationError( f"Version mismatch: GitHub ref is {version}, " f"but pyproject.toml is {pyproject_version}" ) requires_python = data["project"]["requires-python"] assert sys.version_info[0] == 3, "Rewrite this script when Python 4 comes out" match = re.fullmatch(r">=3\.(\d+)", requires_python) if not match: raise ValidationError(f"Invalid requires-python: {requires_python!r}") lowest_minor = int(match.group(1)) description = data["project"]["description"] if not description.endswith(f"3.{lowest_minor}+"): raise ValidationError(f"Description should mention Python 3.{lowest_minor}+") classifiers = set(data["project"]["classifiers"]) for should_be_supported in range(lowest_minor, sys.version_info[1] + 1): if ( f"Programming Language :: Python :: 3.{should_be_supported}" not in classifiers ): raise ValidationError( f"Missing classifier for Python 3.{should_be_supported}" ) if __name__ == "__main__": parser = argparse.ArgumentParser("Script to check the package metadata") parser.add_argument( "github_ref", type=str, help="The current GitHub ref", nargs="?" ) args = parser.parse_args() try: check(args.github_ref) except ValidationError as e: print(e) sys.exit(1)