diff --git a/AUTHORS.txt b/AUTHORS.txt index b86030e3..5171a933 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -63,6 +63,7 @@ Code Contributors - Leo Ryu (@Leo-Ryu) - Joseph Birkner (@josephbirkner) - Márcio Mazza (@marciomazza) +- Martin Vielsmaier (@moser) And a few more "anonymous" contributors. diff --git a/jedi/plugins/pytest.py b/jedi/plugins/pytest.py index 06adda44..acf6ad38 100644 --- a/jedi/plugins/pytest.py +++ b/jedi/plugins/pytest.py @@ -181,7 +181,13 @@ 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) - yield m.as_context() + conftest_module = m.as_context() + yield conftest_module + + plugins_list = m.tree_node.get_used_names().get("pytest_plugins") + if plugins_list: + name = conftest_module.create_name(plugins_list[0]) + yield from _load_pytest_plugins(module_context, name) except FileNotFoundError: pass folder = folder.get_parent_folder() @@ -196,6 +202,19 @@ def _iter_pytest_modules(module_context, skip_own_module=False): yield module_value.as_context() +def _load_pytest_plugins(module_context, name): + from jedi.inference.helpers import get_str_or_none + + for inferred in name.infer(): + for seq_value in inferred.py__iter__(): + for value in seq_value.infer(): + fq_name = get_str_or_none(value) + if fq_name: + names = fq_name.split(".") + for module_value in module_context.inference_state.import_module(names): + 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