| 187 | * logging, warnings, and error handling. |
| 188 | */ |
| 189 | export function resolvePythonVersion({ |
| 190 | isDev, |
| 191 | pythonPackage, |
| 192 | rootDir, |
| 193 | }: { |
| 194 | isDev?: boolean; |
| 195 | pythonPackage: PythonPackage; |
| 196 | rootDir: string; |
| 197 | }): PythonVersionResolution { |
| 198 | if (isDev) { |
| 199 | return { |
| 200 | pythonVersion: getDevPythonVersion(), |
| 201 | pythonPackage, |
| 202 | }; |
| 203 | } |
| 204 | |
| 205 | const constraints = pythonPackage.requiresPython; |
| 206 | const defaultPv = getDefaultPythonVersion({ isDev: false }); |
| 207 | |
| 208 | let selection: PythonVersion; |
| 209 | let source: string | undefined; |
| 210 | let autoUpgraded = false; |
| 211 | |
| 212 | if (!constraints || constraints.length === 0) { |
| 213 | console.log( |
| 214 | `No Python version specified in .python-version, pyproject.toml, or Pipfile.lock. Using python version: ${pythonVersionString(defaultPv)}` |
| 215 | ); |
| 216 | selection = defaultPv; |
| 217 | } else { |
| 218 | const defaultBuild = toPythonBuild(defaultPv); |
| 219 | const availableBuilds = getAvailablePythonBuilds(); |
| 220 | const allBuilds = getAllPythonBuilds(); |
| 221 | |
| 222 | const result = selectPythonVersion({ |
| 223 | constraints, |
| 224 | availableBuilds, |
| 225 | allBuilds, |
| 226 | defaultBuild, |
| 227 | majorMinorOnly: true, |
| 228 | legacyTildeEquals: true, |
| 229 | }); |
| 230 | |
| 231 | source = result.source; |
| 232 | selection = getPythonVersionForBuild(result.build) ?? defaultPv; |
| 233 | |
| 234 | // Auto-upgrade: when the constraint comes from a converted manifest |
| 235 | // (e.g. Pipfile.lock) and resolves to a version below the default, |
| 236 | // upgrade to the default. Legacy projects often pin old versions |
| 237 | // that are incompatible with the builder's runtime requirements. |
| 238 | if ( |
| 239 | pythonPackage.manifest?.origin && |
| 240 | !result.notAvailable && |
| 241 | !result.invalidConstraint && |
| 242 | !versionLessOrEqual(defaultPv, selection) |
| 243 | ) { |
| 244 | const originalVersion = pythonVersionString(selection); |
| 245 | selection = defaultPv; |
| 246 | autoUpgraded = true; |