Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
ecc1ca9
Fix Microsoft/vscode#37627 (#1368)
octref Nov 3, 2017
7c5778c
Version 0.7.0 of extension (#1381)
DonJayamanne Nov 9, 2017
9d1bf82
Update README.md
DonJayamanne Nov 9, 2017
ffba179
Update README.md
DonJayamanne Nov 9, 2017
905c713
sync fork with upstream
DonJayamanne Nov 10, 2017
acc2109
fix readme
DonJayamanne Nov 10, 2017
d470523
Merge branch 'master' of https://github.com/Microsoft/vscode-python
DonJayamanne Nov 16, 2017
d392e8b
merged upstream
DonJayamanne Nov 16, 2017
92f775f
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 20, 2017
32a6e53
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 21, 2017
4b30f2c
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 22, 2017
e396752
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 22, 2017
eff4792
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
4553c28
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
3c6520a
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
966e516
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
63d2d65
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
f6d469e
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 28, 2017
029e055
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 30, 2017
e8c71c0
Merge remote-tracking branch 'upstream/master'
DonJayamanne Nov 30, 2017
51cf9d2
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 1, 2017
7aadc43
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 1, 2017
f0f5c59
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 4, 2017
b2b9da9
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 4, 2017
30a4091
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 5, 2017
b16d2f9
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 6, 2017
c8db345
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 7, 2017
0df7f16
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 8, 2017
3ccc881
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 9, 2017
bb0709e
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 11, 2017
2c19004
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 11, 2017
8f224ab
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 11, 2017
41b7080
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 12, 2017
dab38dc
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 12, 2017
ae22dd4
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 12, 2017
d2340d2
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 14, 2017
bcb8879
use new exec engine instead of spawning manually
DonJayamanne Dec 14, 2017
c6d6f50
refactor to use new execution framework
DonJayamanne Dec 15, 2017
65a949b
refactor to use new exec framework
DonJayamanne Dec 15, 2017
c8559ea
fix linter errors
DonJayamanne Dec 15, 2017
51a2802
refactor
DonJayamanne Dec 15, 2017
c778493
disable messages and copy config files
DonJayamanne Dec 15, 2017
a34a62c
remove old execution layer
DonJayamanne Dec 15, 2017
9452d0e
misc
DonJayamanne Dec 15, 2017
52bb7ae
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 15, 2017
5760886
merged master
DonJayamanne Dec 15, 2017
1714f0c
Merge branch 'D' into FixDebuggerEnvVars
DonJayamanne Dec 15, 2017
1bdc95d
fix tests
DonJayamanne Dec 15, 2017
0313000
fix tests
DonJayamanne Dec 15, 2017
e7eb19e
disable message D102
DonJayamanne Dec 15, 2017
d09b3ef
fix bug introduced into test
DonJayamanne Dec 15, 2017
0467d4c
fix tests
DonJayamanne Dec 15, 2017
ffdfd5d
fixed code review comments
DonJayamanne Dec 15, 2017
59ff402
added tests for env variable parsing
DonJayamanne Dec 16, 2017
bab860f
remove metadata
DonJayamanne Dec 18, 2017
b6b2531
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 19, 2017
2b21cec
merged master
DonJayamanne Dec 19, 2017
56d5c60
Merge branch 'FixDebuggerEnvVars' into EnvVarFixes
DonJayamanne Dec 19, 2017
0ea674b
Merge branch 'RefactorJediAndOthers' into EnvVarFixes
DonJayamanne Dec 19, 2017
09d2372
refactor environment variables parser
DonJayamanne Dec 19, 2017
203e13e
fixed linter error
DonJayamanne Dec 19, 2017
21601f2
Fixed code review comments
DonJayamanne Dec 19, 2017
733f9a1
Merge branch 'RefactorJediAndOthers' into EnvVarFixes
DonJayamanne Dec 19, 2017
24fa57e
added tests for env vars service
DonJayamanne Dec 19, 2017
649b7e7
console could be null
DonJayamanne Dec 19, 2017
8d8d2fc
Merge remote-tracking branch 'upstream/master'
DonJayamanne Dec 19, 2017
6641ec8
merged master
DonJayamanne Dec 19, 2017
b65d7c0
merged master
DonJayamanne Dec 19, 2017
e6c9472
use new env variables service in jedi service
DonJayamanne Dec 20, 2017
bf2d5d5
fix #456
DonJayamanne Dec 21, 2017
98b6993
add missing service registrations
DonJayamanne Dec 21, 2017
db84ded
Merge branch 'EnvVarFixes' into CommonToolExecution
DonJayamanne Dec 21, 2017
25e4b71
add missing service registration
DonJayamanne Dec 21, 2017
81bec0a
Merge branch 'EnvVarFixes' into CommonToolExecution
DonJayamanne Dec 21, 2017
3bbbaaa
add missing service registration
DonJayamanne Dec 21, 2017
30d0bb5
remove imports of 'reflect-metadata'
DonJayamanne Jan 2, 2018
5eb11dc
Merge branch 'EnvVarFixes' into CommonToolExecution
DonJayamanne Jan 2, 2018
c425a55
Merge remote-tracking branch 'upstream/master'
DonJayamanne Jan 3, 2018
f8b9eac
merge master
DonJayamanne Jan 3, 2018
a0bfee9
resolve merge issue
DonJayamanne Jan 3, 2018
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
40 changes: 40 additions & 0 deletions src/client/common/process/pythonToolService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import { inject, injectable } from 'inversify';
import { Uri } from 'vscode';
import { IServiceContainer } from '../../ioc/types';
import { ExecutionInfo } from '../types';
import { IEnvironmentVariablesProvider } from '../variables/types';
import { ExecutionResult, IProcessService, IPythonExecutionFactory, IPythonToolExecutionService, ObservableExecutionResult, SpawnOptions } from './types';

@injectable()
export class PythonToolExecutionService implements IPythonToolExecutionService {
constructor( @inject(IServiceContainer) private serviceContainer: IServiceContainer) { }
public async execObservable(executionInfo: ExecutionInfo, options: SpawnOptions, resource: Uri): Promise<ObservableExecutionResult<string>> {
if (options.env) {
throw new Error('Environment variables are not supported');
}
if (executionInfo.moduleName && executionInfo.moduleName.length > 0) {
const pythonExecutionService = await this.serviceContainer.get<IPythonExecutionFactory>(IPythonExecutionFactory).create(resource);
return pythonExecutionService.execModuleObservable(executionInfo.moduleName, executionInfo.args, options);
} else {
const env = await this.serviceContainer.get<IEnvironmentVariablesProvider>(IEnvironmentVariablesProvider).getEnvironmentVariables(resource);
const processService = this.serviceContainer.get<IProcessService>(IProcessService);
return processService.execObservable(executionInfo.execPath!, executionInfo.args, { ...options, env });
}
}
public async exec(executionInfo: ExecutionInfo, options: SpawnOptions, resource: Uri): Promise<ExecutionResult<string>> {
if (options.env) {
throw new Error('Environment variables are not supported');
}
if (executionInfo.moduleName && executionInfo.moduleName.length > 0) {
const pythonExecutionService = await this.serviceContainer.get<IPythonExecutionFactory>(IPythonExecutionFactory).create(resource);
return pythonExecutionService.execModule(executionInfo.moduleName!, executionInfo.args, options);
} else {
const env = await this.serviceContainer.get<IEnvironmentVariablesProvider>(IEnvironmentVariablesProvider).getEnvironmentVariables(resource);
const processService = this.serviceContainer.get<IProcessService>(IProcessService);
return processService.exec(executionInfo.execPath!, executionInfo.args, { ...options, env });
}
}
}
4 changes: 3 additions & 1 deletion src/client/common/process/serviceRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { IServiceManager } from '../../ioc/types';
import { BufferDecoder } from './decoder';
import { ProcessService } from './proc';
import { PythonExecutionFactory } from './pythonExecutionFactory';
import { IBufferDecoder, IProcessService, IPythonExecutionFactory } from './types';
import { PythonToolExecutionService } from './pythonToolService';
import { IBufferDecoder, IProcessService, IPythonExecutionFactory, IPythonToolExecutionService } from './types';

export function registerTypes(serviceManager: IServiceManager) {
serviceManager.addSingleton<IBufferDecoder>(IBufferDecoder, BufferDecoder);
serviceManager.addSingleton<IProcessService>(IProcessService, ProcessService);
serviceManager.addSingleton<IPythonExecutionFactory>(IPythonExecutionFactory, PythonExecutionFactory);
serviceManager.addSingleton<IPythonToolExecutionService>(IPythonToolExecutionService, PythonToolExecutionService);
}
8 changes: 8 additions & 0 deletions src/client/common/process/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { ChildProcess, SpawnOptions as ChildProcessSpawnOptions } from 'child_process';
import * as Rx from 'rxjs';
import { CancellationToken, Uri } from 'vscode';
import { ExecutionInfo } from '../types';
import { EnvironmentVariables } from '../variables/types';

export const IBufferDecoder = Symbol('IBufferDecoder');
Expand Down Expand Up @@ -69,3 +70,10 @@ export class StdErrError extends Error {
export interface IExecutionEnvironmentVariablesService {
getEnvironmentVariables(resource?: Uri): Promise<EnvironmentVariables | undefined>;
}

export const IPythonToolExecutionService = Symbol('IPythonToolRunnerService');

export interface IPythonToolExecutionService {
execObservable(executionInfo: ExecutionInfo, options: SpawnOptions, resource: Uri): Promise<ObservableExecutionResult<string>>;
exec(executionInfo: ExecutionInfo, options: SpawnOptions, resource: Uri): Promise<ExecutionResult<string>>;
}
19 changes: 5 additions & 14 deletions src/client/formatters/baseFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as vscode from 'vscode';
import { OutputChannel, TextEdit, Uri } from 'vscode';
import { STANDARD_OUTPUT_CHANNEL } from '../common/constants';
import { isNotInstalledError } from '../common/helpers';
import { IPythonToolExecutionService } from '../common/process/types';
import { IProcessService, IPythonExecutionFactory } from '../common/process/types';
import { IInstaller, IOutputChannel, Product } from '../common/types';
import { IEnvironmentVariablesProvider } from '../common/variables/types';
Expand Down Expand Up @@ -53,21 +54,11 @@ export abstract class BaseFormatter {
return [];
}

let executionPromise: Promise<string>;
const executionInfo = this.helper.getExecutionInfo(this.product, args, document.uri);
// Check if required to run as a module or executable.
if (executionInfo.moduleName) {
executionPromise = this.serviceContainer.get<IPythonExecutionFactory>(IPythonExecutionFactory).create(document.uri)
.then(pythonExecutionService => pythonExecutionService.execModule(executionInfo.moduleName!, executionInfo.args.concat([filePath]), { cwd, throwOnStdErr: true, token }))
.then(output => output.stdout);
} else {
const executionService = this.serviceContainer.get<IProcessService>(IProcessService);
executionPromise = this.serviceContainer.get<IEnvironmentVariablesProvider>(IEnvironmentVariablesProvider).getEnvironmentVariables(document.uri)
.then(env => executionService.exec(executionInfo.execPath!, executionInfo.args.concat([filePath]), { cwd, env, throwOnStdErr: true, token }))
.then(output => output.stdout);
}

const promise = executionPromise
executionInfo.args.push(filePath);
const pythonToolsExecutionService = this.serviceContainer.get<IPythonToolExecutionService>(IPythonToolExecutionService);
const promise = pythonToolsExecutionService.exec(executionInfo, { cwd, throwOnStdErr: true, token }, document.uri)
.then(output => output.stdout)
.then(data => {
if (token && token.isCancellationRequested) {
return [] as TextEdit[];
Expand Down
17 changes: 4 additions & 13 deletions src/client/linters/baseLinter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as path from 'path';
import { CancellationToken, OutputChannel, TextDocument, Uri } from 'vscode';
import * as vscode from 'vscode';
import { CancellationToken, OutputChannel, TextDocument, Uri } from 'vscode';
import { IPythonSettings, PythonSettings } from '../common/configSettings';
import '../common/extensions';
import { IPythonToolExecutionService } from '../common/process/types';
import { ExecutionResult, IProcessService, IPythonExecutionFactory } from '../common/process/types';
import { ExecutionInfo, IInstaller, ILogger, Product } from '../common/types';
import { IEnvironmentVariablesProvider } from '../common/variables/types';
Expand Down Expand Up @@ -117,19 +118,9 @@ export abstract class BaseLinter {
protected async run(args: string[], document: vscode.TextDocument, cancellation: vscode.CancellationToken, regEx: string = REGEX): Promise<ILintMessage[]> {
const executionInfo = this.helper.getExecutionInfo(this.product, args, document.uri);
const cwd = this.getWorkspaceRootPath(document);
let executionPromise: Promise<ExecutionResult<string>>;

// Check if required to run as a module or executable.
if (executionInfo.moduleName) {
const pythonExecutionService = await this.serviceContainer.get<IPythonExecutionFactory>(IPythonExecutionFactory).create(document.uri);
executionPromise = pythonExecutionService.execModule(executionInfo.moduleName!, executionInfo.args, { cwd, mergeStdOutErr: true, token: cancellation });
} else {
const env = await this.serviceContainer.get<IEnvironmentVariablesProvider>(IEnvironmentVariablesProvider).getEnvironmentVariables(document.uri);
const executionService = this.serviceContainer.get<IProcessService>(IProcessService);
executionPromise = executionService.exec(executionInfo.execPath!, executionInfo.args, { cwd, env, token: cancellation, mergeStdOutErr: true });
}
const pythonToolsExecutionService = this.serviceContainer.get<IPythonToolExecutionService>(IPythonToolExecutionService);
try {
const result = await executionPromise;
const result = await pythonToolsExecutionService.exec(executionInfo, {cwd, token: cancellation, mergeStdOutErr: true}, document.uri);
this.displayLinterResultHeader(result.stdout);
return await this.parseMessages(result.stdout, document, cancellation, regEx);
} catch (error) {
Expand Down
28 changes: 13 additions & 15 deletions src/client/unittests/common/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ import { CancellationToken, OutputChannel, Uri } from 'vscode';
import { IPythonSettings, PythonSettings } from '../../common/configSettings';
import { ErrorUtils } from '../../common/errors/errorUtils';
import { ModuleNotInstalledError } from '../../common/errors/moduleNotInstalledError';
import { IPythonToolExecutionService } from '../../common/process/types';
import {
IProcessService,
IPythonExecutionFactory,
IPythonExecutionService,
ObservableExecutionResult,
SpawnOptions
} from '../../common/process/types';
import { ExecutionInfo } from '../../common/types';
import { IEnvironmentVariablesProvider } from '../../common/variables/types';
import { IServiceContainer } from '../../ioc/types';
import { NOSETEST_PROVIDER, PYTEST_PROVIDER, UNITTEST_PROVIDER } from './constants';
import { TestProvider } from './types';
import { ITestsHelper, TestProvider } from './types';

export type Options = {
workspaceFolder: Uri;
Expand All @@ -36,21 +38,17 @@ export async function run(serviceContainer: IServiceContainer, testProvider: Tes
// Unit tests have a special way of being executed
const pythonServiceFactory = serviceContainer.get<IPythonExecutionFactory>(IPythonExecutionFactory);
pythonExecutionServicePromise = pythonServiceFactory.create(options.workspaceFolder);
promise = pythonExecutionServicePromise.then(executionService => {
return executionService.execObservable(options.args, { ...spawnOptions });
});
} else if (testExecutablePath) {
const processService = serviceContainer.get<IProcessService>(IProcessService);
const envVarsService = serviceContainer.get<IEnvironmentVariablesProvider>(IEnvironmentVariablesProvider);
promise = envVarsService.getEnvironmentVariables(options.workspaceFolder).then(executionService => {
return processService.execObservable(testExecutablePath, options.args, { ...spawnOptions });
});
promise = pythonExecutionServicePromise.then(executionService => executionService.execObservable(options.args, { ...spawnOptions }));
} else {
const pythonServiceFactory = serviceContainer.get<IPythonExecutionFactory>(IPythonExecutionFactory);
pythonExecutionServicePromise = pythonServiceFactory.create(options.workspaceFolder);
promise = pythonExecutionServicePromise.then(executionService => {
return executionService.execModuleObservable(moduleName, options.args, { ...spawnOptions });
});
const pythonToolsExecutionService = serviceContainer.get<IPythonToolExecutionService>(IPythonToolExecutionService);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up to you, but I think there is an option to derive PythonTestExecutionService, override handling and push instance in the test service registry. This way you won't have to have test code in the main module.

const testHelper = serviceContainer.get<ITestsHelper>(ITestsHelper);
const executionInfo: ExecutionInfo = {
execPath: testExecutablePath,
args: options.args,
moduleName: testExecutablePath && testExecutablePath.length > 0 ? undefined : moduleName,
product: testHelper.parseProduct(testProvider)
};
promise = pythonToolsExecutionService.execObservable(executionInfo, spawnOptions, options.workspaceFolder);
}

return promise.then(result => {
Expand Down
10 changes: 10 additions & 0 deletions src/client/unittests/common/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ export class TestsHelper implements ITestsHelper {
}
}
}
public parseProduct(provider: TestProvider): UnitTestProduct {
switch (provider) {
case 'nosetest': return Product.nosetest;
case 'pytest': return Product.pytest;
case 'unittest': return Product.unittest;
default: {
throw new Error(`Unknown Test Provider ${provider}`);
}
}
}
public getSettingsPropertyNames(product: UnitTestProduct): TestSettingsPropertyNames {
const id = this.parseProviderName(product);
switch (id) {
Expand Down
1 change: 1 addition & 0 deletions src/client/unittests/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ export const ITestsHelper = Symbol('ITestsHelper');

export interface ITestsHelper {
parseProviderName(product: UnitTestProduct): TestProvider;
parseProduct(provider: TestProvider): UnitTestProduct;
getSettingsPropertyNames(product: Product): TestSettingsPropertyNames;
flattenTestFiles(testFiles: TestFile[]): Tests;
placeTestFilesIntoFolders(tests: Tests): void;
Expand Down
4 changes: 3 additions & 1 deletion src/test/serviceRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import { PathUtils } from '../client/common/platform/pathUtils';
import { BufferDecoder } from '../client/common/process/decoder';
import { ProcessService } from '../client/common/process/proc';
import { PythonExecutionFactory } from '../client/common/process/pythonExecutionFactory';
import { PythonToolExecutionService } from '../client/common/process/pythonToolService';
import { registerTypes as processRegisterTypes } from '../client/common/process/serviceRegistry';
import { IBufferDecoder, IProcessService, IPythonExecutionFactory } from '../client/common/process/types';
import { IBufferDecoder, IProcessService, IPythonExecutionFactory, IPythonToolExecutionService } from '../client/common/process/types';
import { registerTypes as commonRegisterTypes } from '../client/common/serviceRegistry';
import { GLOBAL_MEMENTO, ICurrentProcess, IDisposableRegistry, ILogger, IMemento, IOutputChannel, IPathUtils, Is64Bit, IsWindows, WORKSPACE_MEMENTO } from '../client/common/types';
import { registerTypes as variableRegisterTypes } from '../client/common/variables/serviceRegistry';
Expand Down Expand Up @@ -86,6 +87,7 @@ export class IocContainer {
this.serviceManager.addSingleton<IProcessService>(IOriginalProcessService, ProcessService);
this.serviceManager.addSingleton<IProcessService>(IProcessService, MockProcessService);
this.serviceManager.addSingleton<IPythonExecutionFactory>(IPythonExecutionFactory, PythonExecutionFactory);
this.serviceManager.addSingleton<IPythonToolExecutionService>(IPythonToolExecutionService, PythonToolExecutionService);
}

public registerMockProcess() {
Expand Down