use ruff rather than flake8 for python code linting (#37045)

The initially used config is compatible with flake8 rules, including all
pycodestyle (pep8) and pyflakes rules.

Testing: Broke some python files and used `mach test-tidy --all` to test
the linting.
Fixes: servo/servo#37041

Signed-off-by: zefr0x <zer0-x.7ty50@aleeas.com>
This commit is contained in:
zefr0x 2025-05-24 17:19:47 +03:00 committed by GitHub
parent 88fd2e43c8
commit 60eb7c923d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 46 additions and 40 deletions

18
.flake8
View file

@ -1,18 +0,0 @@
[flake8]
ignore =
# trailing whitespace; the standard tidy process will enforce no trailing whitespace
W291,
# linebreak before binary operator; replaced by W504 - linebreak after binary operator
W503,
# 80 character line length; the standard tidy process will enforce line length
E501
exclude =
# temporary local files
target
__pycache__
python/_venv*
# upstream
third_party
python/mach
components
tests

View file

@ -16,6 +16,8 @@
// IDL language support // IDL language support
"mythmon.idl", "mythmon.idl",
// TOML files // TOML files
"tamasfe.even-better-toml" "tamasfe.even-better-toml",
// Python files
"charliermarsh.ruff"
] ]
} }

View file

@ -79,7 +79,7 @@ for (name, raw_samples) in sorted(iter(thread_data.items()), key=lambda x: threa
for frame in sample[1]: for frame in sample[1]:
if not frame['name']: if not frame['name']:
continue continue
if not frame['name'] in frameMap: if frame['name'] not in frameMap:
frameMap[frame['name']] = len(frames) frameMap[frame['name']] = len(frames)
frame_index = string_table.get(frame['name']) frame_index = string_table.get(frame['name'])
frames.append([frame_index]) frames.append([frame_index])

View file

@ -8,7 +8,7 @@ is the canonical repository for this code.
# `tidy` # `tidy`
servo-tidy is used to check licenses, line lengths, whitespace, flake8 on servo-tidy is used to check licenses, line lengths, whitespace, ruff on
Python files, lock file versions, and more. Python files, lock file versions, and more.
# `wpt` # `wpt`

View file

@ -8,10 +8,8 @@ mozlog == 8.0.0
setuptools == 78.1.1 setuptools == 78.1.1
toml == 0.9.2 toml == 0.9.2
# For Python linting # For Python linting and formatting
flake8 == 7.0.0 ruff == 0.11.10
pep8 == 1.5.7
pyflakes == 3.2.0
# For test-webidl # For test-webidl
ply == 3.8 ply == 3.8

View file

@ -356,19 +356,18 @@ def check_by_line(file_name: str, lines: list[bytes]):
yield error yield error
def check_flake8(file_name, contents): def check_ruff_lints():
if not file_name.endswith(".py"):
return
output = ""
try: try:
args = ["flake8", file_name] args = ["ruff", "check", "--output-format", "json"]
subprocess.check_output(args, universal_newlines=True) subprocess.check_output(args, universal_newlines=True)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
output = e.output for error in json.loads(e.output):
for error in output.splitlines(): yield (
_, line_num, _, message = error.split(":", 3) os.path.join(".", os.path.relpath(error["filename"])),
yield line_num, message.strip() error["location"]["row"],
f"[{error['code']}] {error['message']} ({error['url']})",
)
def run_cargo_deny_lints(): def run_cargo_deny_lints():
@ -976,17 +975,18 @@ def scan(only_changed_files=False, progress=False):
directory_errors = check_directory_files(config['check_ext']) directory_errors = check_directory_files(config['check_ext'])
# standard checks # standard checks
files_to_check = filter_files('.', only_changed_files, progress) files_to_check = filter_files('.', only_changed_files, progress)
checking_functions = (check_flake8, check_webidl_spec) checking_functions = (check_webidl_spec,)
line_checking_functions = (check_license, check_by_line, check_toml, check_shell, line_checking_functions = (check_license, check_by_line, check_toml, check_shell,
check_rust, check_spec, check_modeline) check_rust, check_spec, check_modeline)
file_errors = collect_errors_for_files(files_to_check, checking_functions, line_checking_functions) file_errors = collect_errors_for_files(files_to_check, checking_functions, line_checking_functions)
python_errors = check_ruff_lints()
cargo_lock_errors = run_cargo_deny_lints() cargo_lock_errors = run_cargo_deny_lints()
wpt_errors = run_wpt_lints(only_changed_files) wpt_errors = run_wpt_lints(only_changed_files)
# chain all the iterators # chain all the iterators
errors = itertools.chain(config_errors, directory_errors, file_errors, errors = itertools.chain(config_errors, directory_errors, file_errors,
wpt_errors, cargo_lock_errors) python_errors, wpt_errors, cargo_lock_errors)
colorama.init() colorama.init()
error = None error = None

View file

@ -1,3 +0,0 @@
[flake8]
filename = *.py
max-line-length = 120

27
ruff.toml Normal file
View file

@ -0,0 +1,27 @@
line-length = 120
extend-exclude = [
# temporary local files
"target/**",
"__pycache__/**",
"python/_venv*/**",
# upstream
"third_party/**",
"python/mach/**",
"components/**",
"tests/**",
]
[lint]
select = [
"E",
"W",
"F",
]
ignore = [
# Trailing whitespace; the standard tidy process will enforce no trailing whitespace
"W291",
# 80 character line length; the standard tidy process will enforce line length
"E501",
]