Skip to content
This repository has been archived by the owner on Apr 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #2 from anis-campos/fix_is_pytest_fixture
Browse files Browse the repository at this point in the history
See more details in pylint-dev#2
  • Loading branch information
stdedos committed Oct 23, 2023
2 parents 0a47a49 + d5cd873 commit a5c6855
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 6 deletions.
32 changes: 26 additions & 6 deletions pylint_pytest/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def _is_pytest_mark(decorator):


def _is_pytest_fixture(decorator, fixture=True, yield_fixture=True):
attr = None
to_check = set()

if fixture:
Expand All @@ -40,17 +39,38 @@ def _is_pytest_fixture(decorator, fixture=True, yield_fixture=True):
if yield_fixture:
to_check.add("yield_fixture")

def _check_attribute(attr):
"""
handle astroid.Attribute, i.e., when the fixture function is
used by importing the pytest module
"""
return attr.attrname in to_check and attr.expr.name == "pytest"

def _check_name(name_):
"""
handle astroid.Name, i.e., when the fixture function is
directly imported
"""
function_name = name_.name
module = decorator.root().globals.get(function_name, [None])[0]
module_name = module.modname if module else None
return function_name in to_check and module_name == "pytest"

try:
if isinstance(decorator, astroid.Name):
# expecting @fixture
return _check_name(decorator)
if isinstance(decorator, astroid.Attribute):
# expecting @pytest.fixture
attr = decorator

return _check_attribute(decorator)
if isinstance(decorator, astroid.Call):
func = decorator.func
if isinstance(func, astroid.Name):
# expecting @fixture(scope=...)
return _check_name(func)
# expecting @pytest.fixture(scope=...)
attr = decorator.func
return _check_attribute(func)

if attr and attr.attrname in to_check and attr.expr.name == "pytest":
return True
except AttributeError:
pass

Expand Down
28 changes: 28 additions & 0 deletions tests/input/redefined-outer-name/direct_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from pytest import fixture


@fixture
def simple_decorator():
"""the fixture using the decorator without executing it"""


def test_simple_fixture(simple_decorator):
assert True


@fixture()
def un_configured_decorated():
"""the decorated is called without argument, like scope"""


def test_un_configured_decorated(un_configured_decorated):
assert True


@fixture(scope="function")
def configured_decorated():
"""the decorated is called with argument, like scope"""


def test_un_configured_decorated(configured_decorated):
assert True
6 changes: 6 additions & 0 deletions tests/test_redefined_outer_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,9 @@ def test_caller_not_a_test_func(self, enable_plugin):
def test_args_and_kwargs(self, enable_plugin):
self.run_linter(enable_plugin)
self.verify_messages(2)

@pytest.mark.parametrize("enable_plugin", [True, False])
def test_direct_import(self, enable_plugin):
"""the fixture method is directly imported"""
self.run_linter(enable_plugin)
self.verify_messages(0 if enable_plugin else 3)

0 comments on commit a5c6855

Please sign in to comment.