pytest-language-server 🔥
A blazingly fast Language Server Protocol (LSP) implementation for pytest, built with Rust.
Demo

Showcasing go-to-definition, code completion, hover documentation, and code actions. Demo also vibed into existence. ✨
Shamelessly vibed into existence 🤖✨
This entire LSP implementation was built from scratch in a single AI-assisted coding session. No template. No boilerplate. Just pure vibes and Rust. That's right - a complete, working Language Server Protocol implementation for pytest, vibed into reality through the power of modern AI tooling. Even this message about vibing was vibed into existence.
Features
🎯 Go to Definition
Jump directly to fixture definitions from anywhere they're used:
- Local fixtures in the same file
- Fixtures in
conftest.pyfiles - Third-party fixtures from pytest plugins (pytest-mock, pytest-asyncio, etc.)
- Respects pytest's fixture shadowing/priority rules
✨ Code Completion
Smart auto-completion for pytest fixtures:
- Context-aware: Only triggers inside test functions and fixture functions
- Hierarchy-respecting: Suggests fixtures based on pytest's priority rules (same file > conftest.py > third-party)
- Rich information: Shows fixture source file and docstring
- No duplicates: Automatically filters out shadowed fixtures
- Works everywhere: Completions available in both function parameters and function bodies
- Supports both sync and async functions
🔍 Find References
Find all usages of a fixture across your entire test suite:
- Works from fixture definitions or usage sites
- Character-position aware (distinguishes between fixture name and parameters)
- Shows references in all test files
- Correctly handles fixture overriding and hierarchies
- LSP spec compliant: Always includes the current position in results
📚 Hover Documentation
View fixture information on hover:
- Fixture signature
- Source file location
- Docstring (with proper formatting and dedenting)
- Markdown support in docstrings
💡 Code Actions (Quick Fixes)
One-click fixes for common pytest issues:
- Add missing fixture parameters: Automatically add undeclared fixtures to function signatures
- Smart insertion: Handles both empty and existing parameter lists
- Editor integration: Works with any LSP-compatible editor's quick fix menu
- LSP compliant: Full support for
CodeActionKind::QUICKFIX
⚠️ Diagnostics & Quick Fixes
Detect and fix common pytest fixture issues with intelligent code actions:
Undeclared Fixture Detection:
- Detects when fixtures are used in function bodies but not declared as parameters
- Line-aware scoping: Correctly handles local variables assigned later in the function
- Hierarchy-aware: Only reports fixtures that are actually available in the current file's scope
- Works in tests and fixtures: Detects undeclared usage in both test functions and fixture functions
- Excludes built-in names (
self,request) and actual local variables
One-Click Quick Fixes:
- Code actions to automatically add missing fixture parameters
- Intelligent parameter insertion (handles both empty and existing parameter lists)
- Works with both single-line and multi-line function signatures
- Triggered directly from diagnostic warnings
Example:
return
# ✅ user_db properly declared
=
assert ==
# ⚠️ Warning: 'user_db' used but not declared
= # 💡 Quick fix: Add 'user_db' fixture parameter
assert ==
How to use quick fixes:
- Place cursor on the warning squiggle
- Trigger code actions menu (usually Cmd+. or Ctrl+. in most editors)
- Select "Add 'fixture_name' fixture parameter"
- The parameter is automatically added to your function signature
⚡️ Performance
Built with Rust for maximum performance:
- Fast workspace scanning with concurrent file processing
- Efficient AST parsing using rustpython-parser
- Lock-free data structures with DashMap
- Minimal memory footprint
Installation
Choose your preferred installation method:
📦 PyPI (Recommended)
The easiest way to install for Python projects:
# Using uv (recommended)
# Or with pip
# Or with pipx (isolated environment)
🍺 Homebrew (macOS/Linux)
Install via Homebrew for system-wide availability:
To add the tap first:
🦀 Cargo (Rust)
Install from crates.io if you have Rust installed:
📥 Pre-built Binaries
Download pre-built binaries from the GitHub Releases page.
Available for:
- Linux: x86_64, aarch64, armv7 (glibc and musl)
- macOS: Intel and Apple Silicon
- Windows: x64 and x86
🔨 From Source
Build from source for development or customization:
The binary will be at target/release/pytest-language-server.
Setup
Neovim (with nvim-lspconfig)
require..
Zed
Install from the extensions marketplace:
- Open Zed
- Open the command palette (Cmd+Shift+P / Ctrl+Shift+P)
- Search for "zed: extensions"
- Search for "pytest Language Server"
- Click "Install"
The extension downloads platform-specific binaries from GitHub Releases. If you prefer to use your own installation (via pip, cargo, or brew), place pytest-language-server in your PATH.
VS Code
The extension includes pre-built binaries - no separate installation required!
Install from the Visual Studio Marketplace:
- Open VS Code
- Go to Extensions (Cmd+Shift+X / Ctrl+Shift+X)
- Search for "pytest Language Server"
- Click "Install"
Works out of the box with zero configuration!
IntelliJ IDEA / PyCharm
The plugin includes pre-built binaries - no separate installation required!
Install from the JetBrains Marketplace:
- Open PyCharm or IntelliJ IDEA
- Go to Settings/Preferences → Plugins
- Search for "pytest Language Server"
- Click "Install"
Requires PyCharm 2024.2+ or IntelliJ IDEA 2024.2+ with Python plugin.
Other Editors
Any editor with LSP support can use pytest-language-server. Configure it to run the pytest-language-server command.
Configuration
Logging
Control log verbosity with the RUST_LOG environment variable:
# Minimal logging (default)
RUST_LOG=warn
# Info level
RUST_LOG=info
# Debug level (verbose)
RUST_LOG=debug
# Trace level (very verbose)
RUST_LOG=trace
Logs are written to stderr, so they won't interfere with LSP communication.
Virtual Environment Detection
The server automatically detects your Python virtual environment:
- Checks for
.venv/,venv/, orenv/in your project root - Falls back to
$VIRTUAL_ENVenvironment variable - Scans third-party pytest plugins for fixtures
Code Actions / Quick Fixes
Code actions are automatically available on diagnostic warnings. If code actions don't appear in your editor:
- Check LSP capabilities: Ensure your editor supports code actions (most modern editors do)
- Enable debug logging: Use
RUST_LOG=infoto see if actions are being created - Verify diagnostics: Code actions only appear where there are warnings
- Trigger manually: Use your editor's code action keybinding (Cmd+. / Ctrl+.)
For detailed troubleshooting, see CODE_ACTION_TESTING.md.
CLI Commands
In addition to the LSP server mode, pytest-language-server provides useful command-line tools:
Fixtures List
View all fixtures in your test suite with a hierarchical tree view:
# List all fixtures
# Skip unused fixtures
# Show only unused fixtures
The output includes:
- Color-coded display: Files in cyan, directories in blue, used fixtures in green, unused in gray
- Usage statistics: Shows how many times each fixture is used
- Smart filtering: Hides files and directories with no matching fixtures
- Hierarchical structure: Visualizes fixture organization across conftest.py files
Example output:
Fixtures tree for: /path/to/tests
conftest.py (7 fixtures)
├── another_fixture (used 2 times)
├── cli_runner (used 7 times)
├── database (used 6 times)
├── generator_fixture (used 1 time)
├── iterator_fixture (unused)
├── sample_fixture (used 7 times)
└── shared_resource (used 5 times)
subdir/
└── conftest.py (4 fixtures)
├── cli_runner (used 7 times)
├── database (used 6 times)
├── local_fixture (used 4 times)
└── sample_fixture (used 7 times)
This command is useful for:
- Auditing fixture usage across your test suite
- Finding unused fixtures that can be removed
- Understanding fixture organization and hierarchy
- Documentation - visualizing available fixtures for developers
Supported Fixture Patterns
Decorator Style
"""Fixture docstring."""
return 42
Assignment Style (pytest-mock)
=
Async Fixtures
return await
Fixture Dependencies
return
# Go to definition works on fixture_a
return +
Fixture Priority Rules
pytest-language-server correctly implements pytest's fixture shadowing rules:
- Same file: Fixtures defined in the same file have highest priority
- Closest conftest.py: Searches parent directories for conftest.py files
- Virtual environment: Third-party plugin fixtures
Fixture Overriding
The LSP correctly handles complex fixture overriding scenarios:
# conftest.py (parent)
return
# tests/conftest.py (child)
# Overrides parent
return # Uses parent
# tests/test_example.py
# Uses child
pass
When using find-references:
- Clicking on the function name
def cli_runner(...)shows references to the child fixture - Clicking on the parameter
cli_runner(cli_runner)shows references to the parent fixture - Character-position aware to distinguish between the two
Supported Third-Party Fixtures
Automatically discovers fixtures from popular pytest plugins:
- pytest-mock:
mocker,class_mocker - pytest-asyncio:
event_loop - pytest-django: Database fixtures
- pytest-cov: Coverage fixtures
- And any other pytest plugin in your environment
Architecture
- Language: Rust 🦀
- LSP Framework: tower-lsp
- Parser: rustpython-parser
- Concurrency: tokio async runtime
- Data Structures: DashMap for lock-free concurrent access
Development
Prerequisites
- Rust 1.83+ (2021 edition)
- Python 3.10+ (for testing)
Building
Running Tests
Logging During Development
RUST_LOG=debug
Security
Security is a priority. This project includes:
- Automated dependency vulnerability scanning (cargo-audit)
- License compliance checking (cargo-deny)
- Daily security audits in CI/CD
- Dependency review on pull requests
- Pre-commit security hooks
See SECURITY.md for our security policy and how to report vulnerabilities.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Setup
-
Install pre-commit hooks:
-
Run security checks locally:
License
MIT License - see LICENSE file for details.
Acknowledgments
Built with:
- tower-lsp - LSP framework
- rustpython-parser - Python AST parsing
- tokio - Async runtime
Special thanks to the pytest team for creating such an amazing testing framework.
Made with ❤️ and Rust. Shamelessly vibed into existence. Blazingly fast. 🔥
When you need a pytest LSP and the vibes are just right. ✨