Announcing eglot-python-preset

Published:
Keywords: emacs

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:

  1. It detects the script metadata automatically
  2. It locates the cached uv environment for that script (or prompts you to create one)
  3. 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 using uv 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 using uv run in 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.