From 16b0924e3450085659dfaeeab2e92e02c4b15506 Mon Sep 17 00:00:00 2001 From: t Date: Tue, 10 Nov 2026 06:13:36 -0400 Subject: [PATCH] cmake: find the Python3 interpreter before the first add_test uses it, and pin the order (fixes #1864) `find_package(Python3 COMPONENTS Interpreter)` sat at :761 while **nine** registrations above it expanded `${Python3_EXECUTABLE}` to the empty string, so `CTestTestfile.cmake` held e.g. ``` add_test([=[hrx_build_scope]=] "/tools/ci/hrx_build_scope.py" "--self-test") ``` -- the script as the program. Those tests ran only through their **exec bit**, which is why a mode-only rewrite of `tools/ci/hrx_build_scope.py` (100755 -> 100644, no content change) turned the row into `BAD_COMMAND`. The interpreter is now found once, above the first user, and the registrations go through one place: ```cmake find_package(Python3 COMPONENTS Interpreter) function(add_python_test name) if(Python3_Interpreter_FOUND) add_test(NAME ${name} COMMAND ${Python3_EXECUTABLE} ${ARGN}) else() message(STATUS "ctest: not registering ${name} (no Python3 interpreter)") endif() endfunction() ``` Nine registrations used the variable and now use the helper; the second `find_package` (and its now-redundant guard comment) is gone, since the later block is still guarded by `Python3_Interpreter_FOUND`. **Why a helper and not just moving the find_package:** moving it fixes today's nine and leaves the next `add_test` above it free to repeat the bug, and it does nothing for a machine without Python3, where an empty interpreter makes ctest hand a `.py` to the kernel as a program. The helper makes both impossible by construction. ## The rule is now checked, on the file, with no configure `tests/python_test_order_check.py` (`--check --root`, `--self-test`) requires every `${Python3_EXECUTABLE}` use to follow the first `find_package(Python3` in each `CMakeLists.txt`, and is registered twice like the other `*_check.py` pairs. Against `origin/main` it reports **exactly the nine the issue counted**: ``` main offenders: [282, 283, 287, 288, 295, 303, 705, 707, 712] ``` and against this head, none. Its own comment mentions the variable, so the checker strips comments first -- with a self-test case for that, because a checker that trips on the prose explaining it would be switched off in a week. ## Verified ``` cmake -S . -B -> rc 0 CTestTestfile.cmake BEFORE: add_test([=[hrx_build_scope]=] "/tools/ci/hrx_build_scope.py" "--self-test") CTestTestfile.cmake AFTER : add_test([=[hrx_build_scope]=] "/home/bcloud/.local/bin/python3.14" "/... " "--self-test") chmod -x tools/ci/hrx_build_scope.py;