Skip to content

Create VS Code Python Tools LSP Package #290

@edvilme

Description

@edvilme

TL;DR
Due to the great amount of shared code among the VSCode Python Tools extensions, and no mechanism to ensure sync/parity, we need to extract all shared code into a PyPI and NPM package to be consumed by the extensions.

1. Background

Our team maintains several extensions that enable the use of Python formatting and linting tools directly from the editor, using LSP. These are:

Due to their nature, these extensions are essentially wrappers for their respective tools, consisting mostly of workspace settings discovery mechanisms, Python interpreter/environment resolution, LSP handling, and tool spawning and communication. Hence, they share mostly the same codebase with few exceptions like output parsing, CLI arguments, feature availability, etc.

2. Motivation

The code for the extensions was originally bootstrapped from this template. However, with no mechanism to ensure syncing, the codebases from the different extensions tends to deviate over time. This causes duplicate issues with different fixes among the extensions, which makes maintaining the codebases simultaneously a very challenging task. An attempt was made to use agentic workflows detect deviations from the template, and while it aids in the chore, it does not guarantee a sustainable code base. Then, there is a need to have a single source of truth shared between the extension. So that a fix or implementation can be automatically consumed by all the codebases. The proposal is a mono-repo that exposes both PyPI and NPM packages.

3. Plan

This is an ambitious feat that requires having a deep understanding of both the template and the extensions' codebases, as well as major overhauls to all, in a way that exposes a reusable set of API's and maintains existing behavior with NO breaking changes. From the user's perspective, this should behave like an incremental update.

1. Feature parity: Identify solved bugs in different extensions

First, we need to ensure feature parity among the extensions. This includes making sure bugs previously fixed in one extension are not present in another one. This will help reduce the divergence (feature-wise) of the extensions and help keep track of edge cases. This can be achieved by comparing issues and pull requests between the extensions.

First, a list of all the issues across all repos should be obtained. Then, these should be grouped by their lowest common denominator. For each issue group, we should find the PR(s) in each repo that solved them. Issues that have not been solved or have no PRs in any of the repos should be discarded as out of scope. But issues that have been fixed in at least one of the repo's should be fixed in individual PRs for the rest of the repos

2. Test coverage

Tests on the extensions will be our way of avoiding introducing breaking changes. It is important that any special edge case or consideration is properly documented and covered by a test. All solved issues should have at least one associated test.

3. Identifying files / methods

Next, we would need to identify the files (and methods) that are shared across the extensions as they will be the focus of this migration. These should be classified as:

  • Tool-Specific: Specific to the tool, not shared across the rest of the extensions
  • Parametrizable: Shared across the rest of the extensions, but with different parameters
  • Shared: Shared as-is across the extensions

4. Refactor files

In order to make the implementation easier, affected files should be refactored to be more interchangeable. This means having same implementations for methods, same methods in each file, etc. Whenever possible, parametrize behaviors and methods.

5. Mono-Repo

After that it will be easier to extract shared/parametrizable methods and code into its own codebase. The package will be structured in a monorepo called microsoft/vscode-python-tools-lsp and contain both a python and a typescript directory with the respective packages.

6. Implementation

During implementation and while testing, the mono-repo would be consumed via a git submodule. Code should be heavily refactored to use the package and ensure that all tests pass. Any failures should be documented so either the package or the implementation in the repo can be fixed.

7. Publishing

After the implementation and integration are done, the mono-repo should be configured with the correct pipelines and proper documentation to be published to both PyPI and NPM.

4. Next Steps

Afterwards, the new extensions should have 80% code reduction. The extensions should then consume the extension from the feed rather than as a git submodule. A new agentic workflow can be introduced for triaging issues and redirecting them to the mono-repo automatically.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions