docs: test_doc_build: better handle python version

Make the python version logic more generic to allow adding more
python degradation changes on more recent Sphinx tools.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Message-ID: <871255ee391ceae0d24ed18f31c1e91589d139c7.1792053090.git.mchehab+huawei@kernel.org>
This commit is contained in:
Mauro Carvalho Chehab 2026-10-15 10:57:18 +02:00 committed by Jonathan Corbet
parent f000a06da2
commit 5a5021d08b

View File

@ -11,29 +11,47 @@ and optionally test the build.
import argparse
import asyncio
import glob
import os.path
import shutil
import re
import sys
import time
import subprocess
# Minimal python version supported by the building system.
MIN_PYTHON_SUBVER = 9 # Currently, Python 3.9 is the minimal supported version
PYTHON = os.path.basename(sys.executable)
RE_VERSION = re.compile(r"python3\.\d+$")
min_python_bin = None
for i in range(9, 13):
p = f"python3.{i}"
if shutil.which(p):
min_python_bin = p
break
def get_min_python_bin(min_subver):
"""Get minimal python binary since 3.MIN_PYTHON_SUBVER"""
bins = set()
if not min_python_bin:
min_python_bin = PYTHON
paths = os.environ.get("PATH", "").split(os.pathsep)
for d in paths:
for p in glob.glob(os.path.join(d, "python3.[0-9]*")):
if not RE_VERSION.search(p):
continue
# Starting from 8.0, Python 3.9 is not supported anymore.
PYTHON_VER_CHANGES = {(8, 0, 0): PYTHON}
ver = int(p.split(".")[1])
if ver < min_subver:
continue
if os.path.isfile(p) and os.access(p, os.X_OK):
bins.add(p)
if not bins:
return None
return sorted(bins, key=lambda x: (3, int(x.split(".")[1])))[0]
# Minimal python versions. Please notice that for 3.4.3, older python
# versions would work with Sphinx, but kernel doc build is not compatible
# with them anymore, due to Sphinx extensions and kernel-doc.
PYTHON_VER_CHANGES = {
(3, 4, 3): (3, MIN_PYTHON_SUBVER),
(8, 0, 0): (3, 10),
}
DEFAULT_VERSIONS_TO_TEST = [
(3, 4, 3), # Minimal supported version
@ -173,7 +191,7 @@ class AsyncCommands:
self.output = None
self.fp = fp
def log(self, out, verbose, is_info=True):
def log(self, out, verbose=True, is_info=True):
out = out.removesuffix('\n')
if verbose:
@ -362,8 +380,19 @@ class SphinxVenv:
if not args.verbose:
args.verbose = True
cmd = AsyncCommands(fp)
cur_requirements = {}
python_bin = min_python_bin
python_bin = get_min_python_bin(MIN_PYTHON_SUBVER)
if not python_bin:
python_bin = os.path.basename(sys.executable)
python_ver = tuple(sys.version_info[:2])
if python_ver < (3, MIN_PYTHON_SUBVER):
sys.exit(f"Python {python_ver[0]}.{python_ver[1]} is too old.")
else:
ver = int(python_bin.split(".")[1])
python_ver = tuple([3, ver])
vers = set(SPHINX_REQUIREMENTS.keys()) | set(args.versions)
@ -372,8 +401,14 @@ class SphinxVenv:
new_reqs = SPHINX_REQUIREMENTS[cur_ver]
cur_requirements.update(new_reqs)
if cur_ver in PYTHON_VER_CHANGES: # pylint: disable=R1715
python_bin = PYTHON_VER_CHANGES[cur_ver]
if cur_ver in PYTHON_VER_CHANGES:
new_ver = PYTHON_VER_CHANGES[cur_ver]
if python_ver < new_ver:
python_bin = get_min_python_bin(new_ver[1])
if not python_bin:
cmd.log(f"Can't check {cur_ver}: {python_bin} not found.")
break
if cur_ver not in args.versions:
continue
@ -390,7 +425,6 @@ class SphinxVenv:
python_bin)
if args.build:
cmd = AsyncCommands(fp)
cmd.log("\nSummary:", verbose=True)
for ver, elapsed_time in sorted(self.built_time.items()):
cmd.log(f"\tSphinx {ver} elapsed time: {elapsed_time}",