Environment data
- Python Environments extension version: 1.30.0
- Python extension (
ms-python.python) version: 2026.4.0
- VS Code version (Help → About): 1.123.0
- OS and version: macOS 26.5.1 (should happen on Linux and Windows too)
- Python version: Any
- Environment manager in use: Not relevant (uv)
- Shell: Not relevant (bash)
- Remote / container scenario: none
- Workspace type: single folder
- Is this a regression?: Unknown
Repro Steps
- Open a workspace containing a Python environment.
- Allow the Python Environments extension to discover the environment.
- Replace a watched file, such as an activation script or package
METADATA
file, using a rapid remove-and-create or atomic replacement operation.
- Observe the Python Environments view - if the operation happened fast enough
to be coalesced into a UPDATED, it will not result in the extension picking
up the change.
A simple way to reproduce this is to use uv sync --python <different version to the current one> on a reasonably fast machine.
Expected behavior
The relevant environment or package state is invalidated and refreshed after
the watched file is replaced, regardless of whether VS Code reports the
operation to the extension as create/delete events or as a change event.
Actual behavior
The extension does not refresh when VS Code or (in case of FS Events on MacOS,
the underlying filesystem API) coalesces the DELETED and ADDED into a UPDATED.
Logs
Example (partially redacted and trimmed) of VS Code coalescing two parcel events:
...
2026-06-07 12:42:45.951 [trace] [File Watcher ('parcel')] [DELETED] /.../project/.venv/bin/activate
...
2026-06-07 12:42:46.015 [trace] [File Watcher ('parcel')] [ADDED] /.../project/.venv/bin/activate
...
2026-06-07 12:42:46.027 [trace] [File Watcher ('parcel')] >> normalized [CHANGED] /.../project/.venv/bin/activate
...
Additional context
The affected watchers explicitly ignore change events and register handlers
only for creation and deletion:
|
const packageWatcher = createFileSystemWatcher( |
|
'**/site-packages/*.dist-info/METADATA', |
|
false, // don't ignore create events (pip install) |
|
true, // ignore change events (content changes in METADATA don't affect package list) |
|
false // don't ignore delete events (pip uninstall) |
|
); |
|
disposables.push( |
|
packageDebouncedRefresh, |
|
packageWatcher, |
|
packageWatcher.onDidCreate(() => { |
|
packageDebouncedRefresh.trigger(); |
|
}), |
|
packageWatcher.onDidDelete(() => { |
|
packageDebouncedRefresh.trigger(); |
|
}), |
|
const activationWatcher = createFileSystemWatcher('{**/activate}', false, true, false); |
|
disposables.push( |
|
activationWatcher, |
|
activationWatcher.onDidCreate(() => { |
|
venvDebouncedRefresh.trigger(); |
|
}), |
|
activationWatcher.onDidDelete(() => { |
|
venvDebouncedRefresh.trigger(); |
|
}), |
The second ignore argument is ignoreChangeEvents, so onDidChange is never
delivered. There is also no onDidChange listener.
A rapid delete and recreate may be coalesced into a change event by various
parts of the VSCode file watching stack:
Therefore, the assumption that the code makes, that changes are not relevant,
is unsound.
Environment data
ms-python.python) version: 2026.4.0Repro Steps
METADATAfile, using a rapid remove-and-create or atomic replacement operation.
to be coalesced into a UPDATED, it will not result in the extension picking
up the change.
A simple way to reproduce this is to use
uv sync --python <different version to the current one>on a reasonably fast machine.Expected behavior
The relevant environment or package state is invalidated and refreshed after
the watched file is replaced, regardless of whether VS Code reports the
operation to the extension as create/delete events or as a change event.
Actual behavior
The extension does not refresh when VS Code or (in case of FS Events on MacOS,
the underlying filesystem API) coalesces the DELETED and ADDED into a UPDATED.
Logs
Example (partially redacted and trimmed) of VS Code coalescing two parcel events:
Additional context
The affected watchers explicitly ignore change events and register handlers
only for creation and deletion:
vscode-python-environments/src/managers/builtin/main.ts
Lines 62 to 76 in f71716d
vscode-python-environments/src/managers/builtin/main.ts
Lines 30 to 38 in f71716d
The second ignore argument is
ignoreChangeEvents, soonDidChangeis neverdelivered. There is also no
onDidChangelistener.A rapid delete and recreate may be coalesced into a change event by various
parts of the VSCode file watching stack:
Sometimes at the OS API, like it allegedly is for FSEvent on macOS
parcel (underlying library used by VS Code)
https://github.com/parcel-bundler/watcher/blob/8926bb8b281733bbfcaf69bb4e62ab7a1431c42a/src/Event.hh#L20-L42
VS Code itself
https://github.com/microsoft/vscode/blob/331849349a69f1ba6ccf42b1a60e9a8f1f699421/src/vs/platform/files/node/watcher/parcel/parcelWatcher.ts#L453-L462
Therefore, the assumption that the code makes, that changes are not relevant,
is unsound.