(binary)
| 2224 | } |
| 2225 | |
| 2226 | function probePython(binary) { |
| 2227 | const snippet = [ |
| 2228 | 'import json, sys', |
| 2229 | 'print(json.dumps({', |
| 2230 | ' "executable": sys.executable,', |
| 2231 | ' "version": ".".join(str(part) for part in sys.version_info[:3]),', |
| 2232 | ' "major": sys.version_info[0],', |
| 2233 | ' "minor": sys.version_info[1],', |
| 2234 | ' "patch": sys.version_info[2],', |
| 2235 | '}, ensure_ascii=False))', |
| 2236 | ].join('\n'); |
| 2237 | const result = spawnSync(binary, ['-c', snippet], syncSpawnOptions({ |
| 2238 | encoding: 'utf8', |
| 2239 | env: process.env, |
| 2240 | })); |
| 2241 | if (result.error) { |
| 2242 | return { |
| 2243 | ok: false, |
| 2244 | binary, |
| 2245 | error: result.error.message, |
| 2246 | }; |
| 2247 | } |
| 2248 | if (result.status !== 0) { |
| 2249 | return { |
| 2250 | ok: false, |
| 2251 | binary, |
| 2252 | error: (result.stderr || result.stdout || '').trim() || `exit ${result.status}`, |
| 2253 | }; |
| 2254 | } |
| 2255 | try { |
| 2256 | const payload = JSON.parse(result.stdout || '{}'); |
| 2257 | const executable = String(payload.executable || '').trim(); |
| 2258 | return { |
| 2259 | ok: true, |
| 2260 | binary, |
| 2261 | executable, |
| 2262 | realExecutable: executable ? realpathOrSelf(executable) : '', |
| 2263 | version: String(payload.version || '').trim(), |
| 2264 | major: Number(payload.major), |
| 2265 | minor: Number(payload.minor), |
| 2266 | patch: Number(payload.patch), |
| 2267 | }; |
| 2268 | } catch (error) { |
| 2269 | return { |
| 2270 | ok: false, |
| 2271 | binary, |
| 2272 | error: error instanceof Error ? error.message : 'Could not parse Python version probe.', |
| 2273 | }; |
| 2274 | } |
| 2275 | } |
| 2276 | |
| 2277 | function minimumPythonRequest() { |
| 2278 | return `${minimumPythonVersion.major}.${minimumPythonVersion.minor}`; |
no test coverage detected