From f089bd5f74e759f7af6dbf36ccd94fdf73f77169 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 25 Oct 2025 15:51:55 +0300 Subject: [PATCH] Default EOL to end of month in SVG --- _tools/generate_release_cycle.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/_tools/generate_release_cycle.py b/_tools/generate_release_cycle.py index 63d98cfce..dd0a3a7c6 100644 --- a/_tools/generate_release_cycle.py +++ b/_tools/generate_release_cycle.py @@ -3,6 +3,7 @@ from __future__ import annotations import argparse +import calendar import csv import datetime as dt import json @@ -18,10 +19,17 @@ def csv_date(date_str: str, now_str: str) -> str: return date_str -def parse_date(date_str: str) -> dt.date: +def parse_date(date_str: str, *, last: bool = False) -> dt.date: if len(date_str) == len("yyyy-mm"): # We need a full yyyy-mm-dd, so let's approximate - return dt.date.fromisoformat(date_str + "-01") + if last: + # Last day of month + year, month = map(int, date_str.split("-")) + last_day = calendar.monthrange(year, month)[1] + return dt.date(year, month, last_day) + else: + return dt.date.fromisoformat(date_str + "-01") + return dt.date.fromisoformat(date_str) @@ -46,7 +54,7 @@ def __init__(self, *, limit_to_active=False, special_py27=False) -> None: full_years = 1.5 version["first_release_date"] = r1 = parse_date(version["first_release"]) version["start_security_date"] = r1 + dt.timedelta(days=full_years * 365) - version["end_of_life_date"] = parse_date(version["end_of_life"]) + version["end_of_life_date"] = parse_date(version["end_of_life"], last=True) self.cutoff = min(ver["first_release_date"] for ver in self.versions.values())