From 60eb7c923dbb0da826e348ff0765076c7546c8f3 Mon Sep 17 00:00:00 2001 From: zefr0x <65136727+zefr0x@users.noreply.github.com> Date: Sat, 24 May 2025 17:19:47 +0300 Subject: [PATCH] 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 --- .flake8 | 18 ------------------ .vscode/extensions.json | 4 +++- etc/profilicate.py | 2 +- python/README.md | 2 +- python/requirements.txt | 6 ++---- python/tidy/tidy.py | 24 ++++++++++++------------ python/tox.ini | 3 --- ruff.toml | 27 +++++++++++++++++++++++++++ 8 files changed, 46 insertions(+), 40 deletions(-) delete mode 100644 .flake8 delete mode 100644 python/tox.ini create mode 100644 ruff.toml diff --git a/.flake8 b/.flake8 deleted file mode 100644 index d4fb3a318ee..00000000000 --- a/.flake8 +++ /dev/null @@ -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 diff --git a/.vscode/extensions.json b/.vscode/extensions.json index d776261927d..7bf53b27bf2 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -16,6 +16,8 @@ // IDL language support "mythmon.idl", // TOML files - "tamasfe.even-better-toml" + "tamasfe.even-better-toml", + // Python files + "charliermarsh.ruff" ] } \ No newline at end of file diff --git a/etc/profilicate.py b/etc/profilicate.py index 3fa35b5ba77..5112497d4bb 100644 --- a/etc/profilicate.py +++ b/etc/profilicate.py @@ -79,7 +79,7 @@ for (name, raw_samples) in sorted(iter(thread_data.items()), key=lambda x: threa for frame in sample[1]: if not frame['name']: continue - if not frame['name'] in frameMap: + if frame['name'] not in frameMap: frameMap[frame['name']] = len(frames) frame_index = string_table.get(frame['name']) frames.append([frame_index]) diff --git a/python/README.md b/python/README.md index b79a4b2e8ea..d97dc6d6ddd 100644 --- a/python/README.md +++ b/python/README.md @@ -8,7 +8,7 @@ is the canonical repository for this code. # `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. # `wpt` diff --git a/python/requirements.txt b/python/requirements.txt index d64f33add3c..c5e1a0c9bbb 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -8,10 +8,8 @@ mozlog == 8.0.0 setuptools == 78.1.1 toml == 0.9.2 -# For Python linting -flake8 == 7.0.0 -pep8 == 1.5.7 -pyflakes == 3.2.0 +# For Python linting and formatting +ruff == 0.11.10 # For test-webidl ply == 3.8 diff --git a/python/tidy/tidy.py b/python/tidy/tidy.py index fe44be23df8..98062e77683 100644 --- a/python/tidy/tidy.py +++ b/python/tidy/tidy.py @@ -356,19 +356,18 @@ def check_by_line(file_name: str, lines: list[bytes]): yield error -def check_flake8(file_name, contents): - if not file_name.endswith(".py"): - return - - output = "" +def check_ruff_lints(): try: - args = ["flake8", file_name] + args = ["ruff", "check", "--output-format", "json"] subprocess.check_output(args, universal_newlines=True) except subprocess.CalledProcessError as e: - output = e.output - for error in output.splitlines(): - _, line_num, _, message = error.split(":", 3) - yield line_num, message.strip() + for error in json.loads(e.output): + yield ( + os.path.join(".", os.path.relpath(error["filename"])), + error["location"]["row"], + f"[{error['code']}] {error['message']} ({error['url']})", + ) + 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']) # standard checks 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, check_rust, check_spec, check_modeline) 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() wpt_errors = run_wpt_lints(only_changed_files) # chain all the iterators errors = itertools.chain(config_errors, directory_errors, file_errors, - wpt_errors, cargo_lock_errors) + python_errors, wpt_errors, cargo_lock_errors) colorama.init() error = None diff --git a/python/tox.ini b/python/tox.ini deleted file mode 100644 index e684cc63d8b..00000000000 --- a/python/tox.ini +++ /dev/null @@ -1,3 +0,0 @@ -[flake8] -filename = *.py -max-line-length = 120 diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 00000000000..2bc8ee0f250 --- /dev/null +++ b/ruff.toml @@ -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", +]