Add assertDoesNotAddMessages to CheckerTestCase#10930
Add assertDoesNotAddMessages to CheckerTestCase#10930ShehabSherif0 wants to merge 11 commits intopylint-dev:mainfrom
assertDoesNotAddMessages to CheckerTestCase#10930Conversation
Add a new context manager method to CheckerTestCase that asserts specific messages are NOT emitted, while allowing other messages to be present. This complements assertNoMessages which asserts that no messages at all are emitted. Also adds a _messages_match static helper for comparing two MessageTest instances field-by-field. Includes tests covering all six scenarios outlined in the issue plus additional edge cases for ignore_position and multiple unwanted messages. Closes pylint-dev#9598
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Pull request overview
Adds a new negative-assertion helper to Pylint’s checker unit-test infrastructure, enabling tests to assert that specific messages are not emitted while still allowing other messages.
Changes:
- Added
CheckerTestCase.assertDoesNotAddMessages(*messages, ignore_position=False)plus a helper forMessageTestcomparisons. - Added unit tests covering the expected pass/fail scenarios and
ignore_positionbehavior. - Added a towncrier news fragment documenting the feature.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
pylint/testutils/checker_test_case.py |
Introduces assertDoesNotAddMessages and message-matching helper used by test cases. |
tests/testutils/test_checker_test_case.py |
Adds tests validating the new assertion’s behavior across multiple scenarios. |
doc/whatsnew/fragments/9598.feature |
Documents the new test utility in the changelog fragments. |
- Use try/except/else instead of bare yield so messages are always drained and never leak into subsequent tests when the with-block raises an exception - Raise TypeError when called with no arguments (vacuous call) - Fix double space in docstring - Reformat news fragment: wrap long line, use Refs instead of Closes
for more information, see https://pre-commit.ci
This comment has been minimized.
This comment has been minimized.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10930 +/- ##
=======================================
Coverage 96.16% 96.17%
=======================================
Files 178 178
Lines 19627 19649 +22
=======================================
+ Hits 18875 18898 +23
+ Misses 752 751 -1
🚀 New features to boost your workflow:
|
…rage Add targeted unit tests for each early-return False branch in _messages_match: node, args, confidence, col_offset, end_line, and end_col_offset mismatches. This brings patch coverage from 83.33% to 100%.
for more information, see https://pre-commit.ci
This comment has been minimized.
This comment has been minimized.
Pierre-Sassoulas
left a comment
There was a problem hiding this comment.
Thank you for contributing to pylint. Sorry fr the delay I didn't send the review I thought I sent.
| if expected.node != actual.node: | ||
| return False | ||
| if expected.args != actual.args: | ||
| return False | ||
| if expected.confidence != actual.confidence: | ||
| return False | ||
| if not ignore_position: | ||
| if expected.line != actual.line: | ||
| return False | ||
| if expected.col_offset != actual.col_offset: | ||
| return False | ||
| if expected.end_line != actual.end_line: | ||
| return False | ||
| if expected.end_col_offset != actual.end_col_offset: | ||
| return False | ||
| return True |
There was a problem hiding this comment.
Don't we only care about the msgid ?
There was a problem hiding this comment.
You are right. The method now accepts plain message ID strings instead of full MessageTest objects, matching the intended use pattern from the issue. The check is just: if that message ID appears anywhere in the emitted messages, fail. Position, args, node and confidence are all irrelevant to the "did this message fire at all" question. The _messages_match helper and ignore_position parameter have been removed.
- assertDoesNotAddMessages now accepts message ID strings instead of full MessageTest objects, matching the intended use case described in the issue: checking that a specific message was never triggered regardless of position, args, or node - Remove _messages_match helper and ignore_position parameter as they are no longer needed with the simpler msg_id-only matching - Rename news fragment from 9598.feature to 9598.internal since this change touches the plugin developer API, not an end-user feature - Simplify tests to use plain string IDs
for more information, see https://pre-commit.ci
Replace try/except/else with try/except/finally to avoid R1720. The exception_raised flag tracks whether the with-block raised, so the finally block skips message checks when propagating an exception from the test body.
Pierre-Sassoulas
left a comment
There was a problem hiding this comment.
Thank you, let's add some assertion about the message raised and let's merge.
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
for more information, see https://pre-commit.ci
|
🤖 According to the primer, this change has no effect on the checked open source code. 🤖🎉 This comment was generated for commit 9f088f4 |
Summary
Adds
assertDoesNotAddMessages(*message_ids: str)toCheckerTestCaseas a context manager that asserts specific message IDs are not emitted during a checker run, while allowing other messages to be present.This fills the gap between
assertNoMessages()(no messages at all) andassertAddsMessages()(exact set of messages). Now you can write tests like:Motivation
Closes #9598. When testing checkers, it is useful to verify a specific message is not raised for a given input without requiring that zero messages are raised. For example, confirming a checker no longer emits a false positive for a pattern, even if it still correctly emits other warnings.
Changes
pylint/testutils/checker_test_case.py: AddedassertDoesNotAddMessages(*message_ids: str)context manager.tests/testutils/test_checker_test_case.py: New test file covering all six scenarios from the issue plus edge cases.doc/whatsnew/fragments/9598.internal: Towncrier news fragment.Test Scenarios
Following the scenarios from @Pierre-Sassoulas in the issue:
assertAddsMessagesassertAddsMessagesassertAddsMessagesassertDoesNotAddMessagesassertDoesNotAddMessagesassertDoesNotAddMessagesPlus edge cases: no arguments raises
TypeError, multiple unwanted IDs fail if any match, and exceptions inside the body drain the message buffer cleanly.