From 083f392bb0d1a1a6d224119a0c452a896b0c6d11 Mon Sep 17 00:00:00 2001 From: matthewmcneill <97467074+matthewmcneill@users.noreply.github.com> Date: Sun, 26 Apr 2026 13:10:42 +0100 Subject: [PATCH 1/2] fix: enforce strict python baseline < 3.13 --- src/installer/get-python.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/installer/get-python.js b/src/installer/get-python.js index 85cf046..ae3ec53 100644 --- a/src/installer/get-python.js +++ b/src/installer/get-python.js @@ -116,6 +116,20 @@ export async function findPythonExecutable() { fs.existsSync(executable) && (await callInstallerScript(executable, ['check', 'python'])) ) { + // Verify Python version does not exceed maximum stable baseline (e.g., < 3.13) + try { + const versionCheck = await proc.getCommandOutput(executable, [ + '-c', + 'import sys; print("1" if sys.version_info < (3, 13) else "0")' + ]); + if (versionCheck.trim() !== '1') { + console.warn(`Python at ${executable} exceeds max supported version (>= 3.13)`); + continue; // Reject bleeding edge and force fallback loop + } + } catch (err) { + console.warn(`Failed to verify Python version structure for ${executable}:`, err); + continue; + } return executable; } } catch (err) { From 853f784f3ab1df583c39912dfba8261f2c88ea85 Mon Sep 17 00:00:00 2001 From: matthewmcneill <97467074+matthewmcneill@users.noreply.github.com> Date: Mon, 27 Apr 2026 11:09:52 +0100 Subject: [PATCH 2/2] Refactor Python version check to be configurable --- .gitignore | 1 + src/installer/get-python.js | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 34c6b93..675f3fa 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules dist yarn.lock package-lock.json +platformio-node-helpers-11.3.0.tgz diff --git a/src/installer/get-python.js b/src/installer/get-python.js index ae3ec53..abac2a9 100644 --- a/src/installer/get-python.js +++ b/src/installer/get-python.js @@ -104,7 +104,8 @@ jjxDah2nGN59PRbxYvnKkKj9 -----END CERTIFICATE----- `; -export async function findPythonExecutable() { +export async function findPythonExecutable(options = {}) { + const maxPythonVersion = options.maxPythonVersion || process.env.PLATFORMIO_MAX_PYTHON_VERSION || '3.13'; const exenames = proc.IS_WINDOWS ? ['python.exe'] : ['python3', 'python']; const envPath = process.env.PLATFORMIO_PATH || process.env.PATH; const errors = []; @@ -116,14 +117,14 @@ export async function findPythonExecutable() { fs.existsSync(executable) && (await callInstallerScript(executable, ['check', 'python'])) ) { - // Verify Python version does not exceed maximum stable baseline (e.g., < 3.13) + // Verify Python version does not exceed maximum stable baseline try { const versionCheck = await proc.getCommandOutput(executable, [ '-c', - 'import sys; print("1" if sys.version_info < (3, 13) else "0")' + `import sys; print("1" if sys.version_info < tuple(map(int, "${maxPythonVersion}".split("."))) else "0")` ]); if (versionCheck.trim() !== '1') { - console.warn(`Python at ${executable} exceeds max supported version (>= 3.13)`); + console.warn(`Python at ${executable} exceeds max supported version (>= ${maxPythonVersion})`); continue; // Reject bleeding edge and force fallback loop } } catch (err) {