diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ae27fd1f2..c5beee4a3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,14 +7,12 @@ repos: args: [--exit-non-zero-on-fix] - id: ruff-format name: Run Ruff (format) - args: [--check] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: - id: check-case-conflict - id: check-merge-conflict - - id: check-json - id: check-yaml - id: debug-statements - id: end-of-file-fixer diff --git a/Makefile b/Makefile index 3d485ae2d..a3e176438 100644 --- a/Makefile +++ b/Makefile @@ -103,15 +103,20 @@ _ensure-pre-commit: lint: _ensure-pre-commit $(VENVDIR)/bin/python3 -m pre_commit run --all-files -# Defined so that "include/release-cycle.json" -# doesn't fall through to the catch-all target. -include/release-cycle.json: - @exit - -$(_RELEASE_CYCLE): include/release-cycle.json +# Generate all release cycle files together with a single script invocation +# Use branches.csv as the primary target, others depend on it +include/branches.csv: $(VENVDIR)/bin/python3 _tools/generate_release_cycle.py @echo Release cycle data generated. +# Other files are generated together with branches.csv +include/end-of-life.csv: include/branches.csv + @: +include/release-cycle-all.svg: include/branches.csv + @: +include/release-cycle.svg: include/branches.csv + @: + # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. .PHONY: Makefile diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py index dd0a3a7c6..f9df49bab 100644 --- a/_tools/generate_release_cycle.py +++ b/_tools/generate_release_cycle.py @@ -7,6 +7,9 @@ import csv import datetime as dt import json +from functools import cache +from pathlib import Path +from urllib.request import urlopen import jinja2 @@ -37,12 +40,17 @@ def parse_version(ver: str) -> list[int]: return [int(i) for i in ver["key"].split(".")] +@cache +def get_versions() -> str: + with urlopen("https://peps.python.org/api/release-cycle.json") as in_file: + return json.loads(in_file.read().decode("utf-8")) + + class Versions: """For converting JSON to CSV and SVG.""" def __init__(self, *, limit_to_active=False, special_py27=False) -> None: - with open("include/release-cycle.json", encoding="UTF-8") as in_file: - self.versions = json.load(in_file) + self.versions = get_versions() # Generate a few additional fields for key, version in self.versions.items(): @@ -197,6 +205,8 @@ def main() -> None: versions = Versions() assert len(versions.versions) > 10 + Path("include").mkdir(exist_ok=True) + versions.write_csv() versions.write_svg(args.today, "include/release-cycle-all.svg") diff --git a/conf.py b/conf.py index 0f6a820d8..c80797621 100644 --- a/conf.py +++ b/conf.py @@ -1,4 +1,5 @@ import json +from urllib.request import urlopen extensions = [ 'notfound.extension', @@ -178,8 +179,8 @@ # Dynamically expose the Python version associated with the "main" branch. # Exactly one entry in ``release-cycle.json`` should have ``"branch": "main"``. -with open("include/release-cycle.json", encoding="UTF-8") as _f: - _cycle = json.load(_f) +with urlopen("https://peps.python.org/api/release-cycle.json") as _f: + _cycle = json.loads(_f.read().decode("utf-8")) _main_version = next( version for version, data in _cycle.items() if data.get("branch") == "main" diff --git a/include/release-cycle.json b/include/release-cycle.json deleted file mode 100644 index 26436bf00..000000000 --- a/include/release-cycle.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "3.15": { - "branch": "main", - "pep": 790, - "status": "feature", - "first_release": "2026-10-01", - "end_of_life": "2031-10", - "release_manager": "Hugo van Kemenade" - }, - "3.14": { - "branch": "3.14", - "pep": 745, - "status": "bugfix", - "first_release": "2025-10-07", - "end_of_life": "2030-10", - "release_manager": "Hugo van Kemenade" - }, - "3.13": { - "branch": "3.13", - "pep": 719, - "status": "bugfix", - "first_release": "2024-10-07", - "end_of_life": "2029-10", - "release_manager": "Thomas Wouters" - }, - "3.12": { - "branch": "3.12", - "pep": 693, - "status": "security", - "first_release": "2023-10-02", - "end_of_life": "2028-10", - "release_manager": "Thomas Wouters" - }, - "3.11": { - "branch": "3.11", - "pep": 664, - "status": "security", - "first_release": "2022-10-24", - "end_of_life": "2027-10", - "release_manager": "Pablo Galindo Salgado" - }, - "3.10": { - "branch": "3.10", - "pep": 619, - "status": "security", - "first_release": "2021-10-04", - "end_of_life": "2026-10", - "release_manager": "Pablo Galindo Salgado" - }, - "3.9": { - "branch": "3.9", - "pep": 596, - "status": "end-of-life", - "first_release": "2020-10-05", - "end_of_life": "2025-10-31", - "release_manager": "Łukasz Langa" - }, - "3.8": { - "branch": "3.8", - "pep": 569, - "status": "end-of-life", - "first_release": "2019-10-14", - "end_of_life": "2024-10-07", - "release_manager": "Łukasz Langa" - }, - "3.7": { - "branch": "3.7", - "pep": 537, - "status": "end-of-life", - "first_release": "2018-06-27", - "end_of_life": "2023-06-27", - "release_manager": "Ned Deily" - }, - "3.6": { - "branch": "3.6", - "pep": 494, - "status": "end-of-life", - "first_release": "2016-12-23", - "end_of_life": "2021-12-23", - "release_manager": "Ned Deily" - }, - "3.5": { - "branch": "3.5", - "pep": 478, - "status": "end-of-life", - "first_release": "2015-09-13", - "end_of_life": "2020-09-30", - "release_manager": "Larry Hastings" - }, - "3.4": { - "branch": "3.4", - "pep": 429, - "status": "end-of-life", - "first_release": "2014-03-16", - "end_of_life": "2019-03-18", - "release_manager": "Larry Hastings" - }, - "3.3": { - "branch": "3.3", - "pep": 398, - "status": "end-of-life", - "first_release": "2012-09-29", - "end_of_life": "2017-09-29", - "release_manager": "Georg Brandl, Ned Deily (3.3.7+)" - }, - "3.2": { - "branch": "3.2", - "pep": 392, - "status": "end-of-life", - "first_release": "2011-02-20", - "end_of_life": "2016-02-20", - "release_manager": "Georg Brandl" - }, - "2.7": { - "branch": "2.7", - "pep": 373, - "status": "end-of-life", - "first_release": "2010-07-03", - "end_of_life": "2020-01-01", - "release_manager": "Benjamin Peterson" - }, - "3.1": { - "branch": "3.1", - "pep": 375, - "status": "end-of-life", - "first_release": "2009-06-27", - "end_of_life": "2012-04-09", - "release_manager": "Benjamin Peterson" - }, - "3.0": { - "branch": "3.0", - "pep": 361, - "status": "end-of-life", - "first_release": "2008-12-03", - "end_of_life": "2009-06-27", - "release_manager": "Barry Warsaw" - }, - "2.6": { - "branch": "2.6", - "pep": 361, - "status": "end-of-life", - "first_release": "2008-10-01", - "end_of_life": "2013-10-29", - "release_manager": "Barry Warsaw" - } -}