Skip to content

Commit 37ff259

Browse files
authored
Merge branch 'main' into update-service-test
2 parents 3b94389 + 385bb37 commit 37ff259

File tree

14 files changed

+212
-74
lines changed

14 files changed

+212
-74
lines changed

.github/workflows/pr-file-check.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,23 @@ jobs:
1717
runs-on: ubuntu-latest
1818
steps:
1919
- name: 'package-lock.json matches package.json'
20-
uses: brettcannon/check-for-changed-files@v1.1.1
20+
uses: brettcannon/check-for-changed-files@v1.2.0
2121
with:
2222
prereq-pattern: 'package.json'
2323
file-pattern: 'package-lock.json'
2424
skip-label: 'skip package*.json'
2525
failure-message: '${prereq-pattern} was edited but ${file-pattern} was not (the ${skip-label} label can be used to pass this check)'
2626

2727
- name: 'package.json matches package-lock.json'
28-
uses: brettcannon/check-for-changed-files@v1.1.1
28+
uses: brettcannon/check-for-changed-files@v1.2.0
2929
with:
3030
prereq-pattern: 'package-lock.json'
3131
file-pattern: 'package.json'
3232
skip-label: 'skip package*.json'
3333
failure-message: '${prereq-pattern} was edited but ${file-pattern} was not (the ${skip-label} label can be used to pass this check)'
3434

3535
- name: 'Tests'
36-
uses: brettcannon/check-for-changed-files@v1.1.1
36+
uses: brettcannon/check-for-changed-files@v1.2.0
3737
with:
3838
prereq-pattern: src/**/*.ts
3939
file-pattern: |

package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"theme": "dark"
4747
},
4848
"engines": {
49-
"vscode": "^1.79.0-20230526"
49+
"vscode": "^1.82.0-20230809"
5050
},
5151
"enableTelemetry": false,
5252
"keywords": [
@@ -1147,6 +1147,21 @@
11471147
"scope": "machine",
11481148
"type": "string"
11491149
},
1150+
"python.missingPackage.severity":{
1151+
"default": "Hint",
1152+
"description": "%python.missingPackage.severity.description%",
1153+
"enum": [
1154+
"Error",
1155+
"Hint",
1156+
"Information",
1157+
"Warning"
1158+
],
1159+
"scope": "resource",
1160+
"type": "string",
1161+
"tags": [
1162+
"experimental"
1163+
]
1164+
},
11501165
"python.pipenvPath": {
11511166
"default": "pipenv",
11521167
"description": "%python.pipenvPath.description%",
@@ -2151,7 +2166,7 @@
21512166
"@types/stack-trace": "0.0.29",
21522167
"@types/tmp": "^0.0.33",
21532168
"@types/uuid": "^8.3.4",
2154-
"@types/vscode": "^1.75.0",
2169+
"@types/vscode": "^1.81.0",
21552170
"@types/which": "^2.0.1",
21562171
"@types/winreg": "^1.2.30",
21572172
"@types/xml2js": "^0.4.2",

package.nls.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@
200200
"python.linting.pylintPath.deprecationMessage": "This setting will soon be deprecated. Please use the Pylint extension. Learn more here: https://aka.ms/AAlgvkb.",
201201
"python.logging.level.description": "The logging level the extension logs at, defaults to 'error'",
202202
"python.logging.level.deprecation": "This setting is deprecated. Please use command `Developer: Set Log Level...` to set logging level.",
203+
"python.missingPackage.severity.description": "Set severity of missing packages in requirements.txt or pyproject.toml",
203204
"python.pipenvPath.description": "Path to the pipenv executable to use for activation.",
204205
"python.poetryPath.description": "Path to the poetry executable.",
205206
"python.sortImports.args.description": "Arguments passed in. Each argument is a separate item in the array.",
@@ -265,4 +266,4 @@
265266
"walkthrough.step.python.createNewNotebook.altText": "Creating a new Jupyter notebook",
266267
"walkthrough.step.python.openInteractiveWindow.altText": "Opening Python interactive window",
267268
"walkthrough.step.python.dataScienceLearnMore.altText": "Image representing our documentation page and mailing list resources."
268-
}
269+
}

pythonFiles/installed_check.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515
from importlib_metadata import metadata
1616
from packaging.requirements import Requirement
1717

18-
DEFAULT_SEVERITY = 3
18+
DEFAULT_SEVERITY = "3" # 'Hint'
19+
try:
20+
SEVERITY = int(os.getenv("VSCODE_MISSING_PGK_SEVERITY", DEFAULT_SEVERITY))
21+
except ValueError:
22+
SEVERITY = int(DEFAULT_SEVERITY)
1923

2024

2125
def parse_args(argv: Optional[Sequence[str]] = None):
@@ -37,7 +41,8 @@ def parse_requirements(line: str) -> Optional[Requirement]:
3741
elif req.marker.evaluate():
3842
return req
3943
except Exception:
40-
return None
44+
pass
45+
return None
4146

4247

4348
def process_requirements(req_file: pathlib.Path) -> List[Dict[str, Union[str, int]]]:
@@ -60,7 +65,7 @@ def process_requirements(req_file: pathlib.Path) -> List[Dict[str, Union[str, in
6065
"endCharacter": len(req.name),
6166
"package": req.name,
6267
"code": "not-installed",
63-
"severity": DEFAULT_SEVERITY,
68+
"severity": SEVERITY,
6469
}
6570
)
6671
return diagnostics
@@ -100,7 +105,7 @@ def process_pyproject(req_file: pathlib.Path) -> List[Dict[str, Union[str, int]]
100105
"endCharacter": end,
101106
"package": req.name,
102107
"code": "not-installed",
103-
"severity": DEFAULT_SEVERITY,
108+
"severity": SEVERITY,
104109
}
105110
)
106111
return diagnostics

pythonFiles/tests/test_installed_check.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import sys
1010

1111
import pytest
12-
from typing import Dict, List, Union
12+
from typing import Dict, List, Optional, Union
1313

1414
SCRIPT_PATH = pathlib.Path(__file__).parent.parent / "installed_check.py"
1515
TEST_DATA = pathlib.Path(__file__).parent / "test_data"
@@ -29,7 +29,12 @@ def generate_file(base_file: pathlib.Path):
2929
os.unlink(str(fullpath))
3030

3131

32-
def run_on_file(file_path: pathlib.Path) -> List[Dict[str, Union[str, int]]]:
32+
def run_on_file(
33+
file_path: pathlib.Path, severity: Optional[str] = None
34+
) -> List[Dict[str, Union[str, int]]]:
35+
env = os.environ.copy()
36+
if severity:
37+
env["VSCODE_MISSING_PGK_SEVERITY"] = severity
3338
result = subprocess.run(
3439
[
3540
sys.executable,
@@ -39,6 +44,7 @@ def run_on_file(file_path: pathlib.Path) -> List[Dict[str, Union[str, int]]]:
3944
stdout=subprocess.PIPE,
4045
stderr=subprocess.PIPE,
4146
check=True,
47+
env=env,
4248
)
4349
assert result.returncode == 0
4450
assert result.stderr == b""
@@ -88,3 +94,46 @@ def test_installed_check(test_name: str):
8894
with generate_file(base_file) as file_path:
8995
result = run_on_file(file_path)
9096
assert result == EXPECTED_DATA[test_name]
97+
98+
99+
EXPECTED_DATA2 = {
100+
"missing-deps": [
101+
{
102+
"line": 6,
103+
"character": 0,
104+
"endLine": 6,
105+
"endCharacter": 10,
106+
"package": "flake8-csv",
107+
"code": "not-installed",
108+
"severity": 0,
109+
},
110+
{
111+
"line": 10,
112+
"character": 0,
113+
"endLine": 10,
114+
"endCharacter": 11,
115+
"package": "levenshtein",
116+
"code": "not-installed",
117+
"severity": 0,
118+
},
119+
],
120+
"pyproject-missing-deps": [
121+
{
122+
"line": 8,
123+
"character": 34,
124+
"endLine": 8,
125+
"endCharacter": 44,
126+
"package": "flake8-csv",
127+
"code": "not-installed",
128+
"severity": 0,
129+
}
130+
],
131+
}
132+
133+
134+
@pytest.mark.parametrize("test_name", EXPECTED_DATA2.keys())
135+
def test_with_severity(test_name: str):
136+
base_file = TEST_DATA / f"{test_name}.data"
137+
with generate_file(base_file) as file_path:
138+
result = run_on_file(file_path, severity="0")
139+
assert result == EXPECTED_DATA2[test_name]

src/client/interpreter/activation/terminalEnvVarCollectionService.ts

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,7 @@
33

44
import * as path from 'path';
55
import { inject, injectable } from 'inversify';
6-
import {
7-
ProgressOptions,
8-
ProgressLocation,
9-
MarkdownString,
10-
WorkspaceFolder,
11-
EnvironmentVariableCollection,
12-
EnvironmentVariableScope,
13-
} from 'vscode';
6+
import { ProgressOptions, ProgressLocation, MarkdownString, WorkspaceFolder } from 'vscode';
147
import { pathExists } from 'fs-extra';
158
import { IExtensionActivationService } from '../../activation/types';
169
import { IApplicationShell, IApplicationEnvironment, IWorkspaceService } from '../../common/application/types';
@@ -67,7 +60,8 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
6760

6861
public async activate(resource: Resource): Promise<void> {
6962
if (!inTerminalEnvVarExperiment(this.experimentService)) {
70-
this.context.environmentVariableCollection.clear();
63+
const workspaceFolder = this.getWorkspaceFolder(resource);
64+
this.context.getEnvironmentVariableCollection({ workspaceFolder }).clear();
7165
await this.handleMicroVenv(resource);
7266
if (!this.registeredOnce) {
7367
this.interpreterService.onDidChangeInterpreter(
@@ -111,8 +105,8 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
111105
public async _applyCollection(resource: Resource, shell = this.applicationEnvironment.shell): Promise<void> {
112106
const workspaceFolder = this.getWorkspaceFolder(resource);
113107
const settings = this.configurationService.getSettings(resource);
114-
const envVarCollection = this.getEnvironmentVariableCollection(workspaceFolder);
115-
// Clear any previously set env vars from collection.
108+
const envVarCollection = this.context.getEnvironmentVariableCollection({ workspaceFolder });
109+
// Clear any previously set env vars from collection
116110
envVarCollection.clear();
117111
if (!settings.terminal.activateEnvironment) {
118112
traceVerbose('Activating environments in terminal is disabled for', resource?.fsPath);
@@ -160,7 +154,10 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
160154
return;
161155
}
162156
traceVerbose(`Setting environment variable ${key} in collection to ${value}`);
163-
envVarCollection.replace(key, value, { applyAtShellIntegration: true });
157+
envVarCollection.replace(key, value, {
158+
applyAtShellIntegration: true,
159+
applyAtProcessCreation: true,
160+
});
164161
}
165162
}
166163
});
@@ -170,22 +167,13 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
170167
envVarCollection.description = description;
171168
}
172169

173-
private getEnvironmentVariableCollection(workspaceFolder?: WorkspaceFolder) {
174-
const envVarCollection = this.context.environmentVariableCollection as EnvironmentVariableCollection & {
175-
getScopedEnvironmentVariableCollection(scope: EnvironmentVariableScope): EnvironmentVariableCollection;
176-
};
177-
return workspaceFolder
178-
? envVarCollection.getScopedEnvironmentVariableCollection({ workspaceFolder })
179-
: envVarCollection;
180-
}
181-
182170
private async handleMicroVenv(resource: Resource) {
183171
const workspaceFolder = this.getWorkspaceFolder(resource);
184172
const interpreter = await this.interpreterService.getActiveInterpreter(resource);
185173
if (interpreter?.envType === EnvironmentType.Venv) {
186174
const activatePath = path.join(path.dirname(interpreter.path), 'activate');
187175
if (!(await pathExists(activatePath))) {
188-
const envVarCollection = this.getEnvironmentVariableCollection(workspaceFolder);
176+
const envVarCollection = this.context.getEnvironmentVariableCollection({ workspaceFolder });
189177
const pathVarName = getSearchPathEnvVarNames()[0];
190178
envVarCollection.replace(
191179
'PATH',
@@ -195,7 +183,7 @@ export class TerminalEnvVarCollectionService implements IExtensionActivationServ
195183
return;
196184
}
197185
}
198-
this.context.environmentVariableCollection.clear();
186+
this.context.getEnvironmentVariableCollection({ workspaceFolder }).clear();
199187
}
200188

201189
private getWorkspaceFolder(resource: Resource): WorkspaceFolder | undefined {

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { installedCheckScript } from '../../../common/process/internal/scripts';
66
import { plainExec } from '../../../common/process/rawProcessApis';
77
import { IInterpreterPathService } from '../../../common/types';
88
import { traceInfo, traceVerbose, traceError } from '../../../logging';
9+
import { getConfiguration } from '../../../common/vscodeApis/workspaceApis';
910

1011
interface PackageDiagnostic {
1112
package: string;
@@ -39,6 +40,21 @@ function parseDiagnostics(data: string): Diagnostic[] {
3940
return diagnostics;
4041
}
4142

43+
function getMissingPackageSeverity(doc: TextDocument): number {
44+
const config = getConfiguration('python', doc.uri);
45+
const severity: string = config.get<string>('missingPackage.severity', 'Hint');
46+
if (severity === 'Error') {
47+
return DiagnosticSeverity.Error;
48+
}
49+
if (severity === 'Warning') {
50+
return DiagnosticSeverity.Warning;
51+
}
52+
if (severity === 'Information') {
53+
return DiagnosticSeverity.Information;
54+
}
55+
return DiagnosticSeverity.Hint;
56+
}
57+
4258
export async function getInstalledPackagesDiagnostics(
4359
interpreterPathService: IInterpreterPathService,
4460
doc: TextDocument,
@@ -47,7 +63,11 @@ export async function getInstalledPackagesDiagnostics(
4763
const scriptPath = installedCheckScript();
4864
try {
4965
traceInfo('Running installed packages checker: ', interpreter, scriptPath, doc.uri.fsPath);
50-
const result = await plainExec(interpreter, [scriptPath, doc.uri.fsPath]);
66+
const result = await plainExec(interpreter, [scriptPath, doc.uri.fsPath], {
67+
env: {
68+
VSCODE_MISSING_PGK_SEVERITY: `${getMissingPackageSeverity(doc)}`,
69+
},
70+
});
5171
traceVerbose('Installed packages check result:\n', result.stdout);
5272
if (result.stderr) {
5373
traceError('Installed packages check error:\n', result.stderr);

src/client/startupTelemetry.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
import * as vscode from 'vscode';
45
import { IWorkspaceService } from './common/application/types';
56
import { isTestExecution } from './common/constants';
67
import { ITerminalHelper } from './common/terminal/types';
@@ -81,6 +82,7 @@ async function getActivationTelemetryProps(serviceContainer: IServiceContainer):
8182
// TODO: If any one of these parts fails we send no info. We should
8283
// be able to partially populate as much as possible instead
8384
// (through granular try-catch statements).
85+
const appName = vscode.env.appName;
8486
const workspaceService = serviceContainer.get<IWorkspaceService>(IWorkspaceService);
8587
const workspaceFolderCount = workspaceService.workspaceFolders?.length || 0;
8688
const terminalHelper = serviceContainer.get<ITerminalHelper>(ITerminalHelper);
@@ -129,5 +131,6 @@ async function getActivationTelemetryProps(serviceContainer: IServiceContainer):
129131
hasPythonThree,
130132
usingUserDefinedInterpreter,
131133
usingGlobalInterpreter,
134+
appName,
132135
};
133136
}

0 commit comments

Comments
 (0)