-
Notifications
You must be signed in to change notification settings - Fork 259
impl LSP: Navigation support for pytest fixtures #1901 #2075
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements LSP navigation support for pytest fixtures, enabling go-to-definition and find-references functionality for fixture parameters in test functions. When a developer invokes go-to-definition on a fixture parameter (e.g., my_fixture in def test_thing(my_fixture):), the LSP will navigate to the fixture definition. Similarly, finding references on a fixture definition will include all test/fixture functions that use it as a parameter.
Changes:
- Added pytest import and fixture detection logic to identify pytest modules and fixture decorators
- Implemented fixture discovery and parameter scanning to collect fixture definitions and their usage in test functions
- Integrated pytest fixture resolution into LSP go-to-definition and find-references operations
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| pyrefly/lib/state/lsp.rs | Core implementation: added PytestAliases tracking, fixture detection functions, and integrated pytest-aware parameter resolution into LSP operations |
| pyrefly/lib/test/lsp/definition.rs | Added test verifying go-to-definition navigation from fixture parameters to fixture definitions |
| pyrefly/lib/test/lsp/local_find_refs.rs | Added test verifying find-references includes injected fixture parameters in test functions |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This comment has been minimized.
This comment has been minimized.
for sure. maybe a pyrefly/lib/third_party or something similar? |
This comment has been minimized.
This comment has been minimized.
| report.trim(), | ||
| ); | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A more high level comment/question is, do we want to add type support? or is this exclusively an IDE feature? For example, it would be great if the following worked:
from typing import reveal_type
import pytest
@pytest.fixture
def my_fixture() -> int:
return 42
def test_foo(my_fixture):
reveal_type(my_fixture) # int
That would require extending the binding layer.
Additionally, how would conftest.py fit into this support? Overall, I think there are some open questions when it comes to this feature.
On a different note, I would also say that attr support could be a nice problem to look at (if you are specifically interested in 3p support!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we want to add type support
#2201 I think it's here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking more like what we're doing for pydantic and django in the binding layer. Was curious why we didn't follow that direction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pytest fixtures here are only used to improve navigation (definition/refs) in the LSP, not typing.
The LSP path already has AST access and is allowed to do local scans. Avoiding extra binding state keeps the feature isolated
For now, it’s a tradeoff compared to adding new binding data structures and incremental update logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And add typing will be too big for a single pr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the improvements! the diff is looking much better. Let me discuss with the team those tradeoffs.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
pyrefly/lib/state/pytest.rs
Outdated
| identifier: &Identifier, | ||
| covering_nodes: &[AnyNodeRef], | ||
| ) -> Option<Vec<PytestFixtureDefinition>> { | ||
| let module_info = PytestModuleInfo::from_module(module)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my understanding is that this will be recomputed on every call? if so, I would love to learn more on why we are not taking a binding approach to store some of the information we need?
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
Summary
Fixes #1901
Implemented pytest import/alias detection plus fixture discovery and parameter scanning in pyrefly/lib/state/lsp.rs, and hooked it into go‑to‑definition and local references.
todo: should these pytest functions in their own mod?
Test Plan
cargo test pytest_fixture_parameter_goes_to_fixture_definition
cargo test pytest_fixture_references_include_injected_parameters