Overview
Phase 4 normalization for mypy as part of the shared package extraction effort.
Tracking issue: microsoft/vscode-python-tools-extension-template#290
What is normalization?
All 5 Python tool extensions (black-formatter, flake8, isort, mypy, pylint) were originally scaffolded from the same template and share ~70% of their code. Over time, each repo diverged: functions were renamed, parameters changed, utilities landed in different files, and features were added to some repos but not others.
Normalization is the process of re-aligning these codebases so that:
- Equivalent functions have identical signatures — e.g.,
normalize_path() should accept the same parameters everywhere
- Equivalent functionality lives in the same file — e.g., if
_get_settings_by_path() exists in 4 repos' lsp_server.py, the 5th repo should have it too
- Missing shared features are backported — e.g., localization files that exist in 3 repos should be added to the other 2
Why is this needed?
The end goal (template#290) is to extract the shared code into a reusable package (vscode-python-tool-lsp). For this to work, we need a clean 1:1 mapping between repo code and package code. If function signatures differ or utilities live in different files, extraction becomes a messy per-repo special case instead of a clean "delete shared file, import from package" operation.
All changes are backwards-compatible — adding optional parameters with defaults, aligning function signatures, and moving code to the correct files. No behavioral changes.
Tasks
Structural Alignment (methods in the right files)
Python Normalizations (bundled/tool/)
Note: mypy does not use lsp_jsonrpc.py or lsp_runner.py (uses dmypy daemon directly). These files are not applicable.
TypeScript Normalizations (src/common/)
Feature Parity
PR Strategy
Each task gets its own branch and PR for focused review:
- Branch naming:
phase4/<task-slug>
- All changes are backwards-compatible
- Tests must pass before merge
Overview
Phase 4 normalization for mypy as part of the shared package extraction effort.
What is normalization?
All 5 Python tool extensions (black-formatter, flake8, isort, mypy, pylint) were originally scaffolded from the same template and share ~70% of their code. Over time, each repo diverged: functions were renamed, parameters changed, utilities landed in different files, and features were added to some repos but not others.
Normalization is the process of re-aligning these codebases so that:
normalize_path()should accept the same parameters everywhere_get_settings_by_path()exists in 4 repos'lsp_server.py, the 5th repo should have it tooWhy is this needed?
The end goal (template#290) is to extract the shared code into a reusable package (
vscode-python-tool-lsp). For this to work, we need a clean 1:1 mapping between repo code and package code. If function signatures differ or utilities live in different files, extraction becomes a messy per-repo special case instead of a clean "delete shared file, import from package" operation.All changes are backwards-compatible — adding optional parameters with defaults, aligning function signatures, and moving code to the correct files. No behavioral changes.
Tasks
Structural Alignment (methods in the right files)
_get_env_vars()to_get_updated_env()inlsp_server.py(align with other repos)Python Normalizations (
bundled/tool/)_debug_server.pytoUSE_DEBUGPYgate pattern (currently checksDEBUGPY_PATHdirectly)resolve_symlinks=Trueparameter tonormalize_path()inlsp_utils.pyis_match()— makeworkspace_rootparameter optional withNonedefaultNote: mypy does not use
lsp_jsonrpc.pyorlsp_runner.py(uses dmypy daemon directly). These files are not applicable.TypeScript Normalizations (
src/common/)expandTilde()fromsettings.ts(already inenvFile.ts)configWatcher.tsto robust disposal pattern (error handling + disposed flag)settings.tsto baseISettingsinterface with shared fieldsserver.tsviaToolConfig.hooksinterfaceextension.tsto thin wrapper (depends on 4.1e + 4.1f)Feature Parity
package.nls.*.jsonfor all 14 locales (currently missing localization)PR Strategy
Each task gets its own branch and PR for focused review:
phase4/<task-slug>