Skip to content

Commit a5c6855

Browse files
authored
Merge pull request #2 from anis-campos/fix_is_pytest_fixture
See more details in #2
2 parents 0a47a49 + d5cd873 commit a5c6855

File tree

3 files changed

+60
-6
lines changed

3 files changed

+60
-6
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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from pytest import fixture
2+
3+
4+
@fixture
5+
def simple_decorator():
6+
"""the fixture using the decorator without executing it"""
7+
8+
9+
def test_simple_fixture(simple_decorator):
10+
assert True
11+
12+
13+
@fixture()
14+
def un_configured_decorated():
15+
"""the decorated is called without argument, like scope"""
16+
17+
18+
def test_un_configured_decorated(un_configured_decorated):
19+
assert True
20+
21+
22+
@fixture(scope="function")
23+
def configured_decorated():
24+
"""the decorated is called with argument, like scope"""
25+
26+
27+
def test_un_configured_decorated(configured_decorated):
28+
assert True

tests/test_redefined_outer_name.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,9 @@ def test_caller_not_a_test_func(self, enable_plugin):
2929
def test_args_and_kwargs(self, enable_plugin):
3030
self.run_linter(enable_plugin)
3131
self.verify_messages(2)
32+
33+
@pytest.mark.parametrize("enable_plugin", [True, False])
34+
def test_direct_import(self, enable_plugin):
35+
"""the fixture method is directly imported"""
36+
self.run_linter(enable_plugin)
37+
self.verify_messages(0 if enable_plugin else 3)

0 commit comments

Comments
 (0)