setupPython sets up Python with a specific version. Strategy: Try system Python first, fallback to conda if version mismatches.
(ctx context.Context, pythonVersion string)
| 103 | // setupPython sets up Python with a specific version. |
| 104 | // Strategy: Try system Python first, fallback to conda if version mismatches. |
| 105 | func setupPython(ctx context.Context, pythonVersion string) error { |
| 106 | // Quick return only if version hasn't changed AND venv still exists on disk. |
| 107 | envDir := getPythonVenvPath(pythonVersion, ctx.Project().GetName()) |
| 108 | if PythonTool != nil && PythonTool.version == pythonVersion && fileio.PathExists(envDir) { |
| 109 | return nil |
| 110 | } |
| 111 | |
| 112 | // Try to use system Python first if versions match or empty. |
| 113 | useSystemPython := false |
| 114 | systemPythonVer := GetDefaultPythonVersion() |
| 115 | versionMatches := normalizeVersion(systemPythonVer) == normalizeVersion(pythonVersion) |
| 116 | if pythonVersion == "" || versionMatches { |
| 117 | useSystemPython = true |
| 118 | } |
| 119 | |
| 120 | var currentPython python.Python |
| 121 | var isCondaPython bool = false |
| 122 | if useSystemPython { // Use system Python if version matches. |
| 123 | currentPython = &python.SystemPython{} |
| 124 | } else { // Fallback to conda if system Python doesn't match or doesn't exist. |
| 125 | condaTool, err := FindBuildTool(ctx, "conda") |
| 126 | if err != nil { |
| 127 | return fmt.Errorf("failed to find conda tool for python setup -> %w", err) |
| 128 | } |
| 129 | currentPython = python.NewCondaPython(ctx, condaTool.Archive, condaTool.Version, pythonVersion) |
| 130 | isCondaPython = true |
| 131 | } |
| 132 | |
| 133 | if err := currentPython.Setup(); err != nil { |
| 134 | return fmt.Errorf("failed to setup Python %s -> %w", pythonVersion, err) |
| 135 | } |
| 136 | |
| 137 | // Create version specific python environment if not exist. |
| 138 | pythonExec, err := currentPython.GetExecutable() |
| 139 | if err != nil { |
| 140 | return fmt.Errorf("failed to detect python executable for version %s -> %w", pythonVersion, err) |
| 141 | } |
| 142 | |
| 143 | // For conda Python, compute the lib directory for LD_LIBRARY_PATH on Linux/macOS |
| 144 | var condaLibDir string |
| 145 | if isCondaPython && runtime.GOOS != "windows" { |
| 146 | // conda python executable is typically at {conda_env}/bin/python |
| 147 | // so its lib is at {conda_env}/lib |
| 148 | pythonDir := filepath.Dir(pythonExec) // get the bin directory. |
| 149 | condaLibDir = filepath.Join(filepath.Dir(pythonDir), "lib") |
| 150 | } |
| 151 | |
| 152 | // Ensure virtual environment exists. |
| 153 | if !fileio.PathExists(envDir) { |
| 154 | // Detect Python major version to choose appropriate venv creation method |
| 155 | majorVersion := "3" |
| 156 | if strings.HasPrefix(pythonVersion, "2") { |
| 157 | majorVersion = "2" |
| 158 | } |
| 159 | |
| 160 | var command string |
| 161 | if majorVersion == "2" { |
| 162 | // Python2 doesn't have built-in venv module, need to use virtualenv package. |
no test coverage detected