Fix pytest discovery using workspace-root interpreter after missed startup environment events - #26195
Open
MOHAMMED WASIM KHAN (wasim-builds) wants to merge 1 commit into
Conversation
…d startup environment events Subscribe to Python Environments extension project/environment changes before the initial test project discovery, and queue re-discovery for workspaces whose initial project registration is still in flight when an environment is assigned. Previously, environment assignments raised while initial discovery was running were missed entirely, leaving the workspace stuck on the fallback default project that discovers tests with the workspace-root (e.g. system) interpreter instead of the project's environment. Fixes microsoft#25718
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #25718.
In a monorepo where a Python sub-project has its own environment (e.g.
apps/example-py/.venv), pytest test discovery can run with the workspace-root interpreter (system Python, without pytest) instead of the project's environment, failing withNo module named pytest. The reporter suspected a race between the Python Environments extension and the Python extension; this PR closes that race in the project-based test discovery flow ([test-by-project]).Root cause
Project-based discovery intentionally falls back to a "default project" bound to the workspace-root interpreter when a project's environment has not been assigned yet, and relies on the environments extension's
onDidChangeEnvironment/onDidChangePythonProjectsevents to re-discover once environments resolve. Two startup holes made that self-healing unreliable:Events raised before subscription were dropped.
activate()awaited the initialdiscoverAndRegisterProjects()for every workspace before callingsubscribeToProjectChanges()/subscribeToEnvironmentChanges(). Acquiring the environments API during that initial discovery is what activates the environments extension and kicks off its initial refresh, so the environment assignments produced by that refresh could fire into a window where nobody was listening. The workspace then stayed on the fallback default project (workspace-root interpreter) until a manual refresh or file save.Events arriving during initial registration were ignored.
handleEnvironmentChangeonly queued workspaces for whichprojectRegistry.hasProjects()was already true. An environment assignment raised while a workspace's initial project discovery was still in flight (nothing registered yet) was dropped, with the same stuck-on-wrong-interpreter result.Changes (
src/client/testing/testController/controller.ts)activate(): subscribe to project and environment changes before the initial project discovery, so no assignments are missed during startup.handleEnvironmentChange(): queue re-discovery for any workspace that is not in legacy mode (i.e. has no legacyWorkspaceTestAdapterregistered), instead of only workspaces with already-registered projects. Legacy-mode workspaces are still skipped; workspaces mid-registration are now covered.No changes to the fallback default-project behavior itself, to discovery/execution adapters, or to interpreter resolution.
Tests
compile:npx tsc -p ./passes.npm run test:unittestsmocha config): allPythonTestControllerand testing-controller suites pass (13/13 controller tests; 108/108 across the testController-related suites).ignores workspaces that are not in project-based modeto explicitly cover legacy mode (legacy adapter registered).queues workspaces whose initial project registration is still in flight.activate() subscribes to project and environment changes before initial project discovery(asserts call ordering).Terminal Environment Variable Collection Serviceconda-shell mocks,Native Python Finderbinary tests); verified identical failures on a pristineupstream/mainworktree.Test plan / manual verification
I could not run the VS Code integration host here, so end-to-end verification with the reporter's monorepo example is still needed:
apps/example-pywith its.venv).No module named pytestdiscovery error from the system Python; once the environments extension assigns the project environment, the workspace re-discovers automatically and the test tree is rooted at the project with its venv.