python: if no python, install uv and maybe create venv#12904
python: if no python, install uv and maybe create venv#12904isabelizimm merged 15 commits intomainfrom
Conversation
|
E2E Tests 🚀 |
|
Thank you for the QA Notes, @isabelizimm. Creating an issue for automated testing for similar process to which you have outlined in the notes. cc @midleman @testlabauto
|
There was a problem hiding this comment.
Pull request overview
Adds a “Install Python via uv” path to Positron’s interpreter selection flow so users can bootstrap a supported Python install (and optionally a workspace venv) when no suitable Python is available.
Changes:
- Adds a special quick pick entry in the runtime selector to trigger Python installation via
uv. - Introduces a
uvPythonInstallerhelper to list supported Python versions fromuv, installuvif needed, install a selected Python, and optionally create a venv in a workspace. - Updates the Python runtime manager/commands to support refresh + returning a selected runtime id, and adds unit tests for parsing/version filtering.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/vs/workbench/contrib/languageRuntime/browser/languageRuntimeActions.ts | Adds a quick pick option to install Python via uv and then select the newly installed runtime. |
| extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/uvPythonInstaller.ts | New implementation for listing/installing Python via uv and optionally creating a venv. |
| extensions/positron-python/src/client/pythonEnvironments/creation/createEnvApi.ts | Registers the python.installPythonViaUv command and returns the installed runtime info to the caller. |
| extensions/positron-python/src/client/common/constants.ts | Adds the python.installPythonViaUv command id constant. |
| extensions/positron-python/src/client/positron/manager.ts | Updates runtime selection to return a runtime id and adds an interpreter refresh helper. |
| extensions/positron-python/src/client/pythonEnvironments/common/environmentManagers/uv.ts | Exports shared regex/helpers used by the new installer. |
| extensions/positron-python/src/client/pythonEnvironments/creation/provider/uvCreationProvider.ts | Exports createUvVenv() for reuse in the install flow. |
| extensions/positron-python/src/test/pythonEnvironments/common/environmentManagers/uvPythonInstaller.unit.test.ts | Adds unit coverage for uv python list parsing/filtering/deduping/sorting behavior. |
| extensions/positron-python/src/test/configuration/interpreterSelector/commands/setInterpreter.unit.test.ts | Adjusts mocks for updated return type from selectLanguageRuntimeFromPath(). |
| canPickMany: false | ||
| // Check if we should show the "Install Python via uv" option | ||
| // Only check after discovery is complete to avoid showing the option prematurely | ||
| const allowPythonInstall = configurationService.getValue<boolean>('python.allowPythonInstall') ?? true; |
There was a problem hiding this comment.
This is a command that folks can turn off if they don't want to be prompted to install uv. Right now this is the R person escape hatch, but I do worry it's heavy-handed.
|
Okay, after chatting IRL we think it makes sense to make infra to allow languages to install themselves. Please hold on a review! |
…andling - Fix $unregisterRuntimePickerContribution to actually dispose the contribution by tracking disposables in a Map keyed by handle - Extract duplicated installPythonViaUv result handling into shared helper - Fetch picker contribution items in parallel using Promise.all() - Add warning message when venv creation fails (falls back to base Python) - Add security note to installUv documenting the official installation pattern Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
alright, i think this is ready again! |
austin3dickey
left a comment
There was a problem hiding this comment.
Awesome work, this will be so nice! Haven't tested this yet but here are some code review thoughts.
| // Try to register the runtime | ||
| let metadata = await this.registerLanguageRuntimeFromPath(pythonPath, recreateRuntime); | ||
|
|
||
| // If registration failed, the interpreter might be newly created - trigger a refresh and retry |
| * Filters out pre-release versions and returns stable versions only. | ||
| * @returns Array of available Python versions, sorted by version descending | ||
| */ | ||
| export async function getAvailablePythonVersions(): Promise<UvAvailablePython[]> { |
There was a problem hiding this comment.
I think we have a lot of duplicate-ish code in uv.ts, uvCreationProvider.ts, and uvUtils.ts for dealing with python versions and installing python. Maybe you can reuse all or parts of those functions?
E.g. I'd think we'd want to use approximately the same code path if you're creating a new venv with the New Folder From Template flow vs. using the Python: Create Environment command vs. clicking the button in the interpreter picker. Though I get that might be tricker than I think it is, especially because I think there's some hardcoded python stuff in the core new folder service too.
|
|
||
| try { | ||
| // Use exec directly instead of installUvPython to avoid cache issues | ||
| // when uv was just installed in the same session |
There was a problem hiding this comment.
Hm, these caching issues might need a bit more love. Everything is working fantastically along the happy path making a venv inside a workspace. But when I do the flow outside a workspace,
- the new interpreter that starts up is labeled
Unknown, notuv - if I restart Positron it's not able to find that unknown interpreter and so it gives a scary "unable to start up; failed to resolve" error
I am wondering if both those issues would be solved if we somehow force Positron to re-check whether uv is installed? There's some caching on the UvUtils class that maybe we could invalidate upon successfully installing uv? Then theoretically if we refresh discovery it'll know the new interpreter is uv and maybe if the metadata lines up we won't see problem 2.
There was a problem hiding this comment.
I also think there's a "python: clear cache and reload window" command, maybe we could hook into the cache-clear part of that?
There was a problem hiding this comment.
I tried the flow again with uv already installed, and didn't see these problems. So I bet the "is uv installed" cache invalidation would solve them.
There was a problem hiding this comment.
Ah, yeah we didn't have good a no-workspace fallback. I updated it to make a venv at $HOME/.venv . Do you think that's too heavy handed? I debated adding it to the ~/.positron dir, but that isn't as straightforward for discovery and the cwd for the console is $HOME too
| return [ | ||
| { | ||
| id: 'install-python-uv', | ||
| label: '$(add) Install Python via uv', |
There was a problem hiding this comment.
Is it possible to use the lil Python icon instead of ➕ ? If that's too hard it's cool
|
|
||
| try { | ||
| if (process.platform === 'win32') { | ||
| await exec('powershell', [ |
There was a problem hiding this comment.
I tested on Windows ARM, and everything generally worked, though it ended up installing an x64 python instead of arm64. So I got the warning popup that there was an architecture mismatch. Python was still able to run though I'd guess that certain compiled libraries wouldn't work.
I found this:
which has the comment
I believe you can set
UV_PYTHON=arm64.
Maybe we should detect the arch and set that?
There was a problem hiding this comment.
Looks like uv python list needs the --all-arches flag too.
Co-authored-by: Austin Dickey <austin3spammy@gmail.com> Signed-off-by: Isabel Zimmerman <54685329+isabelizimm@users.noreply.github.com>
austin3dickey
left a comment
There was a problem hiding this comment.
Awesome, looks great and Mac works well for me! I still want to test on Windows and Web before approving if that's okay. Else you can merge.
| return pythonPath; | ||
| } | ||
|
|
||
| traceError('Could not find installed Python path'); |
There was a problem hiding this comment.
Cool, everything is working on web!
On ARM Windows, I see this:
2026-04-21 10:50:44.507 [info] > uv python list --all-arches
2026-04-21 10:50:46.377 [info] Installing Python 3.14 via uv...
2026-04-21 10:50:46.392 [info] > uv python install --python-platform windows-arm64 3.14
2026-04-21 10:50:46.433 [info] Python 3.14 installed successfully
2026-04-21 10:50:46.440 [info] > uv python find 3.14
2026-04-21 10:50:46.746 [error] Could not find installed Python path
and it's not able to proceed.
I think it's because --python-platform isn't a thing:
PS C:\Users\austin> uv python install --python-platform windows-arm64 3.14
error: unexpected argument '--python-platform' found
tip: a similar argument exists: '--python-fetch'
Usage: uv.exe python install [OPTIONS] [TARGETS]...
For more information, try '--help'.
So a couple things:
- Not sure why the logs say it was installed successfully
- I looked into it some more and the only way I could get it to work was doing
uv python install cpython-3.14.4-windows-aarch64-none(that is, supply the full name including arch). Using an arg or an env var wasn't helping.
There was a problem hiding this comment.
is cpython-3.14.4-windows-aarch64-none the output when you run uv python list? Trying to figure out how to snag that identifier without generating it ourselves 👀
There was a problem hiding this comment.
Yes that's the identifier! (The first column in uv python list --all-arches)
| const installTarget = identifier ?? version; | ||
| await exec('uv', ['python', 'install', installTarget], { throwOnStdErr: false }); |
There was a problem hiding this comment.
okay, here's what is happening for Windows now! We only pass the identifier on Windows ARM builds, so it will be picked up for that platform but otherwise just use the vanilla version
austin3dickey
left a comment
There was a problem hiding this comment.
Everything works perfectly! Thanks for all your work on this, this is huge!
registerRuntimePickerContributionAPI allowing extensions to add custom items to the interpreter pickerRelease Notes
New Features
uvand supported Python version.Bug Fixes
QA Notes
@:win @:web
Be brave! Uninstall all non-System Pythons. For
uv, it looks like thisSelect Interpreterdropdown. You should see an option to install Python with uv.uvand then the chosen Python.For automated testing purposes, we can force the "Install Python" option to always be shown in the "Select Interpreter" dropdown with the setting
python.INTERNAL_alwaysShowUvInstallOptionequal to True.