GeezerVison is showing github.com — Run extension-internal scripts "isolated". (#10941) · Cetlan/vscode-python@77bf701
File treeExpand file treeCollapse file tree Open diff view settings client/common/process/internal/scripts
Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: pythonFiles/pyvsc-run-isolated.py +5-3Lines changed: 5 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 13 | 13 | del sys.path[0] | 14 | 14 | del sys.argv[0] | 15 | 15 | module = sys.argv[0] | 16 | | -if module.endswith(".py"): | 17 | | - runpy.run_path(module) | | 16 | +if module.startswith("-"): | | 17 | + raise NotImplementedError(sys.argv) | | 18 | +elif module.endswith(".py"): | | 19 | + runpy.run_path(module, run_name="__main__") | 18 | 20 | else: | 19 | | - runpy.run_module(module, alter_sys=True) | | 21 | + runpy.run_module(module, run_name="__main__", alter_sys=True) |
Collapse file Copy file name to clipboardExpand all lines: src/client/common/process/internal/scripts/index.ts +13-10Lines changed: 13 additions & 10 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -8,6 +8,8 @@ import { PythonVersionInfo } from '../../types'; | 8 | 8 | // It is simpler to hard-code it instead of using vscode.ExtensionContext.extensionPath. | 9 | 9 | export const _SCRIPTS_DIR = path.join(EXTENSION_ROOT_DIR, 'pythonFiles'); | 10 | 10 | const SCRIPTS_DIR = _SCRIPTS_DIR; | | 11 | +export const _ISOLATED = path.join(_SCRIPTS_DIR, 'pyvsc-run-isolated.py'); | | 12 | +const ISOLATED = _ISOLATED; | 11 | 13 |
| 12 | 14 | // "scripts" contains everything relevant to the scripts found under | 13 | 15 | // the top-level "pythonFiles" directory. Each of those scripts has | @@ -48,7 +50,7 @@ type PythonEnvInfo = { | 48 | 50 |
| 49 | 51 | export function interpreterInfo(): [string[], (out: string) => PythonEnvInfo] { | 50 | 52 | const script = path.join(SCRIPTS_DIR, 'interpreterInfo.py'); | 51 | | - const args = [script]; | | 53 | + const args = [ISOLATED, script]; | 52 | 54 |
| 53 | 55 | function parse(out: string): PythonEnvInfo { | 54 | 56 | let json: PythonEnvInfo; | @@ -158,7 +160,7 @@ namespace _completion { | 158 | 160 |
| 159 | 161 | export function completion(jediPath?: string): [string[], (out: string) => _completion.Response[]] { | 160 | 162 | const script = path.join(SCRIPTS_DIR, 'completion.py'); | 161 | | - const args = [script]; | | 163 | + const args = [ISOLATED, script]; | 162 | 164 | if (jediPath) { | 163 | 165 | args.push('custom'); | 164 | 166 | args.push(jediPath); | @@ -176,7 +178,7 @@ export function completion(jediPath?: string): [string[], (out: string) => _comp | 176 | 178 |
| 177 | 179 | export function sortImports(filename: string, sortArgs?: string[]): [string[], (out: string) => string] { | 178 | 180 | const script = path.join(SCRIPTS_DIR, 'sortImports.py'); | 179 | | - const args = [script, filename, '--diff']; | | 181 | + const args = [ISOLATED, script, filename, '--diff']; | 180 | 182 | if (sortArgs) { | 181 | 183 | args.push(...sortArgs); | 182 | 184 | } | @@ -194,7 +196,7 @@ export function sortImports(filename: string, sortArgs?: string[]): [string[], ( | 194 | 196 |
| 195 | 197 | export function refactor(root: string): [string[], (out: string) => object[]] { | 196 | 198 | const script = path.join(SCRIPTS_DIR, 'refactor.py'); | 197 | | - const args = [script, root]; | | 199 | + const args = [ISOLATED, script, root]; | 198 | 200 |
| 199 | 201 | // tslint:disable-next-line:no-suspicious-comment | 200 | 202 | // TODO: Make the return type more specific, like we did | @@ -216,7 +218,7 @@ export function refactor(root: string): [string[], (out: string) => object[]] { | 216 | 218 |
| 217 | 219 | export function normalizeForInterpreter(code: string): [string[], (out: string) => string] { | 218 | 220 | const script = path.join(SCRIPTS_DIR, 'normalizeForInterpreter.py'); | 219 | | - const args = [script, code]; | | 221 | + const args = [ISOLATED, script, code]; | 220 | 222 |
| 221 | 223 | function parse(out: string) { | 222 | 224 | // The text will be used as-is. | @@ -256,7 +258,7 @@ export function symbolProvider( | 256 | 258 | text?: string | 257 | 259 | ): [string[], (out: string) => _symbolProvider.Symbols] { | 258 | 260 | const script = path.join(SCRIPTS_DIR, 'symbolProvider.py'); | 259 | | - const args = [script, filename]; | | 261 | + const args = [ISOLATED, script, filename]; | 260 | 262 | if (text) { | 261 | 263 | args.push(text); | 262 | 264 | } | @@ -273,7 +275,7 @@ export function symbolProvider( | 273 | 275 |
| 274 | 276 | export function printEnvVariables(): [string[], (out: string) => NodeJS.ProcessEnv] { | 275 | 277 | const script = path.join(SCRIPTS_DIR, 'printEnvVariables.py').fileToCommandArgument(); | 276 | | - const args = [script]; | | 278 | + const args = [ISOLATED, script]; | 277 | 279 |
| 278 | 280 | function parse(out: string): NodeJS.ProcessEnv { | 279 | 281 | return JSON.parse(out); | @@ -287,7 +289,7 @@ export function printEnvVariables(): [string[], (out: string) => NodeJS.ProcessE | 287 | 289 |
| 288 | 290 | export function printEnvVariablesToFile(filename: string): [string[], (out: string) => NodeJS.ProcessEnv] { | 289 | 291 | const script = path.join(SCRIPTS_DIR, 'printEnvVariablesToFile.py'); | 290 | | - const args = [script, filename.fileToCommandArgument()]; | | 292 | + const args = [ISOLATED, script, filename.fileToCommandArgument()]; | 291 | 293 |
| 292 | 294 | function parse(out: string): NodeJS.ProcessEnv { | 293 | 295 | return JSON.parse(out); | @@ -304,6 +306,7 @@ export function shell_exec(command: string, lockfile: string, shellArgs: string[ | 304 | 306 | // We don't bother with a "parse" function since the output | 305 | 307 | // could be anything. | 306 | 308 | return [ | | 309 | + ISOLATED, | 307 | 310 | script, | 308 | 311 | command.fileToCommandArgument(), | 309 | 312 | // The shell args must come after the command | @@ -319,7 +322,7 @@ export function shell_exec(command: string, lockfile: string, shellArgs: string[ | 319 | 322 | export function testlauncher(testArgs: string[]): string[] { | 320 | 323 | const script = path.join(SCRIPTS_DIR, 'testlauncher.py'); | 321 | 324 | // There is no output to parse, so we do not return a function. | 322 | | - return [script, ...testArgs]; | | 325 | + return [ISOLATED, script, ...testArgs]; | 323 | 326 | } | 324 | 327 |
| 325 | 328 | //============================ | @@ -328,5 +331,5 @@ export function testlauncher(testArgs: string[]): string[] { | 328 | 331 | export function visualstudio_py_testlauncher(testArgs: string[]): string[] { | 329 | 332 | const script = path.join(SCRIPTS_DIR, 'visualstudio_py_testlauncher.py'); | 330 | 333 | // There is no output to parse, so we do not return a function. | 331 | | - return [script, ...testArgs]; | | 334 | + return [ISOLATED, script, ...testArgs]; | 332 | 335 | } |
Collapse file Copy file name to clipboardExpand all lines: src/client/common/process/internal/scripts/testing_tools.ts +3Lines changed: 3 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -47,6 +47,9 @@ export type DiscoveredTests = { | 47 | 47 |
| 48 | 48 | export function run_adapter(adapterArgs: string[]): [string[], (out: string) => DiscoveredTests[]] { | 49 | 49 | const script = path.join(SCRIPTS_DIR, 'run_adapter.py'); | | 50 | + // Note that we for now we do not run this "isolated". The | | 51 | + // script relies on some magic that conflicts with the | | 52 | + // isolated script. | 50 | 53 | const args = [script, ...adapterArgs]; | 51 | 54 |
| 52 | 55 | function parse(out: string): DiscoveredTests[] { | |
Collapse file Copy file name to clipboardExpand all lines: src/client/common/process/internal/scripts/vscode_datascience_helpers.ts +7-7Lines changed: 7 additions & 7 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 2 | 2 | // Licensed under the MIT License. | 3 | 3 |
| 4 | 4 | import * as path from 'path'; | 5 | | -import { _SCRIPTS_DIR } from './index'; | | 5 | +import { _ISOLATED as ISOLATED, _SCRIPTS_DIR } from './index'; | 6 | 6 |
| 7 | 7 | const SCRIPTS_DIR = path.join(_SCRIPTS_DIR, 'vscode_datascience_helpers'); | 8 | 8 |
| @@ -12,7 +12,7 @@ const SCRIPTS_DIR = path.join(_SCRIPTS_DIR, 'vscode_datascience_helpers'); | 12 | 12 | export function getJupyterVariableDataFrameInfo(): string[] { | 13 | 13 | const script = path.join(SCRIPTS_DIR, 'getJupyterVariableDataFrameInfo.py'); | 14 | 14 | // There is no script-specific output to parse, so we do not return a function. | 15 | | - return [script]; | | 15 | + return [ISOLATED, script]; | 16 | 16 | } | 17 | 17 |
| 18 | 18 | //============================ | @@ -21,7 +21,7 @@ export function getJupyterVariableDataFrameInfo(): string[] { | 21 | 21 | export function getJupyterVariableDataFrameRows(): string[] { | 22 | 22 | const script = path.join(SCRIPTS_DIR, 'getJupyterVariableDataFrameRows.py'); | 23 | 23 | // There is no script-specific output to parse, so we do not return a function. | 24 | | - return [script]; | | 24 | + return [ISOLATED, script]; | 25 | 25 | } | 26 | 26 |
| 27 | 27 | //============================ | @@ -41,7 +41,7 @@ type JupyterServerInfo = { | 41 | 41 |
| 42 | 42 | export function getServerInfo(): [string[], (out: string) => JupyterServerInfo[]] { | 43 | 43 | const script = path.join(SCRIPTS_DIR, 'getServerInfo.py'); | 44 | | - const args = [script]; | | 44 | + const args = [ISOLATED, script]; | 45 | 45 |
| 46 | 46 | function parse(out: string): JupyterServerInfo[] { | 47 | 47 | return JSON.parse(out.trim()); | @@ -56,7 +56,7 @@ export function getServerInfo(): [string[], (out: string) => JupyterServerInfo[] | 56 | 56 | export function getJupyterKernels(): string[] { | 57 | 57 | const script = path.join(SCRIPTS_DIR, 'getJupyterKernels.py'); | 58 | 58 | // There is no script-specific output to parse, so we do not return a function. | 59 | | - return [script]; | | 59 | + return [ISOLATED, script]; | 60 | 60 | } | 61 | 61 |
| 62 | 62 | //============================ | @@ -65,15 +65,15 @@ export function getJupyterKernels(): string[] { | 65 | 65 | export function getJupyterKernelspecVersion(): string[] { | 66 | 66 | const script = path.join(SCRIPTS_DIR, 'getJupyterKernelspecVersion.py'); | 67 | 67 | // For now we do not worry about parsing the output here. | 68 | | - return [script]; | | 68 | + return [ISOLATED, script]; | 69 | 69 | } | 70 | 70 |
| 71 | 71 | //============================ | 72 | 72 | // jupyter_nbInstalled.py | 73 | 73 |
| 74 | 74 | export function jupyter_nbInstalled(): [string[], (out: string) => boolean] { | 75 | 75 | const script = path.join(SCRIPTS_DIR, 'jupyter_nbInstalled.py'); | 76 | | - const args = [script]; | | 76 | + const args = [ISOLATED, script]; | 77 | 77 |
| 78 | 78 | function parse(out: string): boolean { | 79 | 79 | return out.toLowerCase().includes('available'); | |
Collapse file Copy file name to clipboardExpand all lines: src/test/common/terminals/synchronousTerminalService.unit.test.ts +3Lines changed: 3 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -67,6 +67,7 @@ suite('Terminal Service (synchronous)', () => { | 67 | 67 | }); | 68 | 68 | }); | 69 | 69 | suite('sendCommand', () => { | | 70 | + const isolated = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'pyvsc-run-isolated.py'); | 70 | 71 | const shellExecFile = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'shell_exec.py'); | 71 | 72 |
| 72 | 73 | test('run sendCommand in terminalService if there is no cancellation token', async () => { | @@ -107,6 +108,7 @@ suite('Terminal Service (synchronous)', () => { | 107 | 108 | terminalService.sendCommand( | 108 | 109 | 'python', | 109 | 110 | deepEqual([ | | 111 | + isolated.fileToCommandArgument(), | 110 | 112 | shellExecFile.fileToCommandArgument(), | 111 | 113 | 'cmd'.fileToCommandArgument(), | 112 | 114 | '1', | @@ -149,6 +151,7 @@ suite('Terminal Service (synchronous)', () => { | 149 | 151 | terminalService.sendCommand( | 150 | 152 | 'python', | 151 | 153 | deepEqual([ | | 154 | + isolated.fileToCommandArgument(), | 152 | 155 | shellExecFile.fileToCommandArgument(), | 153 | 156 | 'cmd'.fileToCommandArgument(), | 154 | 157 | '1', | |
Collapse file Copy file name to clipboardExpand all lines: src/test/interpreters/activation/service.unit.test.ts +6-3Lines changed: 6 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -140,10 +140,13 @@ suite('Interpreters Activation - Python Environment Variables', () => { | 140 | 140 |
| 141 | 141 | const shellCmd = capture(processService.shellExec).first()[0]; | 142 | 142 |
| | 143 | + const isolated = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'pyvsc-run-isolated.py'); | 143 | 144 | const printEnvPyFile = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'printEnvVariables.py'); | 144 | | - const expectedCommand = `${cmd.join( | 145 | | - ' && ' | 146 | | - )} && echo '${getEnvironmentPrefix}' && python ${printEnvPyFile.fileToCommandArgument()}`; | | 145 | + const expectedCommand = [ | | 146 | + ...cmd, | | 147 | + `echo '${getEnvironmentPrefix}'`, | | 148 | + `python ${isolated} ${printEnvPyFile.fileToCommandArgument()}` | | 149 | + ].join(' && '); | 147 | 150 |
| 148 | 151 | expect(shellCmd).to.equal(expectedCommand); | 149 | 152 | }); | |
Collapse file Copy file name to clipboardExpand all lines: src/test/interpreters/activation/terminalEnvironmentActivationService.unit.test.ts +6-1Lines changed: 6 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -95,6 +95,7 @@ suite('Interpreters Activation - Python Environment Variables (using terminals)' | 95 | 95 | }); | 96 | 96 | test('Should execute python file in terminal (that is what dumps variables into json)', async () => { | 97 | 97 | when(envVarsProvider.getCustomEnvironmentVariables(resource)).thenResolve(undefined); | | 98 | + const isolated = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'pyvsc-run-isolated.py'); | 98 | 99 | const pyFile = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'printEnvVariablesToFile.py'); | 99 | 100 |
| 100 | 101 | await envActivationService.getActivatedEnvironmentVariables(resource, interpreter); | @@ -103,7 +104,11 @@ suite('Interpreters Activation - Python Environment Variables (using terminals)' | 103 | 104 | verify( | 104 | 105 | terminal.sendCommand( | 105 | 106 | cmd, | 106 | | - deepEqual([pyFile.fileToCommandArgument(), jsonFile.fileToCommandArgument()]), | | 107 | + deepEqual([ | | 108 | + isolated.fileToCommandArgument(), | | 109 | + pyFile.fileToCommandArgument(), | | 110 | + jsonFile.fileToCommandArgument() | | 111 | + ]), | 107 | 112 | anything(), | 108 | 113 | false | 109 | 114 | ) | |
Collapse file Copy file name to clipboardExpand all lines: src/test/providers/importSortProvider.unit.test.ts +3-1Lines changed: 3 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -31,6 +31,8 @@ import { IServiceContainer } from '../../client/ioc/types'; | 31 | 31 | import { SortImportsEditingProvider } from '../../client/providers/importSortProvider'; | 32 | 32 | import { ISortImportsEditingProvider } from '../../client/providers/types'; | 33 | 33 |
| | 34 | +const ISOLATED = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'pyvsc-run-isolated.py'); | | 35 | + | 34 | 36 | suite('Import Sort Provider', () => { | 35 | 37 | let serviceContainer: TypeMoq.IMock<IServiceContainer>; | 36 | 38 | let shell: TypeMoq.IMock<IApplicationShell>; | @@ -398,7 +400,7 @@ suite('Import Sort Provider', () => { | 398 | 400 | .returns(() => Promise.resolve(processExeService.object)) | 399 | 401 | .verifiable(TypeMoq.Times.once()); | 400 | 402 | const importScript = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'sortImports.py'); | 401 | | - const expectedArgs = [importScript, tmpFile.filePath, '--diff', '1', '2']; | | 403 | + const expectedArgs = [ISOLATED, importScript, tmpFile.filePath, '--diff', '1', '2']; | 402 | 404 | processExeService | 403 | 405 | .setup((p) => | 404 | 406 | p.exec(TypeMoq.It.isValue(expectedArgs), TypeMoq.It.isValue({ throwOnStdErr: true, token: undefined })) | |
Collapse file Copy file name to clipboardExpand all lines: src/test/testing/common/debugLauncher.unit.test.ts +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -207,8 +207,8 @@ suite('Unit Tests - Debug Launcher', () => { | 207 | 207 | expected = getDefaultDebugConfig(); | 208 | 208 | } | 209 | 209 | expected.rules = [{ path: path.join(EXTENSION_ROOT_DIR, 'pythonFiles'), include: false }]; | 210 | | - expected.program = testLaunchScript; | 211 | | - expected.args = options.args; | | 210 | + expected.program = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'pyvsc-run-isolated.py'); | | 211 | + expected.args = [testLaunchScript, ...options.args]; | 212 | 212 | if (!expected.cwd) { | 213 | 213 | expected.cwd = workspaceFolders[0].uri.fsPath; | 214 | 214 | } | |
Collapse file Copy file name to clipboardExpand all lines: src/test/testing/navigation/symbolNavigator.unit.test.ts +10-2Lines changed: 10 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -86,7 +86,11 @@ suite('Unit Tests - Navigation Command Handler', () => { | 86 | 86 | }); | 87 | 87 | test('Ensure no symbols are returned when there are no symbols to be returned', async () => { | 88 | 88 | const docUri = Uri.file(__filename); | 89 | | - const args = [path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'symbolProvider.py'), docUri.fsPath]; | | 89 | + const args = [ | | 90 | + path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'pyvsc-run-isolated.py'), | | 91 | + path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'symbolProvider.py'), | | 92 | + docUri.fsPath | | 93 | + ]; | 90 | 94 | const proc: ExecutionResult<string> = { | 91 | 95 | stdout: JSON.stringify({ classes: [], methods: [], functions: [] }) | 92 | 96 | }; | @@ -114,7 +118,11 @@ suite('Unit Tests - Navigation Command Handler', () => { | 114 | 118 | }); | 115 | 119 | test('Ensure symbols are returned', async () => { | 116 | 120 | const docUri = Uri.file(__filename); | 117 | | - const args = [path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'symbolProvider.py'), docUri.fsPath]; | | 121 | + const args = [ | | 122 | + path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'pyvsc-run-isolated.py'), | | 123 | + path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'symbolProvider.py'), | | 124 | + docUri.fsPath | | 125 | + ]; | 118 | 126 | const proc: ExecutionResult<string> = { | 119 | 127 | stdout: JSON.stringify({ | 120 | 128 | classes: [ | |
|