Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove PythonEnvironment property isCondaEnvWithoutPython #15245

Merged
merged 2 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/kernels/errors/kernelErrorHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ import { IInterpreterService } from '../../platform/interpreter/contracts';
import { PackageNotInstalledWindowsLongPathNotEnabledError } from '../../platform/errors/packageNotInstalledWindowsLongPathNotEnabledError';
import { JupyterNotebookNotInstalled } from '../../platform/errors/jupyterNotebookNotInstalled';
import { fileToCommandArgument } from '../../platform/common/helpers';
import { getPythonEnvDisplayName, getSysPrefix } from '../../platform/interpreter/helpers';
import {
getPythonEnvDisplayName,
getSysPrefix,
isCondaEnvironmentWithoutPython
} from '../../platform/interpreter/helpers';
import { JupyterServerCollection } from '../../api';
import { getJupyterDisplayName } from '../jupyter/connection/jupyterServerProviderRegistry';

Expand Down Expand Up @@ -419,14 +423,14 @@ export abstract class DataScienceErrorHandler implements IDataScienceErrorHandle
if (details) {
sendKernelTelemetryEvent(resource, Telemetry.KernelStartFailureDueToMissingEnv, undefined, {
envMissingReason: 'Unknown',
isEmptyCondaEnv: details.isCondaEnvWithoutPython,
isEmptyCondaEnv: isCondaEnvironmentWithoutPython(details),
pythonEnvType: details.envType,
fileExists
});
} else {
sendKernelTelemetryEvent(resource, Telemetry.KernelStartFailureDueToMissingEnv, undefined, {
envMissingReason: 'EmptyEnvDetailsFromPython',
isEmptyCondaEnv: kernelConnection.interpreter.isCondaEnvWithoutPython,
isEmptyCondaEnv: isCondaEnvironmentWithoutPython(kernelConnection.interpreter),
pythonEnvType: kernelConnection.interpreter.envType,
fileExists
});
Expand All @@ -436,7 +440,7 @@ export abstract class DataScienceErrorHandler implements IDataScienceErrorHandle
const fileExists = await this.fs.exists(kernelConnection.interpreter.uri);
sendKernelTelemetryEvent(resource, Telemetry.KernelStartFailureDueToMissingEnv, undefined, {
envMissingReason: 'FailedToGetEnvDetailsFromPython',
isEmptyCondaEnv: kernelConnection.interpreter.isCondaEnvWithoutPython,
isEmptyCondaEnv: isCondaEnvironmentWithoutPython(kernelConnection.interpreter),
pythonEnvType: kernelConnection.interpreter.envType,
fileExists
});
Expand Down
10 changes: 6 additions & 4 deletions src/kernels/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ import { JupyterKernelSpec } from './jupyter/jupyterKernelSpec';
import { sendTelemetryEvent } from '../telemetry';
import { IPlatformService } from '../platform/common/platform/types';
import { splitLines } from '../platform/common/helpers';
import { getCachedVersion, getPythonEnvironmentName } from '../platform/interpreter/helpers';
import {
getCachedVersion,
getPythonEnvironmentName,
isCondaEnvironmentWithoutPython
} from '../platform/interpreter/helpers';
import { cellOutputToVSCCellOutput } from './execution/helpers';
import { handleTensorBoardDisplayDataOutput } from './execution/executionHelpers';
import { once } from '../platform/common/utils/functional';
Expand Down Expand Up @@ -291,9 +295,7 @@ export function getDisplayNameOrNameOfKernelConnection(kernelConnection: KernelC
return kernelConnection.kernelSpec.display_name;
}
// If this is a conda environment without Python, then don't display `Python` in it.
const isCondaEnvWithoutPython =
kernelConnection.interpreter.envType === EnvironmentType.Conda &&
kernelConnection.interpreter.isCondaEnvWithoutPython === true;
const isCondaEnvWithoutPython = isCondaEnvironmentWithoutPython(kernelConnection.interpreter);
const pythonDisplayName = pythonVersion.trim() ? `Python ${pythonVersion}` : 'Python';
const envName = getPythonEnvironmentName(kernelConnection.interpreter);
if (isCondaEnvWithoutPython && envName) {
Expand Down
18 changes: 12 additions & 6 deletions src/kernels/helpers.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,8 @@ suite('Kernel Connection Helpers', () => {
micro: 7,
release: undefined,
sysVersion: '9.8.7.6-pre'
}
},
tools: []
} as any
]);
const name = getDisplayNameOrNameOfKernelConnection(
Expand Down Expand Up @@ -376,7 +377,8 @@ suite('Kernel Connection Helpers', () => {
micro: 7,
release: undefined,
sysVersion: '9.8.7'
}
},
tools: []
} as any
]);
const name = getDisplayNameOrNameOfKernelConnection(
Expand Down Expand Up @@ -455,7 +457,8 @@ suite('Kernel Connection Helpers', () => {
micro: 3,
release: undefined,
sysVersion: '1.2.3'
}
},
tools: []
} as any
]);
const name = getDisplayNameOrNameOfKernelConnection(
Expand Down Expand Up @@ -540,7 +543,8 @@ suite('Kernel Connection Helpers', () => {
micro: 7,
release: undefined,
sysVersion: '9.8.7.6-pre'
}
},
tools: []
} as any
]);

Expand Down Expand Up @@ -570,7 +574,8 @@ suite('Kernel Connection Helpers', () => {
micro: 7,
release: undefined,
sysVersion: '9.8.7.6-pre'
}
},
tools: []
} as any
]);

Expand Down Expand Up @@ -600,7 +605,8 @@ suite('Kernel Connection Helpers', () => {
micro: 7,
release: undefined,
sysVersion: '9.8.7.6-pre'
}
},
tools: []
} as any
]);

Expand Down
3 changes: 2 additions & 1 deletion src/kernels/raw/finder/localKernelSpecFinderBase.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { getComparisonKey } from '../../../platform/vscode-path/resources';
import { PromiseMonitor } from '../../../platform/common/utils/promises';
import { dispose } from '../../../platform/common/utils/lifecycle';
import { JupyterPaths } from './jupyterPaths.node';
import { isCondaEnvironmentWithoutPython } from '../../../platform/interpreter/helpers';

export type KernelSpecFileWithContainingInterpreter = { interpreter?: PythonEnvironment; kernelSpecFile: Uri };
export const isDefaultPythonKernelSpecSpecName = /python\s\d*.?\d*$/;
Expand Down Expand Up @@ -386,7 +387,7 @@ export async function loadKernelSpec(

// Possible user deleted the underlying interpreter.
const interpreterPath = interpreter?.uri.fsPath || kernelJson?.metadata?.interpreter?.path;
const isEmptyCondaEnv = interpreter?.isCondaEnvWithoutPython ? true : false;
const isEmptyCondaEnv = isCondaEnvironmentWithoutPython(interpreter);
if (interpreterPath && !isEmptyCondaEnv && !(await fs.exists(Uri.file(interpreterPath)))) {
return;
}
Expand Down
6 changes: 5 additions & 1 deletion src/notebooks/controllers/connectionDisplayData.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
} from './connectionDisplayData';
import { DataScience } from '../../platform/common/utils/localize';
import { getJupyterDisplayName } from '../../kernels/jupyter/connection/jupyterServerProviderRegistry';
import { isCondaEnvironmentWithoutPython } from '../../platform/interpreter/helpers';

@injectable()
export class ConnectionDisplayDataProvider implements IConnectionDisplayDataProvider {
Expand Down Expand Up @@ -57,7 +58,10 @@ export class ConnectionDisplayDataProvider implements IConnectionDisplayDataProv
this.details.set(connection.id, newDetails);

// If the interpreter information changes, then update the display data.
if (connection.kind === 'startUsingPythonInterpreter' && connection.interpreter.isCondaEnvWithoutPython) {
if (
connection.kind === 'startUsingPythonInterpreter' &&
isCondaEnvironmentWithoutPython(connection.interpreter)
) {
const updateInterpreterInfo = (e: PythonEnvironment[]) => {
const changedEnv = e.find((env) => env.id === connection.interpreter?.id);
const interpreter = this.interpreters.resolvedEnvironments.find((env) => env.id === changedEnv?.id);
Expand Down
3 changes: 2 additions & 1 deletion src/notebooks/controllers/connectionDisplayData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { IDisposable } from '../../platform/common/types';
import { DataScience } from '../../platform/common/utils/localize';
import { EnvironmentType } from '../../platform/pythonEnvironments/info';
import { IConnectionDisplayData } from './types';
import { isCondaEnvironmentWithoutPython } from '../../platform/interpreter/helpers';

export class ConnectionDisplayData implements IDisposable, IConnectionDisplayData {
private readonly _onDidChange = new EventEmitter<ConnectionDisplayData>();
Expand Down Expand Up @@ -57,7 +58,7 @@ export function getKernelConnectionCategorySync(kernelConnection: KernelConnecti
}
switch (kernelConnection.interpreter.envType) {
case EnvironmentType.Conda:
return kernelConnection.interpreter.isCondaEnvWithoutPython
return isCondaEnvironmentWithoutPython(kernelConnection.interpreter)
? DataScience.kernelCategoryForCondaWithoutPython
: DataScience.kernelCategoryForConda;
case EnvironmentType.Pipenv:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
IVSCodeNotebookController
} from '../types';
import { JupyterServerCollection } from '../../../api';
import { isCondaEnvironmentWithoutPython } from '../../../platform/interpreter/helpers';

@injectable()
export class KernelSourceCommandHandler implements IExtensionSyncActivationService {
Expand Down Expand Up @@ -294,7 +295,7 @@ export class KernelSourceCommandHandler implements IExtensionSyncActivationServi
if (
isLocalConnection(controller.connection) &&
isPythonKernelConnection(controller.connection) &&
controller.connection.interpreter?.isCondaEnvWithoutPython &&
isCondaEnvironmentWithoutPython(controller.connection.interpreter) &&
!isWebExtension()
) {
const disposables: IDisposable[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,7 @@ export class LocalPythonEnvNotebookKernelSourceSelector
);
}
private async buildDummyEnvironment(e: Environment) {
const displayEmptyCondaEnv =
this.pythonApi.pythonExtensionVersion &&
this.pythonApi.pythonExtensionVersion.compare('2023.3.10341119') >= 0;
const interpreter = pythonEnvToJupyterEnv(e, displayEmptyCondaEnv === true);
const interpreter = pythonEnvToJupyterEnv(e);
if (!interpreter || this.filter.isPythonEnvironmentExcluded(interpreter)) {
return;
}
Expand Down
25 changes: 12 additions & 13 deletions src/platform/api/pythonApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ import { PythonExtensionActicationFailedError } from '../errors/pythonExtActivat
import { PythonExtensionApiNotExportedError } from '../errors/pythonExtApiNotExportedError';
import { getOSType, OSType } from '../common/utils/platform';
import { SemVer } from 'semver';
import { getCachedVersion, getEnvironmentType, setPythonApi } from '../interpreter/helpers';
import {
getCachedVersion,
getEnvironmentType,
isCondaEnvironmentWithoutPython,
setPythonApi
} from '../interpreter/helpers';
import { getWorkspaceFolderIdentifier } from '../common/application/workspace.base';

export function deserializePythonEnvironment(
Expand Down Expand Up @@ -96,12 +101,10 @@ export function resolvedPythonEnvToJupyterEnv(
envType = EnvironmentType.VirtualEnv;
}
}
let isCondaEnvWithoutPython = false;
let uri: Uri;
let id = env.id;
if (!env.executable.uri) {
if (envType === EnvironmentType.Conda && supportsEmptyCondaEnv) {
isCondaEnvWithoutPython = true;
uri =
getOSType() === OSType.Windows
? Uri.joinPath(env.environment?.folderUri || Uri.file(env.path), 'python.exe')
Expand All @@ -121,18 +124,15 @@ export function resolvedPythonEnvToJupyterEnv(
envName: env.environment?.name || '',
uri,
displayName: env.environment?.name || '',
envType,
isCondaEnvWithoutPython
envType
};
}
export function pythonEnvToJupyterEnv(env: Environment, supportsEmptyCondaEnv: boolean): PythonEnvironment | undefined {
export function pythonEnvToJupyterEnv(env: Environment): PythonEnvironment | undefined {
const envType = getEnvironmentType(env);
let isCondaEnvWithoutPython = false;
let uri: Uri;
let id = env.id;
if (!env.executable.uri) {
if (envType === EnvironmentType.Conda && supportsEmptyCondaEnv) {
isCondaEnvWithoutPython = true;
if (envType === EnvironmentType.Conda) {
uri =
getOSType() === OSType.Windows
? Uri.joinPath(env.environment?.folderUri || Uri.file(env.path), 'python.exe')
Expand All @@ -152,8 +152,7 @@ export function pythonEnvToJupyterEnv(env: Environment, supportsEmptyCondaEnv: b
envName: env.environment?.name || '',
uri,
displayName: env.environment?.name || '',
envType,
isCondaEnvWithoutPython
envType
};
}

Expand Down Expand Up @@ -873,7 +872,7 @@ export class InterpreterService implements IInterpreterService {
// & subsequently updated as having python then trigger changes.
const pythonInstalledIntoConda =
e.type === 'update' &&
this._interpreters.get(e.env.id)?.resolved.isCondaEnvWithoutPython &&
isCondaEnvironmentWithoutPython(this._interpreters.get(e.env.id)?.resolved) &&
e.env.executable.uri
? true
: false;
Expand All @@ -888,7 +887,7 @@ export class InterpreterService implements IInterpreterService {
e.type === 'update' &&
info &&
pythonInstalledIntoConda &&
!info.resolved.isCondaEnvWithoutPython
!isCondaEnvironmentWithoutPython(info.resolved)
) {
this.triggerEventIfAllowed('interpreterChangeEvent', info.resolved);
this.triggerEventIfAllowed('interpretersChangeEvent', info.resolved);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export class EnvironmentActivationService implements IEnvironmentActivationServi
api
.getActivatedEnvironmentVariables(
resource,
serializePythonEnvironment(pythonEnvToJupyterEnv(environment, true))!,
serializePythonEnvironment(pythonEnvToJupyterEnv(environment))!,
false
)
.catch((ex) => {
Expand Down
21 changes: 14 additions & 7 deletions src/platform/interpreter/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ export function getPythonEnvDisplayName(interpreter: PythonEnvironment | Environ
}
const pythonVersion = getTelemetrySafeVersion(getCachedVersion(interpreter) || '').trim();
// If this is a conda environment without Python, then don't display `Python` in it.
const isCondaEnvWithoutPython =
interpreter.envType === EnvironmentType.Conda && interpreter.isCondaEnvWithoutPython === true;
const isCondaEnvWithoutPython = isCondaEnvironmentWithoutPython(interpreter);
const nameWithVersion = pythonVersion ? `Python ${pythonVersion}` : 'Python';
const envName = getPythonEnvironmentName(interpreter);
if (isCondaEnvWithoutPython && envName) {
Expand Down Expand Up @@ -100,10 +99,6 @@ export function getEnvironmentType(env: Environment): EnvironmentType {
return EnvironmentType.Unknown;
}

export function isCondaEnvironmentWithoutPython(env: Environment) {
return getEnvironmentType(env) === EnvironmentType.Conda && !env.executable.uri;
}

export async function getInterpreterInfo(interpreter?: { id: string }) {
if (!interpreter?.id) {
return;
Expand All @@ -117,7 +112,19 @@ export function setPythonApi(api: PythonExtension) {
pythonApi = api;
}

export function getCachedInterpreterInfo(interpreter?: { id: string }) {
export function isCondaEnvironmentWithoutPython(interpreter?: { id: string }) {
if (!interpreter) {
return false;
}
if (!pythonApi) {
return false;
}

const env = getCachedInterpreterInfo(interpreter);
return env && getEnvironmentType(env) === EnvironmentType.Conda && !env.executable.uri;
}

function getCachedInterpreterInfo(interpreter?: { id: string }) {
if (!interpreter) {
return;
}
Expand Down
11 changes: 2 additions & 9 deletions src/platform/interpreter/installer/condaInstaller.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,14 @@ export class CondaInstaller extends ModuleInstaller {

// If we just installed a package into a conda env without python init, then Python may have gotten installed
// We now need to ensure the conda env gets updated as a result of this.
if (
('executable' in interpreter
? getEnvironmentType(interpreter)
: interpreter.envType === EnvironmentType.Conda) &&
('executable' in interpreter
? isCondaEnvironmentWithoutPython(interpreter)
: interpreter.isCondaEnvWithoutPython)
) {
if (isCondaEnvironmentWithoutPython(interpreter)) {
const pythonExt = this.serviceContainer.get<IPythonExtensionChecker>(IPythonExtensionChecker);
if (!pythonExt.isPythonExtensionActive) {
return;
}
const interpreterService = this.serviceContainer.get<IInterpreterService>(IInterpreterService);
const updatedCondaEnv = await interpreterService.getInterpreterDetails(interpreter.id);
if (updatedCondaEnv && !updatedCondaEnv.isCondaEnvWithoutPython) {
if (updatedCondaEnv && !isCondaEnvironmentWithoutPython(updatedCondaEnv)) {
Object.assign(interpreter, updatedCondaEnv);
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/platform/interpreter/installer/productInstaller.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,6 @@ export class DataScienceInstaller {
if (cancelTokenSource.token.isCancellationRequested) {
return InstallerResponse.Cancelled;
}
if (interpreter.isCondaEnvWithoutPython) {
interpreter.isCondaEnvWithoutPython = false;
}
return this.isInstalled(product, interpreter).then((isInstalled) => {
return isInstalled ? InstallerResponse.Installed : InstallerResponse.Ignore;
});
Expand Down
3 changes: 2 additions & 1 deletion src/platform/interpreter/interpreterPackages.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { getDisplayPath } from '../common/platform/fs-paths.node';
import { IInterpreterPackages } from './types';
import { IPythonExecutionFactory } from './types.node';
import { getWorkspaceFolderIdentifier } from '../common/application/workspace.base';
import { isCondaEnvironmentWithoutPython } from './helpers';

const interestedPackages = new Set(
[
Expand Down Expand Up @@ -178,7 +179,7 @@ export class InterpreterPackages implements IInterpreterPackages {
}

private async getPackageInformation({ interpreter }: { interpreter: PythonEnvironment }) {
if (interpreter.isCondaEnvWithoutPython) {
if (isCondaEnvironmentWithoutPython(interpreter)) {
return;
}
const service = await this.executionFactory.createActivatedEnvironment({
Expand Down
Loading
Loading