diff --git a/Lib/test/test_tools/test_check_warnings.py b/Lib/test/test_tools/test_check_warnings.py new file mode 100644 index 00000000000000..ef5a9bc1f27dec --- /dev/null +++ b/Lib/test/test_tools/test_check_warnings.py @@ -0,0 +1,46 @@ +import importlib +import unittest +from pathlib import Path +from test.support import captured_stdout, os_helper + +from test.test_tools import imports_under_tool, skip_if_missing + + +skip_if_missing("build") +with imports_under_tool("build"): + check_warnings = importlib.import_module("check_warnings") + + +class CheckWarningsTests(unittest.TestCase): + def test_partial_improvement(self): + for expected, actual, ignore_all, status in ( + (2, 1, False, 1), (2, 0, False, 1), + (2, 2, False, 0), (2, 3, False, 0), + (0, 0, False, 0), (2, 1, True, 0), + ): + with self.subTest(expected=expected, actual=actual, + ignore_all=ignore_all): + rules = {check_warnings.IgnoreRule( + "source.c", expected, ignore_all)} + warnings = {"source.c": [{}] * actual} if actual else {} + with captured_stdout(): + result = check_warnings.get_unexpected_improvements( + rules, warnings) + self.assertEqual(result, status) + + def test_cli_partial_improvement(self): + with os_helper.temp_dir() as directory: + output = Path(directory, "compiler.txt") + output.write_text("source.c:1:2: warning: example [-Wunused]\n", + encoding="utf-8") + ignore = Path(directory, "ignore.txt") + ignore.write_text("source.c 2\n", encoding="utf-8") + args = ["-c", str(output), "-i", str(ignore), "-t", "gcc", "-p", ""] + with captured_stdout(): + self.assertEqual(check_warnings.main(args), 0) + self.assertEqual(check_warnings.main( + args + ["--fail-on-improvement"]), 1) + + +if __name__ == "__main__": + unittest.main() diff --git a/Misc/NEWS.d/next/Tools-Demos/2026-10-13-20-09-07.gh-issue-159340.wCntIm.rst b/Misc/NEWS.d/next/Tools-Demos/2026-10-13-20-09-07.gh-issue-159340.wCntIm.rst new file mode 100644 index 00000000000000..4f93f46bb7e279 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2026-10-13-20-09-07.gh-issue-159340.wCntIm.rst @@ -0,0 +1,3 @@ +Fix ``Tools/build/check_warnings.py`` to detect warning-count reductions +when some warnings remain, and to accept zero expected warnings when none +are present. diff --git a/Tools/build/check_warnings.py b/Tools/build/check_warnings.py index 44ccf9708ad72f..afee32f307ca3c 100644 --- a/Tools/build/check_warnings.py +++ b/Tools/build/check_warnings.py @@ -197,23 +197,19 @@ def get_unexpected_improvements( files_with_warnings: dict[str, list[CompileWarning]], ) -> int: """ - Returns failure status if the number of warnings for a file is greater + Returns failure status if the number of warnings for a file is smaller than the expected number of warnings for that file based on the ignore rules """ unexpected_improvements = [] for rule in ignore_rules: - if ( - not rule.ignore_all - and rule.file_path not in files_with_warnings.keys() - ): - if rule.file_path not in files_with_warnings.keys(): - unexpected_improvements.append((rule.file_path, rule.count, 0)) - elif len(files_with_warnings[rule.file_path]) < rule.count: + if not rule.ignore_all: + count = len(files_with_warnings.get(rule.file_path, ())) + if count < rule.count: unexpected_improvements.append(( rule.file_path, rule.count, - len(files_with_warnings[rule.file_path]), + count, )) if unexpected_improvements: