Skip to content

Commit 4153f7c

Browse files
authored
Fix: Don’t use executeCommand on python sub-shell for windows. (#24542)
Related: #24418 Further resolves: #24422 Shell integration does not exist on windows python repl so dont use execute command on python subshell in this case. This will prevent keyboard interrupt from happening even when setting for shell integration is enabled for python shell (which is currently only supported on mac and linux)
1 parent eab8794 commit 4153f7c

File tree

15 files changed

+46
-22
lines changed

15 files changed

+46
-22
lines changed

src/client/common/configSettings.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ import {
3636
} from './types';
3737
import { debounceSync } from './utils/decorators';
3838
import { SystemVariables } from './variables/systemVariables';
39-
import { getOSType, OSType } from './utils/platform';
40-
import { isWindows } from './platform/platformService';
39+
import { getOSType, OSType, isWindows } from './utils/platform';
4140
import { untildify } from './helpers';
4241

4342
export class PythonSettings implements IPythonSettings {

src/client/common/pipes/namedPipes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import * as path from 'path';
1010
import * as rpc from 'vscode-jsonrpc/node';
1111
import { CancellationError, CancellationToken, Disposable } from 'vscode';
1212
import { traceVerbose } from '../../logging';
13-
import { isWindows } from '../platform/platformService';
13+
import { isWindows } from '../utils/platform';
1414
import { createDeferred } from '../utils/async';
1515

1616
const { XDG_RUNTIME_DIR } = process.env;

src/client/common/platform/platformService.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { injectable } from 'inversify';
77
import * as os from 'os';
88
import { coerce, SemVer } from 'semver';
99
import { getSearchPathEnvVarNames } from '../utils/exec';
10-
import { Architecture, getArchitecture, getOSType, OSType } from '../utils/platform';
10+
import { Architecture, getArchitecture, getOSType, isWindows, OSType } from '../utils/platform';
1111
import { parseSemVerSafe } from '../utils/version';
1212
import { IPlatformService } from './types';
1313

@@ -73,7 +73,3 @@ export class PlatformService implements IPlatformService {
7373
return getArchitecture() === Architecture.x64;
7474
}
7575
}
76-
77-
export function isWindows(): boolean {
78-
return getOSType() === OSType.Windows;
79-
}

src/client/common/serviceRegistry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ import { Random } from './utils/random';
8888
import { ContextKeyManager } from './application/contextKeyManager';
8989
import { CreatePythonFileCommandHandler } from './application/commands/createPythonFile';
9090
import { RequireJupyterPrompt } from '../jupyter/requireJupyterPrompt';
91-
import { isWindows } from './platform/platformService';
91+
import { isWindows } from './utils/platform';
9292
import { PixiActivationCommandProvider } from './terminal/environmentActivationProviders/pixiActivationProvider';
9393

9494
export function registerTypes(serviceManager: IServiceManager): void {

src/client/common/terminal/service.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
} from './types';
2222
import { traceVerbose } from '../../logging';
2323
import { getConfiguration } from '../vscodeApis/workspaceApis';
24+
import { isWindows } from '../utils/platform';
2425

2526
@injectable()
2627
export class TerminalService implements ITerminalService, Disposable {
@@ -104,7 +105,7 @@ export class TerminalService implements ITerminalService, Disposable {
104105

105106
const config = getConfiguration('python');
106107
const pythonrcSetting = config.get<boolean>('terminal.shellIntegration.enabled');
107-
if (isPythonShell && !pythonrcSetting) {
108+
if ((isPythonShell && !pythonrcSetting) || (isPythonShell && isWindows())) {
108109
// If user has explicitly disabled SI for Python, use sendText for inside Terminal REPL.
109110
terminal.sendText(commandLine);
110111
return undefined;

src/client/common/utils/platform.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,7 @@ export function getUserHomeDir(): string | undefined {
6767
}
6868
return getEnvironmentVariable('HOME') || getEnvironmentVariable('HOMEPATH');
6969
}
70+
71+
export function isWindows(): boolean {
72+
return getOSType() === OSType.Windows;
73+
}

src/client/pythonEnvironments/base/locators/common/nativePythonFinder.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ import * as path from 'path';
77
import * as rpc from 'vscode-jsonrpc/node';
88
import { PassThrough } from 'stream';
99
import * as fs from '../../../../common/platform/fs-paths';
10-
import { isWindows } from '../../../../common/platform/platformService';
10+
import { isWindows, getUserHomeDir } from '../../../../common/utils/platform';
1111
import { EXTENSION_ROOT_DIR } from '../../../../constants';
1212
import { createDeferred, createDeferredFrom } from '../../../../common/utils/async';
1313
import { DisposableBase, DisposableStore } from '../../../../common/utils/resourceLifecycle';
1414
import { noop } from '../../../../common/utils/misc';
1515
import { getConfiguration, getWorkspaceFolderPaths, isTrusted } from '../../../../common/vscodeApis/workspaceApis';
1616
import { CONDAPATH_SETTING_KEY } from '../../../common/environmentManagers/conda';
1717
import { VENVFOLDERS_SETTING_KEY, VENVPATH_SETTING_KEY } from '../lowLevel/customVirtualEnvLocator';
18-
import { getUserHomeDir } from '../../../../common/utils/platform';
1918
import { createLogOutputChannel } from '../../../../common/vscodeApis/windowApis';
2019
import { sendNativeTelemetry, NativePythonTelemetry } from './nativePythonTelemetry';
2120
import { NativePythonEnvironmentKind } from './nativePythonUtils';

src/client/pythonEnvironments/base/locators/common/pythonWatcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import { Disposable, Event, EventEmitter, GlobPattern, RelativePattern, Uri, WorkspaceFolder } from 'vscode';
55
import { createFileSystemWatcher, getWorkspaceFolder } from '../../../../common/vscodeApis/workspaceApis';
6-
import { isWindows } from '../../../../common/platform/platformService';
6+
import { isWindows } from '../../../../common/utils/platform';
77
import { arePathsSame } from '../../../common/externalDependencies';
88
import { FileChangeType } from '../../../../common/platform/fileSystemWatcher';
99

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@
66
import * as path from 'path';
77
import { readJSON } from 'fs-extra';
88
import which from 'which';
9-
import { getUserHomeDir } from '../../../common/utils/platform';
9+
import { getUserHomeDir, isWindows } from '../../../common/utils/platform';
1010
import { exec, getPythonSetting, onDidChangePythonSetting, pathExists } from '../externalDependencies';
1111
import { cache } from '../../../common/utils/decorators';
1212
import { traceVerbose, traceWarn } from '../../../logging';
1313
import { OUTPUT_MARKER_SCRIPT } from '../../../common/process/internal/scripts';
14-
import { isWindows } from '../../../common/platform/platformService';
1514
import { IDisposableRegistry } from '../../../common/types';
1615
import { getWorkspaceFolderPaths } from '../../../common/vscodeApis/workspaceApis';
1716
import { isTestExecution } from '../../../common/constants';

src/client/pythonEnvironments/creation/common/commonUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Commands } from '../../../common/constants';
77
import { Common } from '../../../common/utils/localize';
88
import { executeCommand } from '../../../common/vscodeApis/commandApis';
99
import { showErrorMessage } from '../../../common/vscodeApis/windowApis';
10-
import { isWindows } from '../../../common/platform/platformService';
10+
import { isWindows } from '../../../common/utils/platform';
1111

1212
export async function showErrorMessageWithLogs(message: string): Promise<void> {
1313
const result = await showErrorMessage(message, Common.openOutputPanel, Common.selectPythonInterpreter);

src/client/pythonEnvironments/creation/provider/venvUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
import { findFiles } from '../../../common/vscodeApis/workspaceApis';
2727
import { traceError, traceVerbose } from '../../../logging';
2828
import { Commands } from '../../../common/constants';
29-
import { isWindows } from '../../../common/platform/platformService';
29+
import { isWindows } from '../../../common/utils/platform';
3030
import { getVenvPath, hasVenv } from '../common/commonUtils';
3131
import { deleteEnvironmentNonWindows, deleteEnvironmentWindows } from './venvDeleteUtils';
3232

src/test/common/configSettings.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as vscode from 'vscode';
44
import { SystemVariables } from '../../client/common/variables/systemVariables';
55
import { getExtensionSettings } from '../extensionSettings';
66
import { initialize } from './../initialize';
7-
import { isWindows } from '../../client/common/platform/platformService';
7+
import { isWindows } from '../../client/common/utils/platform';
88

99
const workspaceRoot = path.join(__dirname, '..', '..', '..', 'src', 'test');
1010

src/test/common/terminals/service.unit.test.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { IServiceContainer } from '../../../client/ioc/types';
2424
import { ITerminalAutoActivation } from '../../../client/terminals/types';
2525
import { createPythonInterpreter } from '../../utils/interpreters';
2626
import * as workspaceApis from '../../../client/common/vscodeApis/workspaceApis';
27+
import * as platform from '../../../client/common/utils/platform';
2728

2829
suite('Terminal Service', () => {
2930
let service: TerminalService;
@@ -42,6 +43,7 @@ suite('Terminal Service', () => {
4243
let getConfigurationStub: sinon.SinonStub;
4344
let pythonConfig: TypeMoq.IMock<WorkspaceConfiguration>;
4445
let editorConfig: TypeMoq.IMock<WorkspaceConfiguration>;
46+
let isWindowsStub: sinon.SinonStub;
4547

4648
setup(() => {
4749
terminal = TypeMoq.Mock.ofType<VSCodeTerminal>();
@@ -94,6 +96,7 @@ suite('Terminal Service', () => {
9496
mockServiceContainer.setup((c) => c.get(ITerminalActivator)).returns(() => terminalActivator.object);
9597
mockServiceContainer.setup((c) => c.get(ITerminalAutoActivation)).returns(() => terminalAutoActivator.object);
9698
getConfigurationStub = sinon.stub(workspaceApis, 'getConfiguration');
99+
isWindowsStub = sinon.stub(platform, 'isWindows');
97100
pythonConfig = TypeMoq.Mock.ofType<WorkspaceConfiguration>();
98101
editorConfig = TypeMoq.Mock.ofType<WorkspaceConfiguration>();
99102
getConfigurationStub.callsFake((section: string) => {
@@ -231,7 +234,8 @@ suite('Terminal Service', () => {
231234
terminal.verify((t) => t.sendText(TypeMoq.It.isValue(textToSend)), TypeMoq.Times.exactly(1));
232235
});
233236

234-
test('Ensure sendText is NOT called when Python shell integration and terminal shell integration are both enabled', async () => {
237+
test('Ensure sendText is NOT called when Python shell integration and terminal shell integration are both enabled - Mac, Linux', async () => {
238+
isWindowsStub.returns(false);
235239
pythonConfig
236240
.setup((p) => p.get('terminal.shellIntegration.enabled'))
237241
.returns(() => true)
@@ -252,6 +256,28 @@ suite('Terminal Service', () => {
252256
terminal.verify((t) => t.sendText(TypeMoq.It.isValue(textToSend)), TypeMoq.Times.never());
253257
});
254258

259+
test('Ensure sendText IS called even when Python shell integration and terminal shell integration are both enabled - Window', async () => {
260+
isWindowsStub.returns(true);
261+
pythonConfig
262+
.setup((p) => p.get('terminal.shellIntegration.enabled'))
263+
.returns(() => true)
264+
.verifiable(TypeMoq.Times.once());
265+
266+
terminalHelper
267+
.setup((helper) => helper.getEnvironmentActivationCommands(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
268+
.returns(() => Promise.resolve(undefined));
269+
service = new TerminalService(mockServiceContainer.object);
270+
const textToSend = 'Some Text';
271+
terminalHelper.setup((h) => h.identifyTerminalShell(TypeMoq.It.isAny())).returns(() => TerminalShellType.bash);
272+
terminalManager.setup((t) => t.createTerminal(TypeMoq.It.isAny())).returns(() => terminal.object);
273+
274+
service.ensureTerminal();
275+
service.executeCommand(textToSend, true);
276+
277+
terminal.verify((t) => t.show(TypeMoq.It.isValue(true)), TypeMoq.Times.exactly(1));
278+
terminal.verify((t) => t.sendText(TypeMoq.It.isValue(textToSend)), TypeMoq.Times.exactly(1));
279+
});
280+
255281
test('Ensure terminal is not shown if `hideFromUser` option is set to `true`', async () => {
256282
terminalHelper
257283
.setup((helper) => helper.getEnvironmentActivationCommands(TypeMoq.It.isAny(), TypeMoq.It.isAny()))

src/test/pythonEnvironments/nativeAPI.unit.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ import {
1313
NativeEnvManagerInfo,
1414
NativePythonFinder,
1515
} from '../../client/pythonEnvironments/base/locators/common/nativePythonFinder';
16-
import { Architecture } from '../../client/common/utils/platform';
16+
import { Architecture, isWindows } from '../../client/common/utils/platform';
1717
import { PythonEnvInfo, PythonEnvKind, PythonEnvType } from '../../client/pythonEnvironments/base/info';
18-
import { isWindows } from '../../client/common/platform/platformService';
1918
import { NativePythonEnvironmentKind } from '../../client/pythonEnvironments/base/locators/common/nativePythonUtils';
2019
import * as condaApi from '../../client/pythonEnvironments/common/environmentManagers/conda';
2120
import * as pyenvApi from '../../client/pythonEnvironments/common/environmentManagers/pyenv';

src/test/serviceRegistry.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import * as TypeMoq from 'typemoq';
77
import { Disposable, Memento } from 'vscode';
88
import { FileSystem } from '../client/common/platform/fileSystem';
99
import { PathUtils } from '../client/common/platform/pathUtils';
10-
import { PlatformService, isWindows } from '../client/common/platform/platformService';
10+
import { PlatformService } from '../client/common/platform/platformService';
11+
import { isWindows } from '../client/common/utils/platform';
1112
import { RegistryImplementation } from '../client/common/platform/registry';
1213
import { registerTypes as platformRegisterTypes } from '../client/common/platform/serviceRegistry';
1314
import { IFileSystem, IPlatformService, IRegistry } from '../client/common/platform/types';

0 commit comments

Comments
 (0)