Skip to content

Fix inline-script env creation for CPython sys.version_info versions (PEP 723) - #1752

Merged
Stella Huang (StellaHuang95) merged 1 commit into
microsoft:mainfrom
StellaHuang95:copilot/fix-inline-script-version-info
Sep 2, 2026
Merged

Fix inline-script env creation for CPython sys.version_info versions (PEP 723)#1752
Stella Huang (StellaHuang95) merged 1 commit into
microsoft:mainfrom
StellaHuang95:copilot/fix-inline-script-version-info

Conversation

@StellaHuang95

Copy link
Copy Markdown
Contributor

Summary

Fixes PEP 723 inline-script environment creation, which currently fails for every interpreter whose version the native locator (pet) reports in CPython's sys.version_info form (e.g. 3.14.3.final.0). The venv is provisioned correctly (base interpreter selected, uv venv --seed + dependencies installed), but is then rejected by a post-creation self-check and deleted, surfacing:

Created inline-script environment does not match the requested cache entry.

Root cause

pet resolve returns interpreter versions as major.minor.micro.releaselevel.serial — e.g. "3.14.3.final.0" (verified against the bundled pet in both server mode and CLI, for Python 3.12 / 3.13 / 3.14). That string is not valid PEP 440, and the @renovatebot/pep440 helpers reject it:

  • parseReleaseSegments("3.14.3.final.0")undefined (because clean() returns null). areEqualPythonReleases() guards on undefined and returns false even when both versions are identical, so buildCacheEntry() treats the freshly-created environment as a version mismatch and deletes it. This blocks creation for scripts without requires-python.
  • satisfies("3.14.3.final.0", ">=3.11") throws (Cannot destructure property 'epoch' of 'input' as it is null). matchesInstallConstraint() catches it and returns false, so scripts with requires-python find no compatible base interpreter during selectBaseInterpreter().

The repo's existing PythonVersion class already parses the sys.version_info form (so matchesPythonVersion was unaffected); only the two @renovatebot/pep440-based helpers were not.

Fix

Add normalizeCpythonVersionInfo() in common/utils/pep440Release.ts, converting the sys.version_info form to PEP 440:

  • 3.14.3.final.03.14.3
  • 3.14.0.candidate.23.14.0rc2 (and .alpha.N / .beta.NaN / bN)
  • release segments are preserved verbatim — no zero-padding, so 3.13 stays 3.13 and extractLowerBoundVersion()'s uv python install targets are unchanged
  • any non-sys.version_info string is returned unchanged

Apply it in:

  • parseReleaseSegments() → fixes areEqualPythonReleases() (create + reuse cache validation) and the interpreter/candidate version sorting that also depends on it
  • matchesInstallConstraint() (before satisfiesPep440) → fixes the requires-python base-selection and reuse paths

Scope is limited to the inline-script feature: parseReleaseSegments is used only by inline-script code, and matchesInstallConstraint is private to the inline-script manager. No change to venv / system / conda / other environment resolution.

Testing

  • New unit tests for normalizeCpythonVersionInfo and parseReleaseSegments (final + prerelease forms, whitespace, no zero-padding, non-matching passthrough).
  • New create-flow regression tests in the inline-script manager suite: creation succeeds when the resolved base reports 3.14.3.final.0, both with and without requires-python (both previously returned undefined).
  • Full unit suite: 1978 passing / 6 pending. tsc (npm run compile-tests) and eslint clean.

Impact / benefit

Restores end-to-end PEP 723 inline-script environment creation on setups where the bundled pet reports sys.version_info-style versions (observed with pet 0.1.0-dev.428887 on Windows for Python 3.12–3.14). Without this fix the "Set up environment" / CodeLens flow provisions the venv and then silently discards it, so users cannot create an inline-script environment at all.

Out of scope

The same non-PEP-440 version string also makes shortenVersionString() return "3.14.3.final.0" verbatim (a cosmetic display artifact that affects all pet-resolved environments, not just inline scripts). That is a separate, non-blocking issue and is intentionally left for a follow-up to keep this fix's blast radius minimal.

…(PEP 723)

The native locator (pet) reports interpreter versions in CPython's
`sys.version_info` form, e.g. "3.14.3.final.0", which is not valid PEP 440.
The `@renovatebot/pep440` helpers reject that shape, so the inline-script
manager mishandled every such interpreter:

- `areEqualPythonReleases()` returned false even for two identical versions,
  because `parseReleaseSegments("3.14.3.final.0")` yields `undefined`. A
  freshly created environment was therefore judged not to match its own
  requested version, rejected with "Created inline-script environment does not
  match the requested cache entry", and deleted — so env creation failed for
  scripts without `requires-python`.
- `matchesInstallConstraint()` threw (caught, returning false), so scripts
  with `requires-python` found no compatible base interpreter.

Add `normalizeCpythonVersionInfo()`, which converts the `sys.version_info`
form to PEP 440 ("3.14.3.final.0" -> "3.14.3", "3.14.0.candidate.2" ->
"3.14.0rc2"). It preserves the release segments verbatim (no zero-padding, so
`extractLowerBoundVersion`'s `uv python install` targets are unaffected) and
returns any other string unchanged. Apply it inside `parseReleaseSegments()`
(fixing `areEqualPythonReleases` and the interpreter/candidate sorting that
also depend on it) and before `satisfiesPep440()` in
`matchesInstallConstraint()` (fixing the `requires-python` paths).
@StellaHuang95
Stella Huang (StellaHuang95) force-pushed the copilot/fix-inline-script-version-info branch from 7101a06 to 6dad4a6 Compare September 2, 2026 00:47
@StellaHuang95
Stella Huang (StellaHuang95) merged commit c5520ef into microsoft:main Sep 2, 2026
83 of 84 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Issue identified by VS Code Team member as probable bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants