Skip to content

Commit 32512b1

Browse files
authored
Fix for prefix conda environments (#24553)
For #24472
1 parent 33b5e97 commit 32512b1

File tree

2 files changed

+56
-7
lines changed

2 files changed

+56
-7
lines changed

src/client/pythonEnvironments/common/environmentManagers/conda.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,15 @@ export class Conda {
495495
);
496496
}
497497

498+
/**
499+
* Retrieves list of directories where conda environments are stored.
500+
*/
501+
@cache(30_000, true, 10_000)
502+
public async getEnvDirs(): Promise<string[]> {
503+
const info = await this.getInfo();
504+
return info.envs_dirs ?? [];
505+
}
506+
498507
public async getName(prefix: string, info?: CondaInfo): Promise<string | undefined> {
499508
info = info ?? (await this.getInfo(true));
500509
if (info.root_prefix && arePathsSame(prefix, info.root_prefix)) {
@@ -619,3 +628,8 @@ export class Conda {
619628
export function setCondaBinary(executable: string): void {
620629
Conda.setConda(executable);
621630
}
631+
632+
export async function getCondaEnvDirs(): Promise<string[] | undefined> {
633+
const conda = await Conda.getConda();
634+
return conda?.getEnvDirs();
635+
}

src/client/pythonEnvironments/nativeAPI.ts

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ import { createDeferred, Deferred } from '../common/utils/async';
2323
import { Architecture, getUserHomeDir } from '../common/utils/platform';
2424
import { parseVersion } from './base/info/pythonVersion';
2525
import { cache } from '../common/utils/decorators';
26-
import { traceError, traceLog, traceWarn } from '../logging';
26+
import { traceError, traceInfo, traceLog, traceWarn } from '../logging';
2727
import { StopWatch } from '../common/utils/stopWatch';
2828
import { FileChangeType } from '../common/platform/fileSystemWatcher';
2929
import { categoryToKind, NativePythonEnvironmentKind } from './base/locators/common/nativePythonUtils';
30-
import { setCondaBinary } from './common/environmentManagers/conda';
30+
import { getCondaEnvDirs, setCondaBinary } from './common/environmentManagers/conda';
3131
import { setPyEnvBinary } from './common/environmentManagers/pyenv';
3232
import {
3333
createPythonWatcher,
@@ -157,26 +157,53 @@ function getEnvType(kind: PythonEnvKind): PythonEnvType | undefined {
157157
}
158158
}
159159

160-
function getName(nativeEnv: NativeEnvInfo, kind: PythonEnvKind): string {
160+
function isSubDir(pathToCheck: string | undefined, parents: string[]): boolean {
161+
return parents.some((prefix) => {
162+
if (pathToCheck) {
163+
return path.normalize(pathToCheck).startsWith(path.normalize(prefix));
164+
}
165+
return false;
166+
});
167+
}
168+
169+
function getName(nativeEnv: NativeEnvInfo, kind: PythonEnvKind, condaEnvDirs: string[]): string {
161170
if (nativeEnv.name) {
162171
return nativeEnv.name;
163172
}
164173

165174
const envType = getEnvType(kind);
166-
if (nativeEnv.prefix && (envType === PythonEnvType.Conda || envType === PythonEnvType.Virtual)) {
175+
if (nativeEnv.prefix && envType === PythonEnvType.Virtual) {
167176
return path.basename(nativeEnv.prefix);
168177
}
178+
179+
if (nativeEnv.prefix && envType === PythonEnvType.Conda) {
180+
if (nativeEnv.name === 'base') {
181+
return 'base';
182+
}
183+
184+
const workspaces = (getWorkspaceFolders() ?? []).map((wf) => wf.uri.fsPath);
185+
if (isSubDir(nativeEnv.prefix, workspaces)) {
186+
traceInfo(`Conda env is --prefix environment: ${nativeEnv.prefix}`);
187+
return '';
188+
}
189+
190+
if (condaEnvDirs.length > 0 && isSubDir(nativeEnv.prefix, condaEnvDirs)) {
191+
traceInfo(`Conda env is --named environment: ${nativeEnv.prefix}`);
192+
return path.basename(nativeEnv.prefix);
193+
}
194+
}
195+
169196
return '';
170197
}
171198

172-
function toPythonEnvInfo(nativeEnv: NativeEnvInfo): PythonEnvInfo | undefined {
199+
function toPythonEnvInfo(nativeEnv: NativeEnvInfo, condaEnvDirs: string[]): PythonEnvInfo | undefined {
173200
if (!validEnv(nativeEnv)) {
174201
return undefined;
175202
}
176203
const kind = categoryToKind(nativeEnv.kind);
177204
const arch = toArch(nativeEnv.arch);
178205
const version: PythonVersion = parseVersion(nativeEnv.version ?? '');
179-
const name = getName(nativeEnv, kind);
206+
const name = getName(nativeEnv, kind, condaEnvDirs);
180207
const displayName = nativeEnv.version
181208
? getDisplayName(version, kind, arch, name)
182209
: nativeEnv.displayName ?? 'Python';
@@ -211,6 +238,9 @@ function toPythonEnvInfo(nativeEnv: NativeEnvInfo): PythonEnvInfo | undefined {
211238
}
212239

213240
function hasChanged(old: PythonEnvInfo, newEnv: PythonEnvInfo): boolean {
241+
if (old.name !== newEnv.name) {
242+
return true;
243+
}
214244
if (old.executable.filename !== newEnv.executable.filename) {
215245
return true;
216246
}
@@ -247,6 +277,8 @@ class NativePythonEnvironments implements IDiscoveryAPI, Disposable {
247277

248278
private _disposables: Disposable[] = [];
249279

280+
private _condaEnvDirs: string[] = [];
281+
250282
constructor(private readonly finder: NativePythonFinder) {
251283
this._onProgress = new EventEmitter<ProgressNotificationEvent>();
252284
this._onChanged = new EventEmitter<PythonEnvCollectionChangedEvent>();
@@ -381,7 +413,7 @@ class NativePythonEnvironments implements IDiscoveryAPI, Disposable {
381413
}
382414

383415
private addEnv(native: NativeEnvInfo, searchLocation?: Uri): PythonEnvInfo | undefined {
384-
const info = toPythonEnvInfo(native);
416+
const info = toPythonEnvInfo(native, this._condaEnvDirs);
385417
if (info) {
386418
const old = this._envs.find((item) => item.executable.filename === info.executable.filename);
387419
if (old) {
@@ -417,6 +449,9 @@ class NativePythonEnvironments implements IDiscoveryAPI, Disposable {
417449
}
418450
const native = await this.finder.resolve(envPath);
419451
if (native) {
452+
if (native.kind === NativePythonEnvironmentKind.Conda && this._condaEnvDirs.length === 0) {
453+
this._condaEnvDirs = (await getCondaEnvDirs()) ?? [];
454+
}
420455
return this.addEnv(native);
421456
}
422457
return undefined;

0 commit comments

Comments
 (0)