FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

[pull] main from microsoft:main by pull[bot] · Pull Request #215 · ConnectionMaster/vscode-python · GitHub

[pull] main from microsoft:main - #215

Merged
pull[bot] merged 1 commit into
ConnectionMaster:mainfrom
microsoft:main
Aug 18, 2026
Merged

[pull] main from microsoft:main#215
pull[bot] merged 1 commit into
ConnectionMaster:mainfrom
microsoft:main

Conversation

pull Bot commented Aug 18, 2026
edited
Loading

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

## Summary

- skip Conda environment placeholders that do not contain a Python
interpreter
- isolate EnvExt conversion failures per item so one unsupported
environment cannot discard later valid environments in the same update
batch
- harden active-interpreter conversion and use consistent executable
identity when removing environments from the compatibility collection
- add focused coverage for discovery, active-environment, removal, and
refresh flows

Fixes microsoft/vscode-python-environments#1681
Related to microsoft/vscode-python-environments#1671

## Context

The Python Environments extension can discover and manage Conda
environments that do not currently have Python installed. It
intentionally exposes those entries to its Environment Manager UI as
placeholders:

```text
name: empty-env
version: no-python
run executable: conda
```

That is useful in the management UI, but the entry is not a selectable
Python interpreter.

Users reported that PET and Environment Manager showed every Conda
environment while both `Python: Select Interpreter` and Jupyter's
Python-environment kernel picker showed only System Python and the
current project environment. Both users confirmed that Python was
delegating discovery to the Python Environments extension, ruling out
the legacy discovery path.

One user then performed a reversible A/B test:

1. with a no-Python Conda environment under `miniconda3/envs`, Python
and Jupyter omitted the other valid Conda environments
2. moving that unchanged directory outside `envs` and reloading restored
both pickers
3. moving it back and reloading reproduced the failure

## Root cause

`src/client/envExt/envExtApi.ts` translates Python Environments API
objects into the legacy `PythonEnvInfo` format consumed by Python and
Jupyter.

The adapter previously parsed every version unconditionally:

```ts
parseVersion(pythonEnv.version)
```

`parseVersion('no-python')` throws `invalid version no-python`.

Environment-list changes arrive as a batch and were processed by an
unguarded `forEach`. When the no-Python placeholder appeared before
valid Conda environments, its conversion exception aborted the callback,
so every valid item later in that batch was lost:

```text
no-python placeholder -> throws
valid Conda A         -> never processed
valid Conda B         -> never processed
```

System environments arrive through a separate valid batch, and
individually resolved/current environments can use separate paths,
explaining the restricted list users observed.

Refresh did not self-heal because each Conda refresh sent another batch
containing the same placeholder and failed at the same conversion point.

## Fix

### Safe version conversion

A shared EnvExt conversion helper now:

- treats the expected `no-python` sentinel as a non-interpreter and
skips it at debug log level
- catches and logs unexpected malformed version strings instead of
throwing into callers

Both discovery-list conversion and active-interpreter compatibility
conversion use this boundary.

### Per-item fault isolation

Every environment-list change is processed independently. A malformed
runtime item is logged and skipped without preventing later valid items
from reaching Python/Jupyter.

Active-environment events are emitted only when every supplied side can
be converted, avoiding synthetic partial clear/set transitions while
preserving normal valid set, clear, and change behavior.

### Consistent removal identity

Adds are keyed by the Python executable path. Removals now derive the
same executable identity from the source environment. Previously Conda
removals used the environment prefix, so they generally could not remove
an entry stored by interpreter executable.

## Behavior and compatibility

| Scenario | Result |
| --- | --- |
| Conda environment without Python | remains visible/manageable in
Environment Manager; omitted from Python/Jupyter interpreter lists |
| Valid Conda, venv, system, Poetry, Pipenv, Pyenv environments | same
conversion and picker behavior as before |
| No-Python item before valid items in a batch | placeholder skipped;
all valid later items retained |
| Unexpected malformed provider item | logged and isolated; later items
continue |
| Valid active environment set/change/clear | unchanged |
| Invalid active environment | ignored instead of throwing |
| Conda refresh remove/add batch | old executable entries removed and
valid refreshed entries restored |

The valid hot path adds only a helper call and the existing version
parse. There are no new filesystem operations, environment discovery
calls, or background tasks.

## Tests

New adapter coverage includes:

- `[no-python, valid, valid]` batch handling
- malformed version in the middle of a batch
- structurally malformed event followed by a valid item
- no-Python and partially invalid active-environment events
- valid active set/change/clear events
- Conda removal by executable identity
- refresh batches containing removals, a no-Python placeholder, and
valid additions
- the actual `triggerRefresh()` path
- active-interpreter resolution for no-Python and malformed versions

Validation performed:

- `gulp compile`
- full repository ESLint
- focused EnvExt tests: **14 passing**
- 24 downstream EnvExt/interpreter-selector/interpreter/environment-API
test files: **345 passing, 1 expected pending**
- full unit suite: **5,178 passing, 34 pending**; the remaining 10
failures are pre-existing/unrelated Windows PATH-casing assertions and
native PET timeouts in untouched suites

The complete diff also went through two code-review passes and a
design-focused review; no production issues remained after addressing
malformed-event and active set/clear coverage.

## Follow-up

The EnvExt adapter currently relies on change events rather than
hydrating an authoritative initial snapshot. That is a separate
resilience concern; this PR intentionally targets the user-confirmed
`no-python` batch-abort failure.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2f537bc5-b389-4ee2-aac2-e2b83be47f5c
pull Bot locked and limited conversation to collaborators Aug 18, 2026
pull Bot added the ⤵️ pull label Aug 18, 2026
pull Bot merged commit e0f1d3c into ConnectionMaster:main Aug 18, 2026
1 check passed
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 subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant


Back | FazBrowse Home | New Git URL