| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | """
 | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  | Parses compiler output from Clang or GCC and checks that warnings | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | exist only in files that are expected to have warnings. | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											2024-08-06 12:26:37 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | import argparse | 
					
						
							| 
									
										
										
										
											2024-08-06 12:26:37 -05:00
										 |  |  | from collections import defaultdict | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | import re | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | from pathlib import Path | 
					
						
							| 
									
										
										
										
											2024-08-14 16:03:53 -05:00
										 |  |  | from typing import NamedTuple | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  | class IgnoreRule(NamedTuple): | 
					
						
							|  |  |  |     file_path: str | 
					
						
							| 
									
										
										
										
											2024-08-14 16:03:53 -05:00
										 |  |  |     count: int | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |     ignore_all: bool = False | 
					
						
							|  |  |  |     is_directory: bool = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def parse_warning_ignore_file(file_path: str) -> set[IgnoreRule]: | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Parses the warning ignore file and returns a set of IgnoreRules | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     files_with_expected_warnings = set() | 
					
						
							|  |  |  |     with Path(file_path).open(encoding="UTF-8") as ignore_rules_file: | 
					
						
							|  |  |  |         files_with_expected_warnings = set() | 
					
						
							|  |  |  |         for i, line in enumerate(ignore_rules_file): | 
					
						
							|  |  |  |             line = line.strip() | 
					
						
							|  |  |  |             if line and not line.startswith("#"): | 
					
						
							|  |  |  |                 line_parts = line.split() | 
					
						
							|  |  |  |                 if len(line_parts) >= 2: | 
					
						
							|  |  |  |                     file_name = line_parts[0] | 
					
						
							|  |  |  |                     count = line_parts[1] | 
					
						
							|  |  |  |                     ignore_all = count == "*" | 
					
						
							|  |  |  |                     is_directory = file_name.endswith("/") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     # Directories must have a wildcard count | 
					
						
							|  |  |  |                     if is_directory and count != "*": | 
					
						
							|  |  |  |                         print( | 
					
						
							|  |  |  |                             f"Error parsing ignore file: {file_path} at line: {i}" | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  |                         print( | 
					
						
							|  |  |  |                             f"Directory {file_name} must have count set to *" | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  |                         sys.exit(1) | 
					
						
							|  |  |  |                     if ignore_all: | 
					
						
							|  |  |  |                         count = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     files_with_expected_warnings.add( | 
					
						
							|  |  |  |                         IgnoreRule( | 
					
						
							|  |  |  |                             file_name, int(count), ignore_all, is_directory | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return files_with_expected_warnings | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  | def extract_warnings_from_compiler_output( | 
					
						
							| 
									
										
										
										
											2024-08-06 12:26:37 -05:00
										 |  |  |     compiler_output: str, | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |     compiler_output_type: str, | 
					
						
							|  |  |  |     path_prefix: str = "", | 
					
						
							| 
									
										
										
										
											2024-08-06 12:26:37 -05:00
										 |  |  | ) -> list[dict]: | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |     Extracts warnings from the compiler output based on compiler | 
					
						
							|  |  |  |     output type. Removes path prefix from file paths if provided. | 
					
						
							|  |  |  |     Compatible with GCC and Clang compiler output. | 
					
						
							| 
									
										
										
										
											2024-09-13 22:47:12 +03:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |     # Choose pattern and compile regex for particular compiler output | 
					
						
							|  |  |  |     if compiler_output_type == "gcc": | 
					
						
							|  |  |  |         regex_pattern = ( | 
					
						
							|  |  |  |             r"(?P<file>.*):(?P<line>\d+):(?P<column>\d+): warning: " | 
					
						
							|  |  |  |             r"(?P<message>.*?)(?: (?P<option>\[-[^\]]+\]))?$" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     elif compiler_output_type == "clang": | 
					
						
							|  |  |  |         regex_pattern = ( | 
					
						
							|  |  |  |             r"(?P<file>.*):(?P<line>\d+):(?P<column>\d+): warning: " | 
					
						
							|  |  |  |             r"(?P<message>.*) (?P<option>\[-[^\]]+\])$" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     compiled_regex = re.compile(regex_pattern) | 
					
						
							| 
									
										
										
										
											2024-09-13 22:47:12 +03:00
										 |  |  |     compiler_warnings = [] | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |     for i, line in enumerate(compiler_output.splitlines(), start=1): | 
					
						
							|  |  |  |         if match := compiled_regex.match(line): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 compiler_warnings.append( | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         "file": match.group("file").removeprefix(path_prefix), | 
					
						
							|  |  |  |                         "line": match.group("line"), | 
					
						
							|  |  |  |                         "column": match.group("column"), | 
					
						
							|  |  |  |                         "message": match.group("message"), | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |                         "option": match.group("option") | 
					
						
							|  |  |  |                         .lstrip("[") | 
					
						
							|  |  |  |                         .rstrip("]"), | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |             except: | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |                 print( | 
					
						
							|  |  |  |                     f"Error parsing compiler output. Unable to extract warning on line {i}:\n{line}" | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |                 sys.exit(1) | 
					
						
							| 
									
										
										
										
											2024-09-13 22:47:12 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return compiler_warnings | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | def get_warnings_by_file(warnings: list[dict]) -> dict[str, list[dict]]: | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |     Returns a dictionary where the key is the file and the data is the | 
					
						
							|  |  |  |     warnings in that file. Does not include duplicate warnings for a | 
					
						
							|  |  |  |     file from list of provided warnings. | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-08-06 12:26:37 -05:00
										 |  |  |     warnings_by_file = defaultdict(list) | 
					
						
							| 
									
										
										
										
											2024-08-14 16:03:53 -05:00
										 |  |  |     warnings_added = set() | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |     for warning in warnings: | 
					
						
							| 
									
										
										
										
											2024-08-14 16:03:53 -05:00
										 |  |  |         warning_key = ( | 
					
						
							|  |  |  |             f"{warning['file']}-{warning['line']}-" | 
					
						
							|  |  |  |             f"{warning['column']}-{warning['option']}" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         if warning_key not in warnings_added: | 
					
						
							|  |  |  |             warnings_added.add(warning_key) | 
					
						
							|  |  |  |             warnings_by_file[warning["file"]].append(warning) | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return warnings_by_file | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  | def is_file_ignored( | 
					
						
							|  |  |  |     file_path: str, ignore_rules: set[IgnoreRule] | 
					
						
							|  |  |  | ) -> IgnoreRule | None: | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Returns the IgnoreRule object for the file path if there is a related rule for it | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     for rule in ignore_rules: | 
					
						
							|  |  |  |         if rule.is_directory: | 
					
						
							|  |  |  |             if file_path.startswith(rule.file_path): | 
					
						
							|  |  |  |                 return rule | 
					
						
							|  |  |  |         elif file_path == rule.file_path: | 
					
						
							|  |  |  |             return rule | 
					
						
							|  |  |  |     return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | def get_unexpected_warnings( | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |     ignore_rules: set[IgnoreRule], | 
					
						
							|  |  |  |     files_with_warnings: set[IgnoreRule], | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | ) -> int: | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Returns failure status if warnings discovered in list of warnings | 
					
						
							|  |  |  |     are associated with a file that is not found in the list of files | 
					
						
							|  |  |  |     with expected warnings | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |     unexpected_warnings = {} | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |     for file in files_with_warnings.keys(): | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         rule = is_file_ignored(file, ignore_rules) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if rule: | 
					
						
							|  |  |  |             if rule.ignore_all: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if len(files_with_warnings[file]) > rule.count: | 
					
						
							|  |  |  |                 unexpected_warnings[file] = ( | 
					
						
							|  |  |  |                     files_with_warnings[file], | 
					
						
							|  |  |  |                     rule.count, | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         elif rule is None: | 
					
						
							|  |  |  |             # If the file is not in the ignore list, then it is unexpected | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |             unexpected_warnings[file] = (files_with_warnings[file], 0) | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if unexpected_warnings: | 
					
						
							|  |  |  |         print("Unexpected warnings:") | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |         for file in unexpected_warnings: | 
					
						
							|  |  |  |             print( | 
					
						
							|  |  |  |                 f"{file} expected {unexpected_warnings[file][1]} warnings," | 
					
						
							|  |  |  |                 f" found {len(unexpected_warnings[file][0])}" | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             for warning in unexpected_warnings[file][0]: | 
					
						
							|  |  |  |                 print(warning) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_unexpected_improvements( | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |     ignore_rules: set[IgnoreRule], | 
					
						
							|  |  |  |     files_with_warnings: set[IgnoreRule], | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | ) -> int: | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |     Returns failure status if the number of warnings for a file is greater | 
					
						
							|  |  |  |     than the expected number of warnings for that file based on the ignore | 
					
						
							|  |  |  |     rules | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     unexpected_improvements = [] | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |     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: | 
					
						
							|  |  |  |                 unexpected_improvements.append( | 
					
						
							|  |  |  |                     ( | 
					
						
							|  |  |  |                         rule.file_path, | 
					
						
							|  |  |  |                         rule.count, | 
					
						
							|  |  |  |                         len(files_with_warnings[rule.file_path]), | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if unexpected_improvements: | 
					
						
							|  |  |  |         print("Unexpected improvements:") | 
					
						
							|  |  |  |         for file in unexpected_improvements: | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |             print(f"{file[0]} expected {file[1]} warnings, found {file[2]}") | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def main(argv: list[str] | None = None) -> int: | 
					
						
							|  |  |  |     parser = argparse.ArgumentParser() | 
					
						
							|  |  |  |     parser.add_argument( | 
					
						
							| 
									
										
										
										
											2024-07-30 14:49:15 -05:00
										 |  |  |         "-c", | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |         "--compiler-output-file-path", | 
					
						
							|  |  |  |         type=str, | 
					
						
							|  |  |  |         required=True, | 
					
						
							|  |  |  |         help="Path to the compiler output file", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     parser.add_argument( | 
					
						
							| 
									
										
										
										
											2024-07-30 14:49:15 -05:00
										 |  |  |         "-i", | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |         "--warning-ignore-file-path", | 
					
						
							|  |  |  |         type=str, | 
					
						
							|  |  |  |         help="Path to the warning ignore file", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     parser.add_argument( | 
					
						
							| 
									
										
										
										
											2024-07-30 14:49:15 -05:00
										 |  |  |         "-x", | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |         "--fail-on-regression", | 
					
						
							|  |  |  |         action="store_true", | 
					
						
							|  |  |  |         default=False, | 
					
						
							|  |  |  |         help="Flag to fail if new warnings are found", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     parser.add_argument( | 
					
						
							| 
									
										
										
										
											2024-07-30 14:49:15 -05:00
										 |  |  |         "-X", | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |         "--fail-on-improvement", | 
					
						
							|  |  |  |         action="store_true", | 
					
						
							|  |  |  |         default=False, | 
					
						
							|  |  |  |         help="Flag to fail if files that were expected " | 
					
						
							|  |  |  |         "to have warnings have no warnings", | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-06 12:26:37 -05:00
										 |  |  |     parser.add_argument( | 
					
						
							|  |  |  |         "-t", | 
					
						
							|  |  |  |         "--compiler-output-type", | 
					
						
							|  |  |  |         type=str, | 
					
						
							|  |  |  |         required=True, | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |         choices=["gcc", "clang"], | 
					
						
							|  |  |  |         help="Type of compiler output file (GCC or Clang)", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     parser.add_argument( | 
					
						
							|  |  |  |         "-p", | 
					
						
							|  |  |  |         "--path-prefix", | 
					
						
							|  |  |  |         type=str, | 
					
						
							|  |  |  |         help="Path prefix to remove from the start of file paths" | 
					
						
							|  |  |  |         " in compiler output", | 
					
						
							| 
									
										
										
										
											2024-08-06 12:26:37 -05:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     args = parser.parse_args(argv) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     exit_code = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Check that the compiler output file is a valid path | 
					
						
							|  |  |  |     if not Path(args.compiler_output_file_path).is_file(): | 
					
						
							|  |  |  |         print( | 
					
						
							| 
									
										
										
										
											2024-08-06 12:26:37 -05:00
										 |  |  |             f"Compiler output file does not exist:" | 
					
						
							|  |  |  |             f" {args.compiler_output_file_path}" | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |         ) | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-06 12:26:37 -05:00
										 |  |  |     # Check that a warning ignore file was specified and if so is a valid path | 
					
						
							|  |  |  |     if not args.warning_ignore_file_path: | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |         print( | 
					
						
							| 
									
										
										
										
											2024-08-06 12:26:37 -05:00
										 |  |  |             "Warning ignore file not specified." | 
					
						
							|  |  |  |             " Continuing without it (no warnings ignored)." | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |         ignore_rules = set() | 
					
						
							| 
									
										
										
										
											2024-08-06 12:26:37 -05:00
										 |  |  |     else: | 
					
						
							|  |  |  |         if not Path(args.warning_ignore_file_path).is_file(): | 
					
						
							|  |  |  |             print( | 
					
						
							|  |  |  |                 f"Warning ignore file does not exist:" | 
					
						
							|  |  |  |                 f" {args.warning_ignore_file_path}" | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             return 1 | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |         ignore_rules = parse_warning_ignore_file(args.warning_ignore_file_path) | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     with Path(args.compiler_output_file_path).open(encoding="UTF-8") as f: | 
					
						
							|  |  |  |         compiler_output_file_contents = f.read() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |     warnings = extract_warnings_from_compiler_output( | 
					
						
							|  |  |  |         compiler_output_file_contents, | 
					
						
							|  |  |  |         args.compiler_output_type, | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |         args.path_prefix, | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-06 12:26:37 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |     files_with_warnings = get_warnings_by_file(warnings) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |     status = get_unexpected_warnings(ignore_rules, files_with_warnings) | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |     if args.fail_on_regression: | 
					
						
							|  |  |  |         exit_code |= status | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |     status = get_unexpected_improvements(ignore_rules, files_with_warnings) | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |     if args.fail_on_improvement: | 
					
						
							|  |  |  |         exit_code |= status | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  |     print( | 
					
						
							|  |  |  |         "For information about this tool and its configuration" | 
					
						
							|  |  |  |         " visit https://devguide.python.org/development-tools/warnings/" | 
					
						
							| 
									
										
										
										
											2024-09-18 02:49:43 -05:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-09-16 12:22:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-27 04:57:44 -05:00
										 |  |  |     return exit_code | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |     sys.exit(main()) |