Skip to content

Commit fe92539

Browse files
authored
Merge branch 'main' into vscode-python-issue-25609-scrollable-repl
2 parents 7ed572f + 015102f commit fe92539

11 files changed

Lines changed: 383 additions & 16 deletions

File tree

‎.github/workflows/build.yml‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ jobs:
311311
if: matrix.test-suite == 'venv'
312312
run: |
313313
python -m pip install virtualenv
314-
python -m virtualenv .virtualenv/
314+
python -m virtualenv --no-venv-redirect .virtualenv/
315315
if ('${{ matrix.os }}' -match 'windows-latest') {
316316
& ".virtualenv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} virtualEnvPath
317317
} else {
@@ -326,10 +326,11 @@ jobs:
326326
if: matrix.test-suite == 'venv' && startsWith(matrix.python, 3.)
327327
run: |
328328
python -m venv .venv
329+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
329330
if ('${{ matrix.os }}' -match 'windows-latest') {
330-
& ".venv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
331+
& "./.venv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
331332
} else {
332-
& ".venv/bin/python" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
333+
& "./.venv/bin/python" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
333334
}
334335
335336
- name: Prepare conda for venv tests

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ jobs:
304304
if: matrix.test-suite == 'venv'
305305
run: |
306306
python -m pip install virtualenv
307-
python -m virtualenv .virtualenv/
307+
python -m virtualenv --no-venv-redirect .virtualenv/
308308
if ('${{ matrix.os }}' -match 'windows-latest') {
309309
& ".virtualenv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} virtualEnvPath
310310
} else {
@@ -319,10 +319,11 @@ jobs:
319319
if: matrix.test-suite == 'venv' && startsWith(matrix.python, 3.)
320320
run: |
321321
python -m venv .venv
322+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
322323
if ('${{ matrix.os }}' -match 'windows-latest') {
323-
& ".venv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
324+
& "./.venv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
324325
} else {
325-
& ".venv/bin/python" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
326+
& "./.venv/bin/python" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
326327
}
327328
328329
- name: Prepare conda for venv tests
@@ -584,7 +585,7 @@ jobs:
584585
shell: pwsh
585586
run: |
586587
python -m pip install virtualenv
587-
python -m virtualenv .virtualenv/
588+
python -m virtualenv --no-venv-redirect .virtualenv/
588589
if ('${{ matrix.os }}' -match 'windows-latest') {
589590
& ".virtualenv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} virtualEnvPath
590591
} else {
@@ -598,10 +599,11 @@ jobs:
598599
shell: pwsh
599600
run: |
600601
python -m venv .venv
602+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
601603
if ('${{ matrix.os }}' -match 'windows-latest') {
602-
& ".venv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
604+
& "./.venv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
603605
} else {
604-
& ".venv/bin/python" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
606+
& "./.venv/bin/python" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
605607
}
606608
607609
- name: Prepare conda for venv tests

‎requirements.txt‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# This file was autogenerated by uv via the following command:
22
# uv pip compile --generate-hashes requirements.in -o requirements.txt
3-
importlib-metadata==9.0.0 \
4-
--hash=sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7 \
5-
--hash=sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc
3+
importlib-metadata==9.0.1 \
4+
--hash=sha256:ab830580bc0ef3db61ce8fae716389e5462b67e033018bab6d8f80ef17172f99 \
5+
--hash=sha256:bba5600596a7e21f3eef53281cf28d6a5195634d2f2b78ff9501a3272c6eaab0
66
# via -r requirements.in
77
microvenv==2025.0 \
88
--hash=sha256:568155ec18af01c89f270d35d123ab803b09672b480c3702d15fd69e9cc5bd1e \

‎src/client/envExt/telemetry.ts‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
import { IDisposableRegistry } from '../common/types';
5+
import { getConfiguration, getWorkspaceFolders, onDidChangeConfiguration } from '../common/vscodeApis/workspaceApis';
6+
import { sendTelemetryEvent } from '../telemetry';
7+
import { EventName } from '../telemetry/constants';
8+
import { EnvsExplicitFalseScope } from '../telemetry/types';
9+
10+
/**
11+
* Reports which scope kinds explicitly configure python.useEnvironmentsExtension to false.
12+
* Defaults and precedence are not applied: overridden false values are still reported.
13+
* Multiple folders count as one scope kind; no setting values or paths are changed.
14+
*/
15+
export function getEnvsExplicitFalseScope(): EnvsExplicitFalseScope {
16+
const folders = getWorkspaceFolders() ?? [];
17+
const inspection = getConfiguration('python', folders[0]?.uri).inspect<boolean>('useEnvironmentsExtension');
18+
const scopes: EnvsExplicitFalseScope[] = [];
19+
if (inspection?.globalValue === false) {
20+
scopes.push('user');
21+
}
22+
if (inspection?.workspaceValue === false) {
23+
scopes.push('workspace');
24+
}
25+
if (
26+
folders.some(
27+
(folder) =>
28+
getConfiguration('python', folder.uri).inspect<boolean>('useEnvironmentsExtension')
29+
?.workspaceFolderValue === false,
30+
)
31+
) {
32+
scopes.push('folder');
33+
}
34+
return scopes.length > 1 ? 'multiple' : scopes[0] ?? 'none';
35+
}
36+
37+
/**
38+
* Reports the current explicit-false scopes when the integration setting changes.
39+
* Registers the listener in disposables without changing the cached integration decision.
40+
* A notification reports configuration, not necessarily an intentional user opt-out.
41+
*/
42+
export function registerEnvironmentsExtensionTelemetry(disposables: IDisposableRegistry): void {
43+
disposables.push(
44+
onDidChangeConfiguration((event) => {
45+
if (event.affectsConfiguration('python.useEnvironmentsExtension')) {
46+
sendTelemetryEvent(EventName.ENVIRONMENTS_EXTENSION_SETTING_CHANGED, undefined, {
47+
envsExplicitFalseScope: getEnvsExplicitFalseScope(),
48+
});
49+
}
50+
}),
51+
);
52+
}

‎src/client/extensionActivation.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import { registerTriggerForTerminalREPL } from './terminals/codeExecution/termin
4848
import { registerPythonStartup } from './terminals/pythonStartup';
4949
import { registerPixiFeatures } from './pythonEnvironments/common/environmentManagers/pixi';
5050
import { registerCustomTerminalLinkProvider } from './terminals/pythonStartupLinkProvider';
51+
import { registerEnvironmentsExtensionTelemetry } from './envExt/telemetry';
5152

5253
export async function activateComponents(
5354
// `ext` is passed to any extra activation funcs.
@@ -84,6 +85,7 @@ export async function activateComponents(
8485
}
8586

8687
export function activateFeatures(ext: ExtensionState, _components: Components): void {
88+
registerEnvironmentsExtensionTelemetry(ext.disposables);
8789
const interpreterQuickPick: IInterpreterQuickPick = ext.legacyIOC.serviceContainer.get<IInterpreterQuickPick>(
8890
IInterpreterQuickPick,
8991
);

‎src/client/startupTelemetry.ts‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { EventName } from './telemetry/constants';
1717
import { EditorLoadTelemetry } from './telemetry/types';
1818
import { IStartupDurations } from './types';
1919
import { useEnvExtension } from './envExt/api.internal';
20+
import { getEnvsExplicitFalseScope } from './envExt/telemetry';
2021

2122
export async function sendStartupTelemetry(
2223
activatedPromise: Promise<any>,
@@ -93,7 +94,12 @@ async function getActivationTelemetryProps(
9394
const terminalHelper = serviceContainer.get<ITerminalHelper>(ITerminalHelper);
9495
const terminalShellType = terminalHelper.identifyTerminalShell();
9596
if (!workspaceService.isTrusted) {
96-
return { workspaceFolderCount, terminal: terminalShellType, isFirstSession };
97+
return {
98+
workspaceFolderCount,
99+
terminal: terminalShellType,
100+
isFirstSession,
101+
envsExplicitFalseScope: getEnvsExplicitFalseScope(),
102+
};
97103
}
98104
const interpreterService = serviceContainer.get<IInterpreterService>(IInterpreterService);
99105
const mainWorkspaceUri = workspaceService.workspaceFolders?.length
@@ -150,5 +156,6 @@ async function getActivationTelemetryProps(
150156
appName,
151157
isFirstSession,
152158
usingEnvironmentsExtension,
159+
envsExplicitFalseScope: getEnvsExplicitFalseScope(),
153160
};
154161
}

‎src/client/telemetry/constants.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
export enum EventName {
77
FORMAT_ON_TYPE = 'FORMAT.FORMAT_ON_TYPE',
88
EDITOR_LOAD = 'EDITOR.LOAD',
9+
ENVIRONMENTS_EXTENSION_SETTING_CHANGED = 'ENVIRONMENTS_EXTENSION.SETTING_CHANGED',
910
REPL = 'REPL',
1011
INVOKE_TOOL = 'INVOKE_TOOL',
1112
CREATE_NEW_FILE_COMMAND = 'CREATE_NEW_FILE_COMMAND',

‎src/client/telemetry/index.ts‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { EnvironmentType, PythonEnvironment } from '../pythonEnvironments/info';
1313
import { TensorBoardPromptSelection } from '../tensorBoard/constants';
1414
import { EventName } from './constants';
1515
import type { UnitTestRunFailureCategory } from './constants';
16-
import type { TestTool } from './types';
16+
import type { EnvsExplicitFalseScope, TestTool } from './types';
1717

1818
/**
1919
* Checks whether telemetry is supported.
@@ -359,7 +359,8 @@ export interface IEventNamePropertyMapping {
359359
"usinguserdefinedinterpreter" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "luabud" },
360360
"usingglobalinterpreter" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "luabud" },
361361
"isfirstsession" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "luabud" },
362-
"usingenvironmentsextension" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "eduardovil" }
362+
"usingenvironmentsextension" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "eduardovil" },
363+
"envsexplicitfalsescope" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "eleanorjboyd" }
363364
}
364365
*/
365366
[EventName.EDITOR_LOAD]: {
@@ -410,6 +411,23 @@ export interface IEventNamePropertyMapping {
410411
* If user has enabled the Python Environments extension integration
411412
*/
412413
usingEnvironmentsExtension?: boolean;
414+
/**
415+
* Scope kinds explicitly setting python.useEnvironmentsExtension to false, even if overridden.
416+
* 'none' excludes defaults; 'multiple' means more than one of user, workspace, or folder.
417+
*/
418+
envsExplicitFalseScope?: EnvsExplicitFalseScope;
419+
};
420+
/**
421+
* Reports explicit-false scopes after a python.useEnvironmentsExtension configuration change.
422+
* This is a configuration notification, not proof of user intent or a changed integration decision.
423+
*/
424+
/* __GDPR__
425+
"environments_extension.setting_changed" : {
426+
"envsexplicitfalsescope" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "eleanorjboyd" }
427+
}
428+
*/
429+
[EventName.ENVIRONMENTS_EXTENSION_SETTING_CHANGED]: {
430+
envsExplicitFalseScope: EnvsExplicitFalseScope;
413431
};
414432
/**
415433
* Telemetry event sent when substituting Environment variables to calculate value of variables

‎src/client/telemetry/types.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { EventName } from './constants';
88

99
export type EditorLoadTelemetry = IEventNamePropertyMapping[EventName.EDITOR_LOAD];
1010

11+
export type EnvsExplicitFalseScope = 'none' | 'user' | 'workspace' | 'folder' | 'multiple';
12+
1113
export type PythonInterpreterTelemetry = IEventNamePropertyMapping[EventName.PYTHON_INTERPRETER];
1214
export type TestTool = 'pytest' | 'unittest';
1315
export type TestRunTelemetry = IEventNamePropertyMapping[EventName.UNITTEST_RUN];

0 commit comments

Comments
 (0)