Skip to content

Commit 838eaac

Browse files
Copiloteleanorjboyd
andcommitted
Add VenvUv support and alwaysUseUv setting
Co-authored-by: eleanorjboyd <26030610+eleanorjboyd@users.noreply.github.com>
1 parent 41ac2bf commit 838eaac

6 files changed

Lines changed: 47 additions & 8 deletions

File tree

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@
127127
"items": {
128128
"type": "string"
129129
}
130+
},
131+
"python-envs.alwaysUseUv": {
132+
"type": "boolean",
133+
"description": "%python-envs.alwaysUseUv.description%",
134+
"default": true,
135+
"scope": "machine"
130136
}
131137
}
132138
},

package.nls.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@
3939
"python-envs.terminal.deactivate.title": "Deactivate Environment in Current Terminal",
4040
"python-envs.uninstallPackage.title": "Uninstall Package",
4141
"python-envs.revealProjectInExplorer.title": "Reveal Project in Explorer",
42-
"python-envs.runPetInTerminal.title": "Run Python Environment Tool (PET) in Terminal..."
42+
"python-envs.runPetInTerminal.title": "Run Python Environment Tool (PET) in Terminal...",
43+
"python-envs.alwaysUseUv.description": "When set to true, uv will be used to manage all virtual environments if available. When set to false, uv will only manage virtual environments explicitly created by uv."
4344
}

src/managers/builtin/helpers.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { CancellationError, CancellationToken, LogOutputChannel } from 'vscode';
33
import { createDeferred } from '../../common/utils/deferred';
44
import { sendTelemetryEvent } from '../../common/telemetry/sender';
55
import { EventNames } from '../../common/telemetry/constants';
6+
import { getConfiguration } from '../../common/workspace.apis';
7+
import { NativePythonEnvironmentKind } from '../common/nativePythonFinder';
68

79
const available = createDeferred<boolean>();
810
export async function isUvInstalled(log?: LogOutputChannel): Promise<boolean> {
@@ -24,6 +26,35 @@ export async function isUvInstalled(log?: LogOutputChannel): Promise<boolean> {
2426
return available.promise;
2527
}
2628

29+
/**
30+
* Determines if uv should be used for managing a virtual environment.
31+
* @param envKind - The kind of environment (Venv, VenvUv, etc.)
32+
* @param log - Optional log output channel
33+
* @returns True if uv should be used, false otherwise
34+
*/
35+
export async function shouldUseUv(
36+
envKind?: NativePythonEnvironmentKind,
37+
log?: LogOutputChannel,
38+
): Promise<boolean> {
39+
// If the environment is explicitly a VenvUv type, always use uv
40+
if (envKind === NativePythonEnvironmentKind.venvUv) {
41+
return await isUvInstalled(log);
42+
}
43+
44+
// Check the alwaysUseUv setting
45+
const config = getConfiguration('python-envs');
46+
const alwaysUseUv = config.get<boolean>('alwaysUseUv', true);
47+
48+
// If alwaysUseUv is true and uv is installed, use it
49+
if (alwaysUseUv) {
50+
return await isUvInstalled(log);
51+
}
52+
53+
// Otherwise, only use uv for VenvUv environments (already handled above)
54+
return false;
55+
}
56+
57+
2758
export async function runUV(
2859
args: string[],
2960
cwd?: string,

src/managers/builtin/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
NativePythonFinder,
1919
} from '../common/nativePythonFinder';
2020
import { shortVersion, sortEnvironments } from '../common/utils';
21-
import { isUvInstalled, runPython, runUV } from './helpers';
21+
import { shouldUseUv, runPython, runUV } from './helpers';
2222
import { parsePipList, PipPackage } from './pipListUtils';
2323

2424
function asPackageQuickPickItem(name: string, version?: string): QuickPickItem {
@@ -139,7 +139,7 @@ export async function refreshPythons(
139139
}
140140

141141
async function refreshPipPackagesRaw(environment: PythonEnvironment, log?: LogOutputChannel): Promise<string> {
142-
const useUv = await isUvInstalled();
142+
const useUv = await shouldUseUv(undefined, log);
143143
if (useUv) {
144144
return await runUV(['pip', 'list', '--python', environment.execInfo.run.executable], undefined, log);
145145
}
@@ -194,7 +194,7 @@ export async function managePackages(
194194
throw new Error('Python 2.* is not supported (deprecated)');
195195
}
196196

197-
const useUv = await isUvInstalled();
197+
const useUv = await shouldUseUv(undefined, manager.log);
198198
const uninstallArgs = ['pip', 'uninstall'];
199199
if (options.uninstall && options.uninstall.length > 0) {
200200
if (useUv) {

src/managers/builtin/venvUtils.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
NativePythonFinder,
2626
} from '../common/nativePythonFinder';
2727
import { getShellActivationCommands, shortVersion, sortEnvironments } from '../common/utils';
28-
import { isUvInstalled, runPython, runUV } from './helpers';
28+
import { shouldUseUv, runPython, runUV } from './helpers';
2929
import { getProjectInstallable, PipPackages } from './pipUtils';
3030
import { resolveSystemPythonEnvironmentPath } from './utils';
3131
import { createStepBasedVenvFlow } from './venvStepBasedFlow';
@@ -176,7 +176,7 @@ export async function findVirtualEnvironments(
176176
const envs = data
177177
.filter((e) => isNativeEnvInfo(e))
178178
.map((e) => e as NativeEnvInfo)
179-
.filter((e) => e.kind === NativePythonEnvironmentKind.venv);
179+
.filter((e) => e.kind === NativePythonEnvironmentKind.venv || e.kind === NativePythonEnvironmentKind.venvUv);
180180

181181
for (const e of envs) {
182182
if (!(e.prefix && e.executable && e.version)) {
@@ -290,7 +290,7 @@ export async function createWithProgress(
290290
async () => {
291291
const result: CreateEnvironmentResult = {};
292292
try {
293-
const useUv = await isUvInstalled(log);
293+
const useUv = await shouldUseUv(undefined, log);
294294
// env creation
295295
if (basePython.execInfo?.run.executable) {
296296
if (useUv) {
@@ -459,7 +459,7 @@ export async function resolveVenvPythonEnvironmentPath(
459459
): Promise<PythonEnvironment | undefined> {
460460
const resolved = await nativeFinder.resolve(fsPath);
461461

462-
if (resolved.kind === NativePythonEnvironmentKind.venv) {
462+
if (resolved.kind === NativePythonEnvironmentKind.venv || resolved.kind === NativePythonEnvironmentKind.venvUv) {
463463
const envInfo = await getPythonInfo(resolved);
464464
return api.createPythonEnvironmentItem(envInfo, manager);
465465
}

src/managers/common/nativePythonFinder.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export enum NativePythonEnvironmentKind {
6969
linuxGlobal = 'LinuxGlobal',
7070
macXCode = 'MacXCode',
7171
venv = 'Venv',
72+
venvUv = 'VenvUv',
7273
virtualEnv = 'VirtualEnv',
7374
virtualEnvWrapper = 'VirtualEnvWrapper',
7475
windowsStore = 'WindowsStore',

0 commit comments

Comments
 (0)