Files
RustPython/scripts/check_redundant_patches.py
T
Shahar Naveh b1eda639f0 Unify lint CI job (#7505)
* use `prek` for unified linting

* Fix actionlint error

* Generate metadata when specific files change

* `check_redundant_patches.py` to accept glob path

* Test

* revert defective changes

* use `rustfmt` over `cargo fmt` for individual files

* debug reviewdog

* rustfmt

* Move comment to correct location

* defevtive fmt test

* Fail with reviewdog

* fix reviewdog perms

* Try to use present token

* without checks oerms

* put normal perms

* fmt
2026-03-26 21:43:34 +09:00

93 lines
2.4 KiB
Python

#!/usr/bin/env python
import argparse
import ast
import glob
import os
import pathlib
import sys
ROOT = pathlib.Path(__file__).parents[1]
TEST_DIR = ROOT / "Lib" / "test"
IS_GH_CI = "GITHUB_ACTIONS" in os.environ
def build_argparser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(prog="check_redundant_patches")
parser.add_argument(
"patterns",
nargs="*",
default=[f"{TEST_DIR}/**/*.py"],
help="Glob patterns (e.g. foo/bar/**.py a/b/file.py)",
)
return parser
def iter_files(patterns: list[str]):
seen = set()
for pattern in set(patterns):
matches = glob.glob(pattern, recursive=True)
for path in matches:
if path in seen:
continue
seen.add(path)
yield path
def main(patterns: list[str]):
exit_status = 0
for file in map(pathlib.Path, iter_files(patterns)):
if file.is_dir():
continue
try:
contents = file.read_text(encoding="utf-8")
except UnicodeDecodeError:
continue
try:
tree = ast.parse(contents)
except SyntaxError:
continue
cls_name = None
for node in ast.walk(tree):
if isinstance(node, ast.ClassDef):
cls_name = node.name
if not isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
continue
name = node.name
if not name.startswith("test"):
continue
if node.decorator_list:
continue
func_code = ast.unparse(node.body)
if func_code in (
f"await super().{name}()",
f"return await super().{name}()",
f"return super().{name}()",
f"super().{name}()",
):
exit_status += 1
lineno = node.lineno
msg = f"{file}:{lineno}:{cls_name}.{name} is a test patch that can be safely removed"
if IS_GH_CI:
end_lineno = node.end_lineno
msg = f"::error file={file},line={lineno},endLine={end_lineno},title=Redundant Test Patch::{msg}"
print(msg, file=sys.stderr)
return exit_status
if __name__ == "__main__":
parser = build_argparser()
args = parser.parse_args()
exit(main(args.patterns))