Skip to content

Commit d5cd873

Browse files
committed
Fixing _is_pytest_fixture
currently, both fixture in this example are flagged has not fixtures ```python from pytest import fixture @fixture def my_fixture(): pass @fixture(name="foo") def my_fixture_2(): pass ``` This is due to the different semantics in astroid when using `import pytest` or `from pytest import ...`
1 parent 630172b commit d5cd873

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

pylint_pytest/utils.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ def _is_pytest_mark(decorator):
3131

3232

3333
def _is_pytest_fixture(decorator, fixture=True, yield_fixture=True):
34-
attr = None
3534
to_check = set()
3635

3736
if fixture:
@@ -40,17 +39,38 @@ def _is_pytest_fixture(decorator, fixture=True, yield_fixture=True):
4039
if yield_fixture:
4140
to_check.add("yield_fixture")
4241

42+
def _check_attribute(attr):
43+
"""
44+
handle astroid.Attribute, i.e., when the fixture function is
45+
used by importing the pytest module
46+
"""
47+
return attr.attrname in to_check and attr.expr.name == "pytest"
48+
49+
def _check_name(name_):
50+
"""
51+
handle astroid.Name, i.e., when the fixture function is
52+
directly imported
53+
"""
54+
function_name = name_.name
55+
module = decorator.root().globals.get(function_name, [None])[0]
56+
module_name = module.modname if module else None
57+
return function_name in to_check and module_name == "pytest"
58+
4359
try:
60+
if isinstance(decorator, astroid.Name):
61+
# expecting @fixture
62+
return _check_name(decorator)
4463
if isinstance(decorator, astroid.Attribute):
4564
# expecting @pytest.fixture
46-
attr = decorator
47-
65+
return _check_attribute(decorator)
4866
if isinstance(decorator, astroid.Call):
67+
func = decorator.func
68+
if isinstance(func, astroid.Name):
69+
# expecting @fixture(scope=...)
70+
return _check_name(func)
4971
# expecting @pytest.fixture(scope=...)
50-
attr = decorator.func
72+
return _check_attribute(func)
5173

52-
if attr and attr.attrname in to_check and attr.expr.name == "pytest":
53-
return True
5474
except AttributeError:
5575
pass
5676

tests/test_redefined_outer_name.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ def test_args_and_kwargs(self, enable_plugin):
3030
self.run_linter(enable_plugin)
3131
self.verify_messages(2)
3232

33-
@pytest.mark.parametrize('enable_plugin', [True, False])
33+
@pytest.mark.parametrize("enable_plugin", [True, False])
3434
def test_direct_import(self, enable_plugin):
35-
"""the fixture method is directly imported """
35+
"""the fixture method is directly imported"""
3636
self.run_linter(enable_plugin)
3737
self.verify_messages(0 if enable_plugin else 3)

0 commit comments

Comments
 (0)