Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

#2 suppressing FP when importing fixtures into conftest #9

Merged
merged 1 commit into from
Mar 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## [Unreleased]

### Added
- Suppressing FP `unused-import` when fixtures defined elsewhere are imported into `conftest.py` but not directly used (#2)

## [1.0.0] - 2021-03-02
### Added
- Python 3.9 support
Expand Down
11 changes: 11 additions & 0 deletions pylint_pytest/checkers/fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,14 @@ def visit_module(self, node):

# run pytest session with customized plugin to collect fixtures
fixture_collector = FixtureCollector()

# save and restore sys.path to prevent pytest.main from altering it
sys_path = sys.path.copy()
pytest.main(
[node.file, '--fixtures', '--collect-only'],
plugins=[fixture_collector],
)
sys.path = sys_path
FixtureChecker._pytest_fixtures = fixture_collector.fixtures
finally:
# restore output devices
Expand Down Expand Up @@ -118,6 +122,13 @@ def patch_add_message(self, msgid, line=None, node=None, args=None,
if message_tokens[0] == 'import' and len(message_tokens) == 2:
pass

# fixture is defined in other modules and being imported to
# conftest for pytest magic
elif isinstance(node.parent, astroid.Module) \
and node.parent.name.split('.')[-1] == 'conftest' \
and fixture_name in FixtureChecker._pytest_fixtures:
return

# imported fixture is referenced in test/fixture func
elif fixture_name in FixtureChecker._invoked_with_func_args \
and fixture_name in FixtureChecker._pytest_fixtures:
Expand Down
7 changes: 3 additions & 4 deletions tests/base_tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,22 @@ def run_linter(self, enable_plugin, file_path=None):

with open(file_path) as fin:
content = fin.read()
module = astroid.parse(content)
module = astroid.parse(content, module_name=module)
module.file = fin.name

self.walk(module) # run all checkers
BasePytestTester.MESSAGES = self.linter.release_messages()
self.MESSAGES = self.linter.release_messages()

def verify_messages(self, msg_count, msg_id=None):
msg_id = msg_id or self.MSG_ID

matched_count = 0
for message in self.MESSAGES:
print(message)
# only care about ID and count, not the content
if message.msg_id == msg_id:
matched_count += 1

assert matched_count == msg_count
assert matched_count == msg_count, f'expecting {msg_count}, actual {matched_count}'

def setup_method(self):
self.linter = UnittestLinter()
Expand Down
6 changes: 6 additions & 0 deletions tests/input/unused-import/_fixture_for_conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import pytest


@pytest.fixture
def conftest_fixture_attr():
return True
1 change: 1 addition & 0 deletions tests/input/unused-import/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from _fixture_for_conftest import conftest_fixture_attr
7 changes: 7 additions & 0 deletions tests/test_unused_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,10 @@ def test_same_name_decorator(self, enable_plugin):
name as fixture - should still raise unused-import warning'''
self.run_linter(enable_plugin)
self.verify_messages(1)

@pytest.mark.parametrize('enable_plugin', [True, False])
def test_conftest(self, enable_plugin):
'''fixtures are defined in different modules and imported to conftest
for pytest to do its magic'''
self.run_linter(enable_plugin)
self.verify_messages(0 if enable_plugin else 1)