From 7d77f61040587212d1d6855c98e01ad8c3cdf220 Mon Sep 17 00:00:00 2001 From: Martin Vielsmaier Date: Tue, 31 Jan 2023 21:41:39 +0100 Subject: [PATCH] Add support for pytest fixtures from local pytest plugins. --- jedi/plugins/pytest.py | 14 ++++++++++++++ test/completion/conftest.py | 6 ++++++ test/completion/fixture_module.py | 6 ++++++ test/completion/pytest.py | 3 +++ 4 files changed, 29 insertions(+) create mode 100644 test/completion/fixture_module.py diff --git a/jedi/plugins/pytest.py b/jedi/plugins/pytest.py index 06adda44..e2fc6198 100644 --- a/jedi/plugins/pytest.py +++ b/jedi/plugins/pytest.py @@ -181,6 +181,9 @@ def _iter_pytest_modules(module_context, skip_own_module=False): if Path(file_io.path) != module_context.py__file__(): try: m = load_module_from_path(module_context.inference_state, file_io) + pytest_plugins_pointer = m.goto("pytest_plugins") + if pytest_plugins_pointer: + yield from _load_pytest_plugins(module_context, pytest_plugins_pointer[0]) yield m.as_context() except FileNotFoundError: pass @@ -196,6 +199,17 @@ def _iter_pytest_modules(module_context, skip_own_module=False): yield module_value.as_context() +def _load_pytest_plugins(module_context, plugins_pointers): + from jedi.inference.value import iterable + from parso.python.tree import String + for inferred in plugins_pointers.infer(): + if isinstance(inferred, iterable.SequenceLiteralValue): + for value in inferred.get_tree_entries(): + if isinstance(value, String): + for module_value in module_context.inference_state.import_module(eval(value.value).split(".")): + yield module_value.as_context() + + class FixtureFilter(ParserTreeFilter): def _filter(self, names): for name in super()._filter(names): diff --git a/test/completion/conftest.py b/test/completion/conftest.py index 7957be9a..1548d844 100644 --- a/test/completion/conftest.py +++ b/test/completion/conftest.py @@ -27,3 +27,9 @@ def capsysbinary(capsysbinary): #? ['close'] capsysbinary.clos return capsysbinary + + +# used when fixtures are defined in multiple files +pytest_plugins = [ + "completion.fixture_module", +] diff --git a/test/completion/fixture_module.py b/test/completion/fixture_module.py new file mode 100644 index 00000000..343c9281 --- /dev/null +++ b/test/completion/fixture_module.py @@ -0,0 +1,6 @@ +# Exists only for completion/pytest.py +import pytest + +@pytest.fixture +def my_module_fixture(): + return 1.0 diff --git a/test/completion/pytest.py b/test/completion/pytest.py index 64971dec..1f52c4f2 100644 --- a/test/completion/pytest.py +++ b/test/completion/pytest.py @@ -96,6 +96,9 @@ def test_x(my_con #? 18 ['my_conftest_fixture'] def test_x(my_conftest_fixture): return +#? ['my_module_fixture'] +def test_x(my_modu + return #? [] def lala(my_con