Skip to content

Use exact per-file environments for Python files (PEP 723 PR 19) - #26129

Open
Stella Huang (StellaHuang95) wants to merge 3 commits into
microsoft:mainfrom
StellaHuang95:copilot/pep723-pr19
Open

Use exact per-file environments for Python files (PEP 723 PR 19)#26129
Stella Huang (StellaHuang95) wants to merge 3 commits into
microsoft:mainfrom
StellaHuang95:copilot/pep723-pr19

Conversation

@StellaHuang95

@StellaHuang95 Stella Huang (StellaHuang95) commented Aug 28, 2026

Copy link
Copy Markdown

Part of microsoft/vscode-python-environments#1602. Design doc: microsoft/vscode-python-environments#1601.

Roadmap context

This is cross-repository PR 19 in the PEP 723 roadmap. It closes the Python extension's per-file lookup gaps for debugging and Pylance configuration.

Cross-repository integration PR Status
Environments PR 7: persisted script associations merged (#1697)
Environments PR 10: exact script projects microsoft/vscode-python-environments#1744
PR 17: Pylance per-file Python path lookup microsoft/pyrx#9265
PR 19: exact Python-file lookup and debugger resolution this PR

Why this PR

IInterpreterService.getActiveInterpreter(resource) normally shares in-flight, timeout, and last-known state by workspace folder. A file URI can therefore receive the workspace interpreter when a workspace lookup is already running or when exact environment resolution exceeds the timeout.

That breaks two per-file consumers:

  • debugger launch resolution can select the workspace interpreter instead of the launch program's interpreter;
  • Pylance's file-scoped workspace/configuration request can receive a cached workspace interpreter.

The exact lookup must also avoid publishing a file interpreter as a workspace-wide interpreter change.

What this PR does

  • Adds an internal exactResource option to IInterpreterService.
  • Bypasses workspace-keyed in-flight, timeout, and last-known state for exact environment-extension lookups.
  • Suppresses workspace-level interpreter-change reporting for those silent exact reads.
  • Resolves debugger programs from:
    • absolute paths;
    • ${file};
    • ${workspaceFolder};
    • ${workspaceFolder:name}.
  • Prefers the program interpreter and falls back to the normal workspace interpreter only when no exact environment is available.
  • Reuses the selected interpreter for both legacy pythonPath and command-valued python.
  • Applies activation variables when the program interpreter differs from the workspace interpreter.
  • Uses exact lookup only for .py-scoped Pylance configuration requests; workspace-level requests retain the existing cached fast path.

Lookup semantics

Condition Behavior
No concrete launch program Preserve workspace lookup
Exact program environment exists Use it for debugger resolution
Exact program lookup returns no environment Fall back to workspace interpreter
Program and workspace interpreters match Preserve existing terminal activation behavior
Program interpreter differs Apply its activation variables
Pylance requests python config for a .py URI Resolve the exact file environment
Pylance requests workspace-level config Preserve normal workspace caching
Exact lookup resolves an environment Do not publish a false workspace interpreter-change event

Performance and safety

  • The existing fast workspace cache remains unchanged for normal consumers.
  • Exact lookup is opt-in and used only by debugger program selection and .py configuration scopes.
  • The environments extension's own URI-scoped timeout/last-known behavior remains in effect.
  • No public Python or environments API is changed.

User impact

Users without a per-file environment retain the same interpreter and debugger behavior. When a Python file has a distinct environment, Pylance configuration and debugger launch consistently use that file's interpreter rather than a workspace-cached value.

Tests

  • Prettier check for all changed files
  • ESLint for all changed files
  • Focused middleware, resolver, launch, environment-adapter, and interpreter-service tests: 181 passing, 3 pending
  • Repository-wide TypeScript compilation currently also reports two existing TelemetryReporter import errors in untouched files.
  • The full unit command was run; its failures were confined to untouched platform/path, terminal activation, activated-environment, and native-finder tests.

Scope and follow-up

This PR does not implement Pylance's open-file rerouting notification. Live movement and reanalysis after a per-file environment change remain in PR 18.

Resolve debugger programs and Pylance Python-file configuration against the exact file resource without publishing false workspace interpreter changes. Preserve workspace fallback and activate differing program environments.

Part of microsoft/vscode-python-environments#1602.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@StellaHuang95 Stella Huang (StellaHuang95) added the feature-request Request for new features or functionality label Aug 28, 2026
@bschnurr

Bill Schnurr (bschnurr) commented Aug 28, 2026

Copy link
Copy Markdown
Member

🔒 Automated review in progress — Bill Schnurr (@bschnurr) is auto-reviewing this PR.

@bschnurr

Copy link
Copy Markdown
Member

Verification: The relevant tests could not be fully run in the isolated environment; this review is not fully verified.

Result: could-not-verify

Summary: Verification could not execute because no trusted sandbox image is configured for `microsoft/vscode-python`, and local execution was not authorized. The PR adds eight focused unit tests covering exact interpreter lookup, debugger selection, activation, and Pylance configuration. None could be run, so no pass/fail confidence is available. Two newly introduced debugger resolution paths appear uncovered.

Test runs: 1 not run

  • ⚠️ Not run | Verification preflight and test discovery | git status --short && git branch --show-current && git diff --name-status upstream/main...HEAD && node -e "const p=require('./package.json'); console.log(JSON.stringify({test:p.scripts.test,compile:p.scripts.compile,unit:p.scripts['test:unit'],pretest:p.scripts.pretest},null,2))" && if [ -d node_modules ]; then echo NODE_MODULES_PRESENT; else echo NODE_MODULES_MISSING; fi
⚠️ Verification preflight and test discovery diagnostic output
Container verification could not start: no trusted sandbox image is configured for microsoft/vscode-python. Local execution was not authorized for this PR HEAD.

@bschnurr Bill Schnurr (bschnurr) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approved via Review Center.

@bschnurr Bill Schnurr (bschnurr) added the review-auto:approved Automated review: no blocking findings (approval posted). label Aug 28, 2026
Clarify why the workspace/configuration handler resolves the interpreter for the exact .py file (exactResource) rather than its folder: it honors a per-file environment such as a PEP 723 inline-script env for the language client this extension hosts, and only diverges from folder resolution when the Python Environments extension is in use.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bschnurr

Copy link
Copy Markdown
Member

Verification: The relevant tests could not be fully run in the isolated environment; this review is not fully verified.

Result: could-not-verify

Summary: Verification was blocked because no trusted sandbox image is configured for `microsoft/vscode-python`, and local execution was not authorized. No tests meaningfully ran. The PR adds eight focused unit tests, but `${file}` debugger program resolution lacks explicit coverage.

Test runs: 1 not run

  • ⚠️ Not run | Verification preflight and test discovery | git status --short && git diff --name-status upstream/main...HEAD && git diff --unified=0 upstream/main...HEAD -- package.json .github\instructions\testing-workflow.instructions.md && if exist node_modules (echo NODE_MODULES_PRESENT) else (echo NODE_MODULES_MISSING) && if defined AUTOMATION_SANDBOX_PROFILE (echo AUTOMATION_SANDBOX_PROFILE=%AUTOMATION_SANDBOX_PROFILE%) else (echo AUTOMATION_SANDBOX_PROFILE_UNSET) && node -e "const p=require('./package.json'); console.log(JSON.stringify(p.scripts,null,2))"
⚠️ Verification preflight and test discovery diagnostic output
Container verification could not start: no trusted sandbox image is configured for microsoft/vscode-python, and local execution was not authorized.

The debug resolver now resolves \/\ to a program
URI and looks up the interpreter for that file. To avoid changing behavior
for users who are not using the environments extension (e.g. multi-root
debugging of a file that lives in a different folder than the launch
config), only take the program-scoped path when useEnvExtension() is true;
otherwise fall back to the historical workspace-folder resolution.
Environments-extension users still get per-file (inline-script) resolution.

Stub useEnvExtension() in the existing program-scoped resolver tests and
add a test covering the gated fallback.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bschnurr

Copy link
Copy Markdown
Member

Verification: The relevant tests could not be fully run in the isolated environment; this review is not fully verified.

Result: could-not-verify

Summary: Verification could not run because no trusted sandbox image is configured for `microsoft/vscode-python`, and local execution was not authorized. The PR adds nine focused unit tests covering exact interpreter lookup, debugger selection/fallback, named workspaces, and activation. One documented path, `${file}` debugger program resolution, has no test coverage I could find.

Test runs: 1 not run

  • ⚠️ Not run | Dependency and test discovery | git status --short && git branch --show-current && git --no-pager diff --name-status upstream/main...HEAD && if [ -d node_modules ]; then echo NODE_MODULES_PRESENT; else echo NODE_MODULES_MISSING; fi && node -e "const p=require('./package.json'); console.log(JSON.stringify(p.scripts,null,2))"
⚠️ Dependency and test discovery diagnostic output
Container verification could not start: no trusted sandbox image is configured for microsoft/vscode-python. Local execution was not authorized for this PR HEAD.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature-request Request for new features or functionality review-auto:approved Automated review: no blocking findings (approval posted).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants