Skip to content
Draft
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
1 change: 1 addition & 0 deletions src/common/localize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export namespace Common {
export const ok = l10n.t('Ok');
export const quickCreate = l10n.t('Quick Create');
export const installPython = l10n.t('Install Python');
export const pythonNotFound = l10n.t('Python is not installed or not found in PATH. Please install Python to run Python files.');
}

export namespace WorkbenchStrings {
Expand Down
15 changes: 15 additions & 0 deletions src/common/utils/executableExists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import which from 'which';

/**
* Checks if an executable exists in the system PATH.
* @param executable The name or path of the executable to check.
* @returns A promise that resolves to true if the executable exists, false otherwise.
*/
export async function executableExists(executable: string): Promise<boolean> {
try {
await which(executable);
return true;
} catch (_err) {
return false;
}
}
9 changes: 9 additions & 0 deletions src/features/execution/runInBackground.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import * as cp from 'child_process';
import { PythonEnvironment, PythonBackgroundRunOptions, PythonProcess } from '../../api';
import { showErrorMessage } from '../../common/window.apis';
import { executableExists } from '../../common/utils/executableExists';
import { Common } from '../../common/localize';

export async function runInBackground(
environment: PythonEnvironment,
Expand All @@ -10,6 +13,12 @@ export async function runInBackground(
const args = environment.execInfo?.activatedRun?.args ?? environment.execInfo?.run.args ?? [];
const allArgs = [...args, ...options.args];

// Check if the Python executable exists
if (!(await executableExists(executable))) {
await showErrorMessage(Common.pythonNotFound, { modal: true }, Common.installPython);
throw new Error(Common.pythonNotFound);
}

const proc = cp.spawn(executable, allArgs, { stdio: 'pipe', cwd: options.cwd, env: options.env });

return {
Expand Down
10 changes: 9 additions & 1 deletion src/features/terminal/runInTerminal.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Terminal, TerminalShellExecution } from 'vscode';
import { PythonEnvironment, PythonTerminalExecutionOptions } from '../../api';
import { onDidEndTerminalShellExecution } from '../../common/window.apis';
import { onDidEndTerminalShellExecution, showErrorMessage } from '../../common/window.apis';
import { createDeferred } from '../../common/utils/deferred';
import { quoteArgs } from '../execution/execUtils';
import { identifyTerminalShell } from '../common/shellDetector';
import { ShellConstants } from '../common/shellConstants';
import { executableExists } from '../../common/utils/executableExists';
import { Common } from '../../common/localize';

export async function runInTerminal(
environment: PythonEnvironment,
Expand All @@ -20,6 +22,12 @@ export async function runInTerminal(
const args = environment.execInfo?.activatedRun?.args ?? environment.execInfo?.run.args ?? [];
const allArgs = [...args, ...(options.args ?? [])];

// Check if the Python executable exists
if (!(await executableExists(executable))) {
await showErrorMessage(Common.pythonNotFound, { modal: true }, Common.installPython);
return;
}

if (terminal.shellIntegration) {
let execution: TerminalShellExecution | undefined;
const deferred = createDeferred<void>();
Expand Down