From 99ba6f69c413608c9c79f461045e411d68dc7af7 Mon Sep 17 00:00:00 2001 From: Ivan Yang Date: Mon, 24 Aug 2026 10:21:59 -0700 Subject: [PATCH] fix: make check_copyright_year run on Python 3.9 Line 21 annotates `-> int | None`. PEP 604 unions in an annotation are evaluated at import time before 3.10, so on 3.9 the module raises TypeError before it checks anything: def git_last_modified_year(path: Path) -> int | None: TypeError: unsupported operand type(s) for |: 'type' and 'NoneType' `from __future__ import annotations` defers annotation evaluation, which is what the other local hook scripts already do (check_lfs_pointers.py:6). This has been silent since the script landed, for two compounding reasons: the workflow sets SKIP: check-copyright-year, so CI never runs it, and anyone whose python3 is 3.10 or newer sees it pass. Only a 3.9 contributor hits it, and the hook fails open from their point of view -- it never reports a stale year because it never starts. Tested: python3.9.6 and python3.12.13, plain and --fix, plus `pre-commit run` over the changed file. Before the change 3.9 raises and 3.12 passes; after it, both pass. Note for whoever merges: with the hook running again, `--all-files` now wants to update the year on ~101 files that drifted while it was dead. That backlog is deliberately not in this commit -- it is a separate, reviewable change. Signed-off-by: Ivan Yang --- scripts/check_copyright_year.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/check_copyright_year.py b/scripts/check_copyright_year.py index fe8c6b8c9a..c22feb8624 100644 --- a/scripts/check_copyright_year.py +++ b/scripts/check_copyright_year.py @@ -4,6 +4,8 @@ """Check that SPDX-FileCopyrightText year includes the last-modified year (from git). Use --fix to update. Falls back to current year if not in a git repo.""" +from __future__ import annotations + import os import re import subprocess