You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 39ba576
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: .github/instructions/testing-workflow.instructions.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,6 +20,8 @@ This guide covers the full testing lifecycle:
20
20
21
21
- Pip commands that return JSON must pass `--disable-pip-version-check`; the process helper combines stderr with stdout, so update notices can otherwise make valid JSON unparseable (1).
22
22
- When a view subscribes to a newly added provider event, TypeMoq-based view tests must return a real `EventEmitter.event`; an unstubbed event yields an undefined disposable and fails during teardown (1).
23
+
- Test agent selections across a full reload with `python.defaultInterpreterPath` set. An effective manager value equal to the extension default does not prove a workspace value was saved; tool-owned persistence must inspect `workspaceValue` or startup can restore the global interpreter (1).
24
+
-`vscode.executeCodeLensProvider` verifies provider output, not visible editor refresh. VS Code cancels its debounced CodeLens refresh when the editor loses focus; account for background UI automation restoring focus to another app before diagnosing a stale rendered lens (1).
Copy file name to clipboardExpand all lines: CONTRIBUTING.md
+146Lines changed: 146 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -98,6 +98,152 @@ The npm package under [`api/`](./api) is the public API facade other extensions
98
98
-`src/api.ts`, `src/types.ts`, and `src/publicErrors.ts` are validated on every PR by the extension's own lint and TypeScript compile.
99
99
-**Versioning and compatibility:** the published package version in [`api/package.json`](./api/package.json) is maintained independently of the extension version in [`package.json`](./package.json) — the two do not need to match. Compatibility is based on the API shape exported by the installed Python Environments extension at runtime. Package updates must preserve backwards-compatible contracts unless the API package version intentionally communicates a breaking change; consumers should treat newly added members as optional when they may run against older installed extension versions. Any PR that edits `src/api.ts`, `src/types.ts`, or `src/publicErrors.ts` must bump `api/package.json` (use the `skip api version` label to bypass) and add an entry to [`api/CHANGELOG.md`](./api/CHANGELOG.md) (use the `skip api changelog` label to bypass).
100
100
101
+
## Internal Python agent-tool bridge
102
+
103
+
The extension's existing **flat** export also provides `__pythonTools.version === 1`.
104
+
This is an internal convention, not a security boundary or a supported public API.
105
+
Its types live only in `src/internal/pythonToolsApi.ts`; do not copy them into
106
+
`src/types.ts`, `src/api.ts`, or the published API package. Consumers must check the
107
+
version and all three methods at runtime before using the private API. The Python
108
+
consumer uses its previous public Environments integration when that capability
109
+
is absent or incompatible; that compatibility route can still prompt. It never
110
+
falls back after a private operation starts, including errors, partial results,
111
+
timeouts, or cancellation. Environments-disabled users retain the legacy Python
112
+
route.
113
+
Explicit compatibility selection persists through the public Environments setter, not
114
+
just the Python extension's cached interpreter path, so later package operations
115
+
use the same environment. Reusing an already-selected environment is read-only;
116
+
it does not reselect or wait for an interpreter-change event.
117
+
118
+
| Method | Request | Result |
119
+
| --- | --- | --- |
120
+
|`configureEnvironment(request, token)`|`{ resourcePath?: string, pythonPath?: string }`| Select an explicit interpreter exactly; otherwise reuse an isolated environment or create one for the project. Success includes `created`. |
121
+
|`getEnvironment(request, token)`|`{ resourcePath?: string, includePackages?: boolean }`| Resolve the real selected environment, not the public API's short-timeout cache. `includePackages: true` returns `{ name, version?: string }[]`, including `[]`, or an error. |
122
+
|`installPackages(request, token)`|`{ resourcePath?: string, packages: string[] }`| Install into an isolated environment. Does not create or change selection implicitly, or modify any global/base interpreter. |
123
+
124
+
Automatic configuration uses isolation by default, regardless of whether a global
125
+
interpreter was selected automatically or by a person. Virtual environments are
126
+
recognized by `pyvenv.cfg`; non-base Conda and inline-script environments are also
127
+
isolated. Existing isolated environments outside the workspace remain reusable.
128
+
When no isolated environment is selected, configuration can resolve Poetry/Pipenv
129
+
caches through the native finder's project association. It does not infer ownership
130
+
from the cache location or record selection history; ambiguous project matches
131
+
require an explicit `pythonPath`. Read-only queries do not select these candidates.
132
+
There is no selection-origin bookkeeping or persistence. Old origin records are
133
+
ignored; ordinary current-interpreter selection and its persistence are unchanged.
134
+
An explicit `pythonPath` selects that interpreter without creating an environment.
135
+
This can select global Python for execution or queries, but does not authorize
136
+
package installation into it: `ENVIRONMENT_NOT_ISOLATED` directs the caller to
137
+
configure without `pythonPath` or select an existing isolated environment.
138
+
139
+
All methods require a VS Code `CancellationToken` and a trusted workspace.
140
+
`resourcePath` accepts an absolute path or a `file:` URI within an open workspace.
141
+
The Python tools default an omitted or empty path to the first workspace folder and
142
+
pass it explicitly. They disclose the target in preparation/results and instruct agents
143
+
to reuse the returned `resourcePath`. Editor focus does not change this default.
144
+
At the direct private API boundary, omission selects the only workspace root;
145
+
zero/multiple roots still produce actionable errors. The consumer default does not
146
+
relax that backend validation.
147
+
Other explicit input is never replaced by that default. Because the route is
148
+
workspace scoped, read-only tools keep their previous Environments behaviour when
149
+
no folder is open. Configuration and installation with a compatible private API
150
+
report `NO_WORKSPACE` instead of opening a picker or modifying global Python.
151
+
Nested projects and per-script selections retain their scope; a file is
152
+
never used as an environment creation directory. There is no User/global settings
153
+
fallback. An explicit `pythonPath` can switch away from an unavailable manager.
154
+
New nested targets persist as exact project entries without changing root defaults;
155
+
their automatic dependency discovery is restricted to that target directory.
156
+
Tool selections at the workspace root persist an explicit workspace manager, even
157
+
when it matches the extension default. This prevents `python.defaultInterpreterPath`
158
+
from restoring global Python on reload without rewriting that interpreter setting.
159
+
Ordinary human selections retain their existing settings-write behavior.
160
+
161
+
Results are `{ status: 'success', environment, resourcePath?, created?, packages? }`
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -130,7 +130,7 @@ All commands can be accessed via the Command Palette (`ctrl/cmd + Shift + P`):
130
130
| pythonProjects |`[]`| A list of Python workspaces, specified by the path, in which you can set particular environment and package managers. You can set information for a workspace as `[{"path": "/path/to/workspace", "envManager": "ms-python.python:venv", "packageManager": "ms-python.python:pip"]}`. |
131
131
| terminal.showActivateButton |`false`| (experimental) Show a button in the terminal to activate/deactivate the current environment for the terminal. This button is only shown if the active terminal is associated with a project that has an activatable environment. |
132
132
| terminal.autoActivationType |`"command"`| Specifies how the extension can activate an environment in a terminal. Accepted values: `command` (execute activation command in terminal), `shellStartup` (`terminal.integrated.shellIntegration.enabled` successfully enabled or we may modify shell startup scripts ), `off` (no auto-activation). Shell startup is only supported for: zsh, fish, pwsh, bash, cmd. **Takes precedence over**`python.terminal.activateEnvironment`. Restart terminals after changing this setting. To revert shell startup changes, run `Python Envs: Revert Shell Startup Script Changes`. |
133
-
| alwaysUseUv |`true`| When `true`, [uv](https://github.com/astral-sh/uv) will be used to manage all virtual environments if available. When `false`, uv will only manage virtual environments explicitly created by uv. The extension prefers`uv` on its PATH; if unavailable in a trusted workspace, it also checks that workspace's `.pyprojectx/main/uv` (`uv.exe` on Windows) for environments inside that workspace. External environments still require uv on PATH. This does not alter the integrated terminal's PATH. |
133
+
| alwaysUseUv |`true`| When `true`, [uv](https://github.com/astral-sh/uv) will be used to manage all virtual environments if available. When `false`, uv will only manage virtual environments explicitly created by uv. The extension uses`uv` on its PATH, or the executable it installed during the current session. If unavailable in a trusted workspace, it also checks that workspace's `.pyprojectx/main/uv` (`uv.exe` on Windows) for environments inside that workspace. External environments require uv on PATH or a current-session installation. This does not alter the integrated terminal's PATH. |
134
134
| globalSearchPaths |`[]`| Global search paths for Python environments. Array of absolute directory paths to search for environments at the user level. This setting is merged with the legacy `python.venvPath` and `python.venvFolders` settings. |
135
135
| workspaceSearchPaths |`[]`| Workspace search paths for Python environments. Can be absolute paths or relative directory paths searched within the workspace. |
Copy file name to clipboardExpand all lines: docs/managing-python-projects.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -101,7 +101,9 @@ When you create a script, the extension generates a single `.py` file with PEP 7
101
101
102
102
An inline-script environment is built from the script's `# /// script` block and stored in the extension's cache, where it is shared by every script with the same dependencies and base interpreter. Because editing one would silently change the others, these environments are not user-managed: the Python Environments views do not offer install, uninstall, or version-change actions for them. Their package list remains visible.
103
103
104
-
A CodeLens above the `# /// script` block offers **Set up environment for this script**, and the same action is available as a quick fix on an unresolved import. For a few seconds after setup succeeds it is replaced by a **Script environment ready (Python X.Y.Z)** confirmation naming the Python that was selected — useful when `requires-python` matches several installed versions, or when one was installed on demand. The confirmation is plain text rather than a clickable action, and it expires on its own; at every other time the setup CodeLens behaves exactly as before.
104
+
A CodeLens stays above the `# /// script` block, including while its metadata is incomplete, malformed, or unsaved. It offers **Set up environment for this script** until the block matches a validated environment, then displays **Script environment ready (Python X.Y.Z)** as persistent, non-clickable text. The ready label also appears for environments restored after reopening VS Code.
105
+
106
+
The CodeLens follows the live block text: editing the block offers setup immediately without requiring a save, while editing Python code outside it does not change its fingerprint. Diagnostics continue to explain malformed metadata as you type; a warning popup appears only if you try to set up an invalid block. Setup saves valid unsaved changes before creating the environment. Execution and interpreter routing still use validated, saved metadata, and saving can restore a matching existing association without rebuilding it.
105
107
106
108
Setup records which distributions it installed. If that record and the environment's contents later disagree — for example after installing a package into it from a terminal — every script sharing the environment needs setup again. Saving or reopening a script does not repair it; use the script's setup action to rebuild from its declared dependencies.
0 commit comments