Skip to content

Add opt-in refreshExtensionOnPackagesChange to restart the language server on package changes#72

Merged
edvilme merged 11 commits into
mainfrom
copilot/add-option-to-refresh-on-package-update
Jun 26, 2026
Merged

Add opt-in refreshExtensionOnPackagesChange to restart the language server on package changes#72
edvilme merged 11 commits into
mainfrom
copilot/add-option-to-refresh-on-package-update

Conversation

Copilot AI commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an opt-in ToolConfig.refreshExtensionOnPackagesChange key that restarts the language server whenever the active Python environment's package managers report a package change (install/uninstall). The behavior is wired through the shared activation logic and is off by default, so existing extensions are unaffected until they opt in.

Changes

  • types.ts — new optional ToolConfig.refreshExtensionOnPackagesChange boolean (defaults to false).
  • activation.ts — when the key is true, initializePython is given a callback that restarts the language server (safeRunServer, same path as config/interpreter changes) on each package change.
  • python.tsIPythonApi exposes an onDidChangePackages subscription. The newer ms-python.python-environments adapter forwards the extension event; the legacy ms-python.python adapter is a no-op since it does not emit package events. The automatic refresh wiring (the callback that restarts the server) stays internal to activation.
  • Testsactivation.test.ts covers the enabled (callback restarts server) and disabled (no callback) paths; python.test.ts confirms initializePython accepts the optional callback.
  • Docs — README and CHANGELOG updated.
  • Version — bumped to 0.8.0.

Validation

  • npm run build — clean
  • npm test — 127 passing

Copilot AI changed the title [WIP] Add option to refresh extension on package update Add opt-in server refresh on package changes Jun 24, 2026
Copilot AI requested a review from edvilme June 24, 2026 22:01
Copilot AI changed the title Add opt-in server refresh on package changes Move refresh-on-package-change opt-in from a VS Code setting to a ToolConfig key Jun 24, 2026
Copilot AI changed the title Move refresh-on-package-change opt-in from a VS Code setting to a ToolConfig key Handle package-change refresh internally and drop public onDidChangePackages Jun 24, 2026
… event internal

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@edvilme edvilme changed the title Handle package-change refresh internally and drop public onDidChangePackages Add opt-in refreshExtensionOnPackageChange to restart the language server on package changes Jun 25, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@edvilme

edvilme commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

@edvilme edvilme marked this pull request as ready for review June 25, 2026 23:52
edvilme and others added 2 commits June 25, 2026 16:53
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@edvilme edvilme changed the title Add opt-in refreshExtensionOnPackageChange to restart the language server on package changes Add opt-in refreshExtensionOnPackagesChange to restart the language server on package changes Jun 25, 2026
Comment thread typescript/src/activation.ts Outdated
Comment thread typescript/src/python.ts Outdated
Comment thread typescript/src/python.ts Outdated
Comment thread typescript/src/activation.ts Outdated
Comment thread typescript/tests/activation.test.ts
Comment thread typescript/package-lock.json
@rchiodo

rchiodo commented Jun 26, 2026

Copy link
Copy Markdown

Solid, well-scoped opt-in feature. The main thing to resolve before merge is that the package-change subscription is only wired when the Python extension resolves the interpreter — pinning an interpreter via setting makes refreshExtensionOnPackagesChange: true silently do nothing. Either wire it in both paths or document the limitation. A few smaller hardening/test items are noted inline.

@rchiodo

rchiodo commented Jun 26, 2026

Copy link
Copy Markdown

Solid, well-scoped opt-in feature. The main thing to resolve before merge is the pinned-interpreter dead zone: when <serverId>.interpreter is set, initializePython is never called, so refreshExtensionOnPackagesChange: true does nothing and nothing tells the user. Either wire the subscription independently of how the interpreter was resolved (mirroring the onDidChangeInterpreter pattern in registerCommonSubscriptions) or document the limitation. Also worth hardening: don't let the refresh subscription run before refreshServerPython(), and add a real integration test for the one wiring line.

…rden subscription

- Wire onDidChangePackages refresh regardless of how the interpreter was chosen (resolved by the Python extension or pinned via setting), so refreshExtensionOnPackagesChange is never silently inert.

- Move the subscription into a dedicated, non-fatal PythonEnvironmentsProvider.subscribeToPackageChanges (guards typeof + try/catch, returns undefined on failure) so it can never block server startup.

- Add a trailing-edge debounce around the package trigger to collapse bursty multi-package installs into one restart.

- Add real subscription test (fake IPythonApi + fired event) and rewrite activation tests to await an observable restart signal instead of counting macrotasks; cover the pinned-interpreter path.

- Revert incidental package-lock.json peer-drift, keeping only the version bump.

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

edvilme commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Thanks for the thorough review! Addressed in 4cb83cb:

  • Pinned-interpreter blocker — the package subscription is now wired in initialize() after interpreter resolution in both paths (extension-resolved and pinned via <serverId>.interpreter), so refreshExtensionOnPackagesChange: true is never silently inert.
  • Non-fatal subscription — moved into a dedicated PythonEnvironmentsProvider.subscribeToPackageChanges() that guards typeof onDidChangePackages and try/catches, returning undefined on failure. It can no longer block interpreter resolution or server startup.
  • Debounce — added a trailing-edge debounce around the package trigger to collapse bursty installs. Active-environment filtering is deferred pending the richer event payload (Add site-packages watchers vscode-python-environments#1597).
  • Tests — real subscription test (fake API + fired event), pinned-path coverage, and rewrote the activation test to await an observable restart signal instead of counting macrotasks.
  • Lock hygiene — reverted the incidental "peer": true drift; the lock diff is now just the version bump.

npm run build, npm run lint, and npm test (131 passing) all green.

Comment thread typescript/src/python.ts
@rchiodo

rchiodo commented Jun 26, 2026

Copy link
Copy Markdown

Looks good. Note that most of the carried-over 'unresolved' findings no longer apply to this revision: the subscription is now a standalone subscribeToPackageChanges method wired after interpreter resolution (so it works for pinned interpreters too, with a test to prove it), a trailing-edge triggerPackageRefresh debounce was added, and the tests now inject a fake API / await an observable signal rather than relying on getApi() returning undefined or flushing macrotasks. Only two small non-blocking items below.

@rchiodo rchiodo left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Approved via Review Center.

@edvilme edvilme merged commit 74080a4 into main Jun 26, 2026
20 checks passed
@edvilme edvilme deleted the copilot/add-option-to-refresh-on-package-update branch June 26, 2026 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants