Mach: introduce Pyrefly for Python type checking, starting with the wpt folder (#37953)

This is the first stage of adopting Pyrefly. It introduces the Python
folder and focuses on fixing issues around it.

Testing: *Describe how this pull request is tested or why it doesn't
require tests*
Fixes: *Link to an issue this pull requests fixes or remove this line if
there is no issue*

---------

Signed-off-by: Jerens Lensun <jerensslensun@gmail.com>
This commit is contained in:
Jerens Lensun 2025-07-11 21:07:36 +08:00 committed by GitHub
parent 2366a8bf9e
commit 55fd7b862f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 303 additions and 154 deletions

View file

@ -17,7 +17,8 @@ import os
import re
import subprocess
import sys
from typing import Any, Dict, List
from dataclasses import dataclass
from typing import Any, Dict, Iterator, List, Tuple
import colorama
import toml
@ -128,6 +129,10 @@ def is_iter_empty(iterator):
return False, iterator
def normalize_path(path: str) -> str:
return os.path.relpath(os.path.abspath(path), TOPDIR)
def normilize_paths(paths):
if isinstance(paths, str):
return os.path.join(*paths.split("/"))
@ -376,6 +381,38 @@ def check_ruff_lints():
)
@dataclass
class PyreflyDiagnostic:
"""
Represents a single diagnostic error reported by Pyrefly.
"""
line: int
column: int
stop_line: int
stop_column: int
path: str
code: int
name: str
description: str
concise_description: str
def run_python_type_checker() -> Iterator[Tuple[str, int, str]]:
print("\r ➤ Checking type annotations in python files ...")
try:
result = subprocess.run(["pyrefly", "check", "--output-format", "json"], capture_output=True)
parsed_json = json.loads(result.stdout)
errors = parsed_json.get("errors", [])
except subprocess.CalledProcessError as error:
print(f"{colorama.Fore.YELLOW}{error}{colorama.Style.RESET_ALL}")
pass
else:
for error in errors:
diagnostic = PyreflyDiagnostic(**error)
yield normalize_path(diagnostic.path), diagnostic.line, diagnostic.concise_description
def run_cargo_deny_lints():
print("\r ➤ Running `cargo-deny` checks...")
result = subprocess.run(
@ -1003,11 +1040,14 @@ def scan(only_changed_files=False, progress=False, github_annotations=False):
file_errors = collect_errors_for_files(files_to_check, checking_functions, line_checking_functions)
python_errors = check_ruff_lints()
python_type_check = run_python_type_checker()
cargo_lock_errors = run_cargo_deny_lints()
wpt_errors = run_wpt_lints(only_changed_files)
# chain all the iterators
errors = itertools.chain(config_errors, directory_errors, file_errors, python_errors, wpt_errors, cargo_lock_errors)
errors = itertools.chain(
config_errors, directory_errors, file_errors, python_errors, python_type_check, wpt_errors, cargo_lock_errors
)
colorama.init()
error = None