From 17ab862169b34e29d8ad606b9cd874fbf9bf9aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 3 Jun 2025 11:00:16 +0200 Subject: [PATCH] scripts: ci: add vermin (min python version check) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a compliance check that allows to flag when a given file requires a Python version higher than 3.10 (minimum supported version in Zephyr at the time of writing) since not all Python scripts are tested against 3.10 in CI and we want to avoid introducing changes that could break users. Signed-off-by: Benjamin Cabé --- .gitignore | 1 + scripts/ci/check_compliance.py | 60 +++++++++++++++++++++++++++++ scripts/requirements-actions.in | 1 + scripts/requirements-actions.txt | 4 ++ scripts/requirements-compliance.txt | 1 + 5 files changed, 67 insertions(+) diff --git a/.gitignore b/.gitignore index aab3981f52f..c24356df575 100644 --- a/.gitignore +++ b/.gitignore @@ -102,6 +102,7 @@ MaintainersFormat.txt ModulesMaintainers.txt Nits.txt Pylint.txt +PythonCompat.txt Ruff.txt SphinxLint.txt SysbuildKconfig.txt diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index cd97ea96717..88bb50f871a 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -1815,6 +1815,66 @@ class Ruff(ComplianceTest): desc = f"Run 'ruff format {file}'" self.fmtd_failure("error", "Python format error", file, desc=desc) +class PythonCompatCheck(ComplianceTest): + """ + Python Compatibility Check + """ + name = "PythonCompat" + doc = "Check that Python files are compatible with Zephyr minimum supported Python version." + + MAX_VERSION = (3, 10) + MAX_VERSION_STR = f"{MAX_VERSION[0]}.{MAX_VERSION[1]}" + + def run(self): + py_files = [f for f in get_files(filter="d") if f.endswith(".py")] + if not py_files: + return + cmd = ["vermin", "-f", "parsable", "--violations", + f"-t={self.MAX_VERSION_STR}", "--no-make-paths-absolute"] + py_files + try: + result = subprocess.run(cmd, + check=False, + capture_output=True, + cwd=GIT_TOP) + except Exception as ex: + self.error(f"Failed to run vermin: {ex}") + output = result.stdout.decode("utf-8") + failed = False + for line in output.splitlines(): + parts = line.split(":") + if len(parts) < 6: + continue + filename, line_number, column, _, py3ver, feature = parts[:6] + if not line_number: + # Ignore all file-level messages + continue + + desc = None + if py3ver.startswith('!'): + desc = f"{feature} is known to be incompatible with Python 3." + elif py3ver.startswith('~'): + # "no known reason it won't work", just skip + continue + else: + major, minor = map(int, py3ver.split(".")[:2]) + if (major, minor) > self.MAX_VERSION: + desc = f"{feature} requires Python {major}.{minor}, which is higher than " \ + f"Zephyr's minimum supported Python version ({self.MAX_VERSION_STR})." + + if desc is not None: + self.fmtd_failure( + "error", + "PythonCompat", + filename, + line=int(line_number), + col=int(column) if column else None, + desc=desc, + ) + failed = True + if failed: + self.failure("Some Python files use features that are not compatible with Python " \ + f"{self.MAX_VERSION_STR}.") + class TextEncoding(ComplianceTest): """ diff --git a/scripts/requirements-actions.in b/scripts/requirements-actions.in index bf4a50e2aa2..2094546f423 100644 --- a/scripts/requirements-actions.in +++ b/scripts/requirements-actions.in @@ -35,6 +35,7 @@ tabulate tomli>=1.1.0 tox unidiff +vermin west>=0.14.0 xlsxwriter yamllint diff --git a/scripts/requirements-actions.txt b/scripts/requirements-actions.txt index b1997b68439..065d5992399 100644 --- a/scripts/requirements-actions.txt +++ b/scripts/requirements-actions.txt @@ -1235,6 +1235,10 @@ urllib3==2.4.0 \ # elastic-transport # pygithub # requests +vermin==1.6.0 \ + --hash=sha256:6266ca02f55d1c2aa189a610017c132eb2d1934f09e72a955b1eb3820ee6d4ef \ + --hash=sha256:f1fa9ee40f59983dc40e0477eb2b1fa8061a3df4c3b2bcf349add462a5610efb + # via -r requirements-actions.in virtualenv==20.31.2 \ --hash=sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11 \ --hash=sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af diff --git a/scripts/requirements-compliance.txt b/scripts/requirements-compliance.txt index a7134e7ff00..19bdcb3071f 100644 --- a/scripts/requirements-compliance.txt +++ b/scripts/requirements-compliance.txt @@ -13,5 +13,6 @@ python-magic; sys_platform != "win32" ruff==0.11.11 sphinx-lint unidiff +vermin yamllint # zephyr-keep-sorted-stop