{"record":{"id":"6152c209a31b26b7","repo":"pulumi/pulumi","slug":"invalid-python-version-format-q","errorCode":null,"errorMessage":"invalid Python version format: %q","messagePattern":"invalid Python version format: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdk/python/toolchain/toolchain.go","lineNumber":306,"sourceCode":"\tcmd, err := commandFunc(ctx, \"-c\", \"import sys; print(sys.executable)\")\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tout, err := cmd.Output()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to get python executable path: %w\", err)\n\t}\n\treturn strings.TrimSpace(string(out)), nil\n}\n\nfunc ParsePythonVersion(versionString string) (semver.Version, error) {\n\tversionString = strings.TrimSpace(versionString)\n\tversionString = strings.TrimPrefix(versionString, \"Python \")\n\n\tre := regexp.MustCompile(`^(\\d+)\\.(\\d+)(?:\\.(\\d+))?(?:(a|b|rc|dev)(\\d+))?`)\n\tmatches := re.FindStringSubmatch(versionString)\n\tif len(matches) < 3 {\n\t\treturn semver.Version{}, fmt.Errorf(\"invalid Python version format: %q\", versionString)\n\t}\n\n\tmajor, minor := matches[1], matches[2]\n\tpatch := matches[3]\n\tif patch == \"\" {\n\t\tpatch = \"0\"\n\t}\n\n\tnormalizedVersion := fmt.Sprintf(\"%s.%s.%s\", major, minor, patch)\n\n\t// Convert Python pre-release naming to semver format\n\tif matches[4] != \"\" {\n\t\tpreReleaseType := matches[4]\n\t\tpreReleaseNum := matches[5]\n\t\tswitch preReleaseType {\n\t\tcase \"a\":\n\t\t\tnormalizedVersion += \"-alpha.\" + preReleaseNum\n\t\tcase \"b\":","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/sdk/python/toolchain/toolchain.go#L288-L324","documentation":"`ParsePythonVersion` extracts `major.minor[.patch][pre-release]` from strings like `Python 3.11.4` using a regex. If the trimmed string does not match at least `major.minor`, the version string is unparseable and this error is returned.","triggerScenarios":"The command that reports the Python version returned empty output, a locale/OS-specific message, an error banner, or a version with an unusual format (e.g. `3` alone, or `Python 3.11.4rc1 (main, ...) [...]` prefixed by compiler text) that the regex cannot match.","commonSituations":"Interpreter on PATH is a shim/wrapper script printing extra text; output captured includes a shell banner or deprecation notice; a minimal Python build reporting only `3.12`; empty output because the version command failed silently.","solutions":["Run `python --version` yourself and confirm it prints a standard `Python X.Y.Z` line","Remove PATH entries where wrappers/shims print extra output before the version","Ensure the resolved interpreter is a real CPython (not the Windows Store alias) and reinstall if it emits nothing","If a pre-release like `3.13.0a1` still fails, pin a stable release"],"exampleFix":"// before\nPython 3.11.4 (main, Jun 20 2023) [clang ...] wrapped by shim printing banner\n// after\n$ python --version\nPython 3.11.4","handlingStrategy":"validation","validationCode":"out, _ := exec.Command(\"python\", \"--version\").CombinedOutput()\nver := strings.TrimSpace(string(out))\nmatched, _ := regexp.MatchString(`^Python \\d+\\.\\d+(\\.\\d+)?`, ver)\nif !matched {\n    return fmt.Errorf(\"interpreter reported unparseable version: %q\", ver)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure `python --version` prints a plain standard line (no shims/banners)","Use stable CPython releases when possible","Sanitize captured output (strip non-version lines) before parsing"],"tags":["python","version","parsing"],"backgroundTag":"invalid-version-format","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}