Announcing eglot-python-preset
Contents
Introduction
I’m happy to announce the release of eglot-python-preset↗, a new Emacs package that simplifies Python LSP configuration with Eglot. It’s now available on MELPA.
The package was born from a
discussion on r/emacs↗
about using Emacs for Python development with uv and basedpyright. The original
poster had a common pain point: they were writing standalone Python scripts with
PEP-723↗ inline dependencies, using
uv run script.py to execute them. Everything worked fine from the command
line, but their LSP (basedpyright) couldn’t resolve the imports because it had
no awareness of uv’s cached environments.
This is a gap in the tooling. uv manages isolated environments for PEP-723
scripts automatically, but there was no bridge between those environments and
the editor’s language server. You’d get reportMissingImports errors for
packages that were clearly installed and working at runtime.
What eglot-python-preset Does
The package handles the glue between uv, PEP-723 scripts, and your LSP server. When you open a Python file containing PEP-723 metadata:
- It detects the script metadata automatically
- It locates the cached uv environment for that script (or prompts you to create one)
- It configures the LSP server to use that environment for type checking
For standard Python projects with pyproject.toml or requirements.txt, the
package handles project root detection so Eglot starts from the right directory.
Basic Setup
Installation from MELPA:
(use-package eglot-python-preset
:ensure t
:after eglot
:custom
(eglot-python-preset-lsp-server 'ty) ; or 'basedpyright
:config
(eglot-python-preset-setup))
The package supports both ty↗ (Astral’s new Rust-based type checker) and basedpyright↗. See my earlier post on ty for why you might want to try ty — it’s dramatically faster than the alternatives.
Key Commands
-
M-x eglot-python-preset-sync-environment- Sync dependencies for a PEP-723 script usinguv sync --script, then restart Eglot. Use this after adding or modifying dependencies in your script’s metadata block. -
M-x eglot-python-preset-remove-environment- Remove the cached environment to force a clean reinstall. -
M-x eglot-python-preset-run-script- Run the current script usinguv runin a compilation buffer.
Future Directions
There are two potential follow-ups I’m considering:
Autodetecting tools: Currently you choose between ty and basedpyright manually. It would be useful to detect the appropriate LSP server automatically based on project configuration or installed tools.
rass support: The rassumfrassum↗ project (an LSP multiplexer by Eglot’s author) could integrate with eglot-python-preset to run multiple servers like ty and Ruff simultaneously. rass might eventually handle autodetection itself, or it could be done on the elisp side. Either way, better integration with rass may be worth exploring.