Skip to main content

soma_provider_adapters/python/
interpreter.rs

1use std::path::PathBuf;
2
3use super::materializer;
4
5/// Selects the Python interpreter. `Ambient` preserves historical command
6/// overrides, while `Prepared` is authoritative so a managed immutable
7/// environment cannot be bypassed by process or provider configuration.
8#[derive(Debug, Clone, Default, PartialEq, Eq)]
9pub enum PythonInterpreter {
10    #[default]
11    Ambient,
12    Prepared(PathBuf),
13}
14
15impl PythonInterpreter {
16    pub fn prepared(environment: &materializer::PreparedPythonEnvironment) -> Self {
17        Self::Prepared(environment.python.clone())
18    }
19
20    pub(crate) fn command(&self) -> String {
21        match self {
22            Self::Ambient => default_python_command().to_owned(),
23            Self::Prepared(path) => path.to_string_lossy().into_owned(),
24        }
25    }
26}
27
28pub(super) fn select_python_command(
29    manifest_command: Option<&str>,
30    environment_command: Option<String>,
31    interpreter: &PythonInterpreter,
32) -> String {
33    match interpreter {
34        PythonInterpreter::Prepared(_) => interpreter.command(),
35        PythonInterpreter::Ambient => manifest_command
36            .map(str::to_owned)
37            .or(environment_command)
38            .unwrap_or_else(|| interpreter.command()),
39    }
40}
41
42#[cfg(windows)]
43pub(crate) fn default_python_command() -> &'static str {
44    "python"
45}
46
47#[cfg(not(windows))]
48pub(crate) fn default_python_command() -> &'static str {
49    "python3"
50}