Python language servers revisited
What are the best linters and language servers for python?
LSP for Python?
Introducing the Python Language Server
Videos
All of the different language servers, linters, and formatters available for Python can be very confusing. There is significant overlap between tools and it's hard to know what is what- this is my attempt to sort through it all.
Below is what I have been able to figure out, corrections and additions added as I see them from the comments.
Ruff is a fast linter / code formatter. It has overtaken Black and Flake8 as the best / most popular linter although not as thourough as Pylint. Rust.
JEDI is a static analysis tool that supports autocompletion, goto, and refactoring. It works with several langauge servers. Similar functionality to Pyright. Python.
Pyright is a language server maintained by Microsoft. It supports type checking (primary function), goto, autocomplete, similar to JEDI. It is written in TypeScript. Pylance is a Microsoft product that builds on Pyright and adds additional feataures to VS Code. TypeScript.
Basedpyright is a fork of Pyright to add Pylance functionality to Pyright for non-Microsoft editors. Mostly TypeScript with Python additions.
MyPy is one of the original static type checkers (2012, but still actively maintained). Python.
PyLSP/Python LSP Server is a language server implementation that interfaces with other libraries like JEDI to provide various LSP functionality. Python.
Pylint is a static code analyser and very thorough (and slow) linter. It can be used alongside other analysis tools like Ruff or Black, and mypy or pyright. Python.
In addition to the above, some commercial IDEs like PyCharm use their own proprietary linters and type checkers.
I use the Helix editor and by default it will use Ruff, JEDI, and pylsp together. I was confused why it used more than one language server/library, which was the motivation for looking into all of this.
I am the author of multilspy, which is a LSP client in Python, with a library interface and is intended to be used to build applications around language servers. It handles the configuration and initialization of different language servers, and offers a simple interface. It currently supports running Eclipse JDT.LS for Java, rust-analyzer for Rust, OmniSharp for C# and jedi-language-server for Python. You can install it using pip by running:
pip install multilspy
Example usage of multilspy:
from multilspy import SyncLanguageServer
from multilspy.multilspy_config import MultilspyConfig
from multilspy.multilspy_logger import MultilspyLogger
...
config = MultilspyConfig.from_dict({"code_language": "java"}) # Also supports "python", "rust", "csharp"
logger = MultilspyLogger()
lsp = SyncLanguageServer.create(config, logger, "/abs/path/to/project/root/")
with lsp.start_server():
result = lsp.request_definition(
"relative/path/to/code_file.java", # Filename of location where request is being made
163, # line number of symbol for which request is being made
4 # column number of symbol for which request is being made
)
result2 = lsp.request_completions(
...
)
result3 = lsp.request_references(
...
)
...
I've discovered that, as of July 2023, there is a library named pygls (https://github.com/openlawlibrary/pygls) that is currently developing a usable client for the Language Server Protocol (LSP).
While we wait for the first official release, I've included it in my setup.py file under "install_requires". This ensures it will be automatically installed during the setup of my project. Here's how I modified the file:
install_requires=[
'pygls @ git+https://github.com/openlawlibrary/pygls.git'
]
With this line of code, pygls will be directly fetched from the GitHub repository and installed into your environment.