Skip to content

Commit

Permalink
Make sure inheritance works for fixtures, fixes #791
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhalter committed Jan 5, 2020
1 parent 5da9f9f commit 4243d01
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 11 deletions.
38 changes: 27 additions & 11 deletions jedi/plugins/pytest.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,17 @@ def get_returns(value):
return function_context.get_return_values()

def wrapper(param_name):
if _is_a_pytest_param(param_name):
is_pytest_param, param_name_is_function_name = \
_is_a_pytest_param_and_inherited(param_name)
if is_pytest_param:
module = param_name.get_root_context()
fixtures = _goto_pytest_fixture(module, param_name.string_name)
fixtures = _goto_pytest_fixture(
module,
param_name.string_name,
# This skips the current module, because we are basically
# inheriting a fixture from somewhere else.
skip_own_module=param_name_is_function_name,
)
if fixtures:
return ValueSet.from_sets(
get_returns(value)
Expand All @@ -56,8 +64,14 @@ def wrapper(param_name):

def goto_anonymous_param(func):
def wrapper(param_name):
if _is_a_pytest_param(param_name):
names = _goto_pytest_fixture(param_name.get_root_context(), param_name.string_name)
is_pytest_param, param_name_is_function_name = \
_is_a_pytest_param_and_inherited(param_name)
if is_pytest_param:
names = _goto_pytest_fixture(
param_name.get_root_context(),
param_name.string_name,
skip_own_module=param_name_is_function_name,
)
if names:
return names
return func(param_name)
Expand All @@ -77,14 +91,14 @@ def wrapper(context, func_name, decorator_nodes):
return wrapper


def _goto_pytest_fixture(module_context, name):
for module_context in _iter_pytest_modules(module_context):
def _goto_pytest_fixture(module_context, name, skip_own_module):
for module_context in _iter_pytest_modules(module_context, skip_own_module=skip_own_module):
names = FixtureFilter(module_context).get(name)
if names:
return names


def _is_a_pytest_param(param_name):
def _is_a_pytest_param_and_inherited(param_name):
"""
Pytest params are either in a `test_*` function or have a pytest fixture
with the decorator @pytest.fixture.
Expand All @@ -93,9 +107,10 @@ def _is_a_pytest_param(param_name):
"""
funcdef = search_ancestor(param_name.tree_name, 'funcdef')
if funcdef is None: # A lambda
return False
return False, False
decorators = funcdef.get_decorators()
return _is_pytest_func(funcdef.name.value, decorators)
return _is_pytest_func(funcdef.name.value, decorators), \
funcdef.name.value == param_name.string_name


def _is_pytest_func(func_name, decorator_nodes):
Expand All @@ -104,8 +119,9 @@ def _is_pytest_func(func_name, decorator_nodes):


@inference_state_method_cache()
def _iter_pytest_modules(module_context):
yield module_context
def _iter_pytest_modules(module_context, skip_own_module=False):
if not skip_own_module:
yield module_context

file_io = module_context.get_value().file_io
if file_io is not None:
Expand Down
5 changes: 5 additions & 0 deletions test/completion/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ def my_conftest_fixture(my_other_conftest_fixture):

def my_not_existing_fixture():
return 3 # Just a normal function


@pytest.fixture()
def inheritance_fixture():
return ''
30 changes: 30 additions & 0 deletions test/completion/pytest.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,33 @@ def test_p(capsysbin

#? ['tmpdir', 'tmpdir_factory']
def test_p(tmpdi


def close_parens():
pass
# -----------------
# inheritance
# -----------------

@fixture
#? 40 ['inheritance_fixture']
def inheritance_fixture(inheritance_fixture):
#? str()
inheritance_fixture
#? ['upper']
inheritance_fixture.upper
return 1


#! 48 ['def inheritance_fixture']
def test_inheritance_fixture(inheritance_fixture, caplog):
#? int()
inheritance_fixture

#? ['set_level']
caplog.set_le


@pytest.fixture
def caplog(caplog):
yield caplog

0 comments on commit 4243d01

Please sign in to comment.