Python LSP Server
Python LSP Server (`pylsp`) provides a Language Server Protocol (LSP) implementation for Python. It offers features like autocompletion, linting, formatting, refactoring, and more, integrating with various editors and IDEs. It is currently at version 1.14.0 and maintains an active release cadence with frequent minor updates and occasional major versions introducing new features or breaking changes.
Warnings
- breaking The built-in `rope_rename` plugin was removed in v1.11.0. If you relied on Rope-based rename functionality, you must now install the `pylsp-rope` third-party plugin separately.
- breaking Support for Python 3.8 was officially dropped in version 1.13.0. Users on Python 3.8 must use an older version of `python-lsp-server`.
- gotcha Many advanced features like linting (Flake8, Pylint), formatting (Black, Autopep8), and import sorting (isort) require their respective Python packages to be installed alongside `python-lsp-server` to function.
- gotcha While v1.14.0 introduced fixes for Python 3.14 compatibility, older versions of `python-lsp-server` (pre-1.14.0) might exhibit issues or incomplete support when used with Python 3.14.
Install
-
pip install python-lsp-server -
pip install 'python-lsp-server[all]'
Imports
- main
from pylsp.cli import main
Quickstart
import subprocess
import sys
import os
import time
import shutil
# The Python LSP Server is primarily meant to be run as a separate process
# and communicated with via stdin/stdout using the Language Server Protocol.
# This example shows how to launch it programmatically for testing or custom integration.
print("Launching python-lsp-server in a subprocess...")
try:
# Using `sys.executable -m pylsp` ensures the correct Python environment is used.
# We redirect stdout/stderr to pipes to prevent it from blocking the console.
# For real use, stdout would carry LSP messages to a client.
process = subprocess.Popen(
[sys.executable, '-m', 'pylsp', '--log-level', 'WARNING'], # Adjust log-level as needed
stdin=subprocess.PIPE, # Server expects LSP messages here
stdout=subprocess.PIPE, # Server sends LSP messages here
stderr=subprocess.PIPE, # Server logs errors/debug info here
text=True, # Handle stdin/stdout as text
bufsize=0 # Unbuffered I/O for real-time LSP communication
)
print("Server process started.")
print("It is now listening for LSP messages on stdin and sending responses on stdout.")
print("This process will block waiting for input unless a client sends messages.")
print("Waiting for 2 seconds to simulate runtime...")
time.sleep(2)
# In a real scenario, you would send JSON-RPC LSP messages here, e.g.,
# process.stdin.write('Content-Length: ...\r\n\r\n{"jsonrpc": "2.0", ...}\r\n')
# process.stdin.flush()
print("Attempting to terminate the server.")
process.terminate() # Send SIGTERM (or equivalent on Windows)
stdout, stderr = process.communicate(timeout=5) # Wait for it to exit and get output
print(f"\nServer exit code: {process.returncode}")
if stdout:
print("\n--- Server STDOUT (LSP messages) ---")
print(stdout.strip())
if stderr:
print("\n--- Server STDERR (Logs/Errors) ---")
print(stderr.strip())
except FileNotFoundError:
print(f"Error: `pylsp` command or `sys.executable` not found. Is python-lsp-server installed?")
except subprocess.TimeoutExpired:
print("Server did not terminate gracefully within the timeout. Killing it.")
process.kill()
stdout, stderr = process.communicate()
except Exception as e:
print(f"An error occurred: {e}")
finally:
print("Quickstart demonstration complete.")