Skip to content

Commit

Permalink
Merge pull request #8 from eleanorjboyd/new-main
Browse files Browse the repository at this point in the history
New-main
  • Loading branch information
eleanorjboyd committed Apr 19, 2023
2 parents 7dbe187 + 582d780 commit cc46906
Show file tree
Hide file tree
Showing 36 changed files with 450 additions and 212 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,7 @@
},
"python.logging.level": {
"default": "error",
"deprecationMessage": "%python.logging.level.deprecation%",
"description": "%python.logging.level.description%",
"enum": [
"debug",
Expand Down
1 change: 1 addition & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"python.linting.pylintEnabled.description": "Whether to lint Python files using pylint.",
"python.linting.pylintPath.description": "Path to Pylint, you can use a custom version of pylint by modifying this setting to include the full path.",
"python.logging.level.description": "The logging level the extension logs at, defaults to 'error'",
"python.logging.level.deprecation": "This setting is deprecated. Please use command `Developer: Set Log Level...` to set logging level.",
"python.pipenvPath.description": "Path to the pipenv executable to use for activation.",
"python.poetryPath.description": "Path to the poetry executable.",
"python.sortImports.args.description": "Arguments passed in. Each argument is a separate item in the array.",
Expand Down
18 changes: 18 additions & 0 deletions pythonFiles/tests/unittestadapter/.data/test_subtest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import unittest

# Test class for the test_subtest_run test.
# The test_failed_tests function should return a dictionary that has a "success" status
# and the "result" value is a dict with 6 entries, one for each subtest.


class NumbersTest(unittest.TestCase):
def test_even(self):
"""
Test that numbers between 0 and 5 are all even.
"""
for i in range(0, 6):
with self.subTest(i=i):
self.assertEqual(i % 2, 0)
29 changes: 29 additions & 0 deletions pythonFiles/tests/unittestadapter/test_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,35 @@ def test_single_ids_run() -> None:
assert id_result["outcome"] == "success"


def test_subtest_run() -> None:
"""This test runs on a the test_subtest which has a single method, test_even,
that uses unittest subtest.
The actual result of run should return a dict payload with 6 entry for the 6 subtests.
"""
id = "test_subtest.NumbersTest.test_even"
actual = run_tests(
os.fspath(TEST_DATA_PATH), [id], "test_subtest.py", None, "fake-uuid"
)
subtests_ids = [
"test_subtest.NumbersTest.test_even (i=0)",
"test_subtest.NumbersTest.test_even (i=1)",
"test_subtest.NumbersTest.test_even (i=2)",
"test_subtest.NumbersTest.test_even (i=3)",
"test_subtest.NumbersTest.test_even (i=4)",
"test_subtest.NumbersTest.test_even (i=5)",
]
assert actual
assert all(item in actual for item in ("cwd", "status"))
assert actual["status"] == "success"
assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
assert "result" in actual
result = actual["result"]
assert len(result) == 6
for id in subtests_ids:
assert id in result


@pytest.mark.parametrize(
"test_ids, pattern, cwd, expected_outcome",
[
Expand Down
5 changes: 4 additions & 1 deletion pythonFiles/unittestadapter/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ def formatResult(
formatted = formatted[1:]
tb = "".join(formatted)

test_id = test.id()
if subtest:
test_id = subtest.id()
else:
test_id = test.id()

result = {
"test": test.id(),
Expand Down
4 changes: 2 additions & 2 deletions src/client/application/diagnostics/applicationDiagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { IWorkspaceService } from '../../common/application/types';
import { isTestExecution } from '../../common/constants';
import { Resource } from '../../common/types';
import { IServiceContainer } from '../../ioc/types';
import { traceInfo, traceLog } from '../../logging';
import { traceLog, traceVerbose } from '../../logging';
import { IApplicationDiagnostics } from '../types';
import { IDiagnostic, IDiagnosticsService, ISourceMapSupportService } from './types';

Expand All @@ -21,7 +21,7 @@ function log(diagnostics: IDiagnostic[]): void {
break;
}
default: {
traceInfo(message);
traceVerbose(message);
}
}
});
Expand Down
8 changes: 4 additions & 4 deletions src/client/common/process/pythonEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as path from 'path';
import { traceError, traceInfo } from '../../logging';
import { traceError, traceVerbose } from '../../logging';
import { Conda, CondaEnvironmentInfo } from '../../pythonEnvironments/common/environmentManagers/conda';
import { buildPythonExecInfo, PythonExecInfo } from '../../pythonEnvironments/exec';
import { InterpreterInformation } from '../../pythonEnvironments/info';
Expand Down Expand Up @@ -71,7 +71,7 @@ class PythonEnvironment implements IPythonEnvironment {
try {
data = await this.deps.exec(info.command, info.args);
} catch (ex) {
traceInfo(`Error when getting version of module ${moduleName}`, ex);
traceVerbose(`Error when getting version of module ${moduleName}`, ex);
return undefined;
}
return parse(data.stdout);
Expand All @@ -84,7 +84,7 @@ class PythonEnvironment implements IPythonEnvironment {
try {
await this.deps.exec(info.command, info.args);
} catch (ex) {
traceInfo(`Error when checking if module is installed ${moduleName}`, ex);
traceVerbose(`Error when checking if module is installed ${moduleName}`, ex);
return false;
}
return true;
Expand All @@ -93,7 +93,7 @@ class PythonEnvironment implements IPythonEnvironment {
private async getInterpreterInformationImpl(): Promise<InterpreterInformation | undefined> {
try {
const python = this.getExecutionInfo();
return await getInterpreterInfo(python, this.deps.shellExec, { info: traceInfo, error: traceError });
return await getInterpreterInfo(python, this.deps.shellExec, { verbose: traceVerbose, error: traceError });
} catch (ex) {
traceError(`Failed to get interpreter information for '${this.pythonPath}'`, ex);
}
Expand Down
2 changes: 2 additions & 0 deletions src/client/environmentApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
ResolvedEnvironment,
Resource,
} from './apiTypes';
import { buildEnvironmentCreationApi } from './pythonEnvironments/creation/createEnvApi';

type ActiveEnvironmentChangeEvent = {
resource: WorkspaceFolder | undefined;
Expand Down Expand Up @@ -253,6 +254,7 @@ export function buildEnvironmentApi(
sendApiTelemetry('onDidChangeEnvironments');
return onEnvironmentsChanged.event;
},
...buildEnvironmentCreationApi(),
};
return environmentApi;
}
Expand Down
7 changes: 0 additions & 7 deletions src/client/extensionActivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import { IInterpreterService } from './interpreter/contracts';
import { getLanguageConfiguration } from './language/languageConfiguration';
import { LinterCommands } from './linters/linterCommands';
import { registerTypes as lintersRegisterTypes } from './linters/serviceRegistry';
import { setLoggingLevel } from './logging';
import { PythonFormattingEditProvider } from './providers/formatProvider';
import { ReplProvider } from './providers/replProvider';
import { registerTypes as providersRegisterTypes } from './providers/serviceRegistry';
Expand All @@ -47,7 +46,6 @@ import * as pythonEnvironments from './pythonEnvironments';
import { ActivationResult, ExtensionState } from './components';
import { Components } from './extensionInit';
import { setDefaultLanguageServer } from './activation/common/defaultlanguageServer';
import { getLoggingLevel } from './logging/settings';
import { DebugService } from './common/application/debugService';
import { DebugSessionEventDispatcher } from './debugger/extension/hooks/eventHandlerDispatcher';
import { IDebugSessionEventHandlers } from './debugger/extension/hooks/types';
Expand Down Expand Up @@ -137,11 +135,6 @@ async function activateLegacy(ext: ExtensionState): Promise<ActivationResult> {
const extensions = serviceContainer.get<IExtensions>(IExtensions);
await setDefaultLanguageServer(extensions, serviceManager);

// Note we should not trigger any extension related code which logs, until we have set logging level. So we cannot
// use configurations service to get level setting. Instead, we use Workspace service to query for setting as it
// directly queries VSCode API.
setLoggingLevel(getLoggingLevel());

const configuration = serviceManager.get<IConfigurationService>(IConfigurationService);
// Settings are dependent on Experiment service, so we need to initialize it after experiments are activated.
serviceContainer.get<IConfigurationService>(IConfigurationService).getSettings().register();
Expand Down
11 changes: 2 additions & 9 deletions src/client/interpreter/activation/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,7 @@ import { EventName } from '../../telemetry/constants';
import { IInterpreterService } from '../contracts';
import { IEnvironmentActivationService } from './types';
import { TraceOptions } from '../../logging/types';
import {
traceDecoratorError,
traceDecoratorVerbose,
traceError,
traceInfo,
traceVerbose,
traceWarn,
} from '../../logging';
import { traceDecoratorError, traceDecoratorVerbose, traceError, traceVerbose, traceWarn } from '../../logging';
import { Conda } from '../../pythonEnvironments/common/environmentManagers/conda';
import { StopWatch } from '../../common/utils/stopWatch';
import { identifyShellFromShellPath } from '../../common/terminal/shellDetectors/baseShellDetector';
Expand Down Expand Up @@ -290,7 +283,7 @@ export class EnvironmentActivationService implements IEnvironmentActivationServi
// that's the case, wait and try again. This happens especially on AzDo
const excString = (exc as Error).toString();
if (condaRetryMessages.find((m) => excString.includes(m)) && tryCount < 10) {
traceInfo(`Conda is busy, attempting to retry ...`);
traceVerbose(`Conda is busy, attempting to retry ...`);
result = undefined;
tryCount += 1;
await sleep(500);
Expand Down
37 changes: 7 additions & 30 deletions src/client/logging/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { StopWatch } from '../common/utils/stopWatch';
import { sendTelemetryEvent } from '../telemetry';
import { EventName } from '../telemetry/constants';
import { FileLogger } from './fileLogger';
import { Arguments, ILogging, LoggingLevelSettingType, LogLevel, TraceDecoratorType, TraceOptions } from './types';
import { Arguments, ILogging, LogLevel, TraceDecoratorType, TraceOptions } from './types';
import { argsToLogString, returnValueToLogString } from './util';

const DEFAULT_OPTS: TraceOptions = TraceOptions.Arguments | TraceOptions.ReturnValue;
Expand All @@ -26,21 +26,6 @@ export function registerLogger(logger: ILogging): Disposable {
};
}

const logLevelMap: Map<string | undefined, LogLevel> = new Map([
['error', LogLevel.Error],
['warn', LogLevel.Warn],
['info', LogLevel.Info],
['debug', LogLevel.Debug],
['none', LogLevel.Off],
['off', LogLevel.Off],
[undefined, LogLevel.Error],
]);

let globalLoggingLevel: LogLevel;
export function setLoggingLevel(level?: LoggingLevelSettingType): void {
globalLoggingLevel = logLevelMap.get(level) ?? LogLevel.Error;
}

export function initializeFileLogging(disposables: Disposable[]): void {
if (process.env.VSC_PYTHON_LOG_FILE) {
const fileLogger = new FileLogger(createWriteStream(process.env.VSC_PYTHON_LOG_FILE));
Expand All @@ -54,27 +39,19 @@ export function traceLog(...args: Arguments): void {
}

export function traceError(...args: Arguments): void {
if (globalLoggingLevel >= LogLevel.Error) {
loggers.forEach((l) => l.traceError(...args));
}
loggers.forEach((l) => l.traceError(...args));
}

export function traceWarn(...args: Arguments): void {
if (globalLoggingLevel >= LogLevel.Warn) {
loggers.forEach((l) => l.traceWarn(...args));
}
loggers.forEach((l) => l.traceWarn(...args));
}

export function traceInfo(...args: Arguments): void {
if (globalLoggingLevel >= LogLevel.Info) {
loggers.forEach((l) => l.traceInfo(...args));
}
loggers.forEach((l) => l.traceInfo(...args));
}

export function traceVerbose(...args: Arguments): void {
if (globalLoggingLevel >= LogLevel.Debug) {
loggers.forEach((l) => l.traceVerbose(...args));
}
loggers.forEach((l) => l.traceVerbose(...args));
}

/** Logging Decorators go here */
Expand All @@ -89,7 +66,7 @@ export function traceDecoratorInfo(message: string): TraceDecoratorType {
return createTracingDecorator({ message, opts: DEFAULT_OPTS, level: LogLevel.Info });
}
export function traceDecoratorWarn(message: string): TraceDecoratorType {
return createTracingDecorator({ message, opts: DEFAULT_OPTS, level: LogLevel.Warn });
return createTracingDecorator({ message, opts: DEFAULT_OPTS, level: LogLevel.Warning });
}

// Information about a function/method call.
Expand Down Expand Up @@ -223,7 +200,7 @@ export function logTo(logLevel: LogLevel, ...args: Arguments): void {
case LogLevel.Error:
traceError(...args);
break;
case LogLevel.Warn:
case LogLevel.Warning:
traceWarn(...args);
break;
case LogLevel.Info:
Expand Down
12 changes: 0 additions & 12 deletions src/client/logging/settings.ts

This file was deleted.

14 changes: 7 additions & 7 deletions src/client/logging/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-explicit-any */

export type LoggingLevelSettingType = 'off' | 'error' | 'warn' | 'info' | 'debug';
export type Arguments = unknown[];

export enum LogLevel {
Off = 0,
Error = 10,
Warn = 20,
Info = 30,
Debug = 40,
Trace = 1,
Debug = 2,
Info = 3,
Warning = 4,
Error = 5,
}

export type Arguments = unknown[];

export interface ILogging {
traceLog(...data: Arguments): void;
traceError(...data: Arguments): void;
Expand Down
6 changes: 5 additions & 1 deletion src/client/proposedApiTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

export interface ProposedExtensionAPI {}
export interface ProposedExtensionAPI {
/**
* Top level proposed APIs should go here.
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { createDeferred, Deferred, sleep } from '../../../common/utils/async';
import { createRunningWorkerPool, IWorkerPool, QueuePosition } from '../../../common/utils/workerPool';
import { getInterpreterInfo, InterpreterInformation } from './interpreter';
import { buildPythonExecInfo } from '../../exec';
import { traceError, traceInfo, traceWarn } from '../../../logging';
import { traceError, traceVerbose, traceWarn } from '../../../logging';
import { Conda, CONDA_ACTIVATION_TIMEOUT, isCondaEnvironment } from '../../common/environmentManagers/conda';
import { PythonEnvInfo, PythonEnvKind } from '.';
import { normCasePath } from '../../common/externalDependencies';
Expand Down Expand Up @@ -153,7 +153,7 @@ class EnvironmentInfoService implements IEnvironmentInfoService {
// as complete env info may not be available at this time.
const isCondaEnv = env.kind === PythonEnvKind.Conda || (await isCondaEnvironment(env.executable.filename));
if (isCondaEnv) {
traceInfo(
traceVerbose(
`Validating ${env.executable.filename} normally failed with error, falling back to using conda run: (${reason})`,
);
if (this.condaRunWorkerPool === undefined) {
Expand Down
4 changes: 2 additions & 2 deletions src/client/pythonEnvironments/base/info/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
InterpreterInfoJson,
} from '../../../common/process/internal/scripts';
import { Architecture } from '../../../common/utils/platform';
import { traceError, traceInfo } from '../../../logging';
import { traceError, traceVerbose } from '../../../logging';
import { shellExecute } from '../../common/externalDependencies';
import { copyPythonExecInfo, PythonExecInfo } from '../../exec';
import { parseVersion } from './pythonVersion';
Expand Down Expand Up @@ -102,6 +102,6 @@ export async function getInterpreterInfo(
traceError(`Failed to parse interpreter information for >> ${quoted} << with ${ex}`);
return undefined;
}
traceInfo(`Found interpreter for >> ${quoted} <<: ${JSON.stringify(json)}`);
traceVerbose(`Found interpreter for >> ${quoted} <<: ${JSON.stringify(json)}`);
return extractInterpreterInfo(python.pythonExecutable, json);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { Event } from 'vscode';
import { isTestExecution } from '../../../../common/constants';
import { traceInfo, traceVerbose } from '../../../../logging';
import { traceVerbose } from '../../../../logging';
import { arePathsSame, getFileInfo, pathExists } from '../../../common/externalDependencies';
import { PythonEnvInfo, PythonEnvKind } from '../../info';
import { areEnvsDeepEqual, areSameEnv, getEnvPath } from '../../info/env';
Expand Down Expand Up @@ -225,7 +225,7 @@ export class PythonEnvInfoCache extends PythonEnvsWatcher<PythonEnvCollectionCha
await this.persistentStorage.store(envs);
return;
}
traceInfo('Environments added to cache', JSON.stringify(this.envs));
traceVerbose('Environments added to cache', JSON.stringify(this.envs));
this.markAllEnvsAsFlushed();
await this.persistentStorage.store(this.envs);
}
Expand Down
Loading

0 comments on commit cc46906

Please sign in to comment.