-
-
Notifications
You must be signed in to change notification settings - Fork 508
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
Add support for pytest fixtures #791
Comments
would it be possible to implement this in the general case or would exceptions have to be made for pytest's case? nothing about python gives you the hint as to where the fixture is defined, it comes into play as pytest collects tests and finds the fixtures by name as they are defined in the given file, related contest.py, and project dependences that define their own pytest fixtures. does Jedi have a plugin system where that sort of stuff could be kept? i feel like this would have to be isolated from Jedi in general, as it seems like you'd have to pull quite a bit in scope to find the right fixture |
This would be awesome. I'm using Is there always a
I agree. However a plugin system would definitely be right for this. However I haven't really thought about this and it feels like alot of work. I just don't know really what good entry points would be for such a plugin. I guess I would be ok with supporting py.test for now (within Jedi) and eventually moving it to a separate module. At the same time I'm not even sure. I think it's OK to support certain core-python libraries (like pytest or django) within Jedi. It seems a bit awkward to need to install a lot of plugins (that might not be well maintained). |
There's some discussion about this in pytest-dev/pytest#5981, based on using type annotations. |
How could we handle plugin hooks (like
I could imagine that this works for mypy via a mypy plugin, but that's nothing Jedi uses currently, is it? Not that this is similar to fixtures in general, but there it would have to discover which fixture is actually used (based on nearest conftest etc - a helper from within pytest would be useful here I guess). |
What's your use case for this? I'm not sure where it would help. |
@davidhalter |
I just don't really understand where Jedi could help you (assuming it does magic :)). |
That I get completion for |
I just pushed support for pytest fixtures. It looks pretty nice. It should also work with jedi-vim. goto works, inferring works and completions as well. Are the |
@davidhalter import pytest
class Foo:
def bar():
pass
@pytest.fixture
def fix() -> Foo:
return Foo()
def test(fix, monkeypatch):
monkeypatch.
fix.
Not sure how Lines 8 to 13 in 3ec73f1
("_pytest", "pytester") probably (for testdir etc).
|
Looks like I understood test discovery wrong (I only searched for
Done. |
I decided not to pursue stuff like I generally use pytest a lot and I use those method very rarely, so I feel like apart from you @blueyed, and some pytest core devs nobody uses this stuff as intensely :). |
@davidhalter I've noticed that with the following it will go to the fixture itself (with "goto" on the "caplog" function argument), and not the "parent fixture": @pytest.fixture
def caplog(caplog):
yield caplog Completion however works when using I've noticed both issues with something along the following in a @pytest.fixture
def caplog(caplog):
# from loguru import logger
#
# handler = LoguruPropogateHandler()
# handler_id = logger.add(handler, format="{message}")
yield caplog
# logger.remove(handler_id) With that "goto" from a test goes there, but completion with (Feel free to create an issue from this comment - I wasn't sure about it myself.) |
I have to think if I support this case, but reopening for now so I don't forget it. How exactly does pytest do inheritance there? |
@davidhalter But it sill does not go to the original fixture from/via "goto" on the "testdir" arg with the following in a @pytest.fixture
def testdir(testdir):
return testdir When using it in a |
Thanks for bringing it up. I fixed it now. Forgot to test this. Let me know if you find further stuff. |
@davidhalter I've noticed that it does not work for The code around this is also how fixtures get filled in (your previous question), which cannot be answered in a simple way I fear (but the current method appears to work really good already in general). |
The first goto from a test jumps to the argument in the test function - I think it would be better if it would go to the fixture definition directly (but goto-assignment should go to the argument (which it does currently also)). |
At the moment this is entirely intentional. If we want to change that in the future, we can add maybe an additional param go BTW: There's also
I'm not against that per se, but it's not a priority at all for me. So I would consider merging it, but I won't do it. |
Thanks so much for adding this! Can I expect it to work with a language server that leverages jedi, e.g. https://github.com/pappasam/jedi-language-server or https://github.com/palantir/python-language-server? I've tried jumping to pytest fixtures from both of these (and jedi-vim actually) but nothing happened, and I wanted to check that goto fixture definitions is still an expected behaviour before digging deeper. |
I'm pretty sure this works quite well, since I use it very often. The palantir language server will probably not work, because it uses Jedi <0.18.0. The other language server should probably work. You should probably check that you have |
Pytest fixtures are decorated functions that can be dynamically requested in test functions, simply by using them as function arguments.
I could imagine Jedi supporting this:
In
test_fix
it could be known thatfix
is apytest.fixture
and then that information could be used for completion.What works currently with Jedi is using type annotations for this (
def test_fix(fix: Obj)
), but typically that involves importingObj
in / before your test function, sinceObj
gets imported typically only in the fixture function itself.Two things make this more difficult:
conftest
module (which is basically a local pytest plugin AFAIK). For this Jedi probably needs support from pytest to get those, based on the current file / location.pytest.fixture
has an optionalname
kwarg, which allows to use a different name, which adds an additional layer of redirection to this.I'd be happy to help out with this, of course - also with regard to adding/improving interfaces in pytest.
Related: #257
The text was updated successfully, but these errors were encountered: