From 6144574954aa9b8127717c28e1028574aa5d5c5f Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 13 Apr 2026 16:40:15 -0700 Subject: [PATCH 1/8] ruff.toml: Increase line-length to 100 This was done in tc-build but not this repo, where it actually improves readability quite a bit. Signed-off-by: Nathan Chancellor --- ruff.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/ruff.toml b/ruff.toml index 0ccd3d2..f148a6d 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,4 +1,5 @@ target-version = 'py39' +line-length = 100 [format] quote-style = 'preserve' From e776a33d45938fb632b1a971a0c814d008404726 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 13 Apr 2026 16:41:09 -0700 Subject: [PATCH 2/8] boot-utils: Results of 'ruff format .' after line length increase Signed-off-by: Nathan Chancellor --- boot-qemu.py | 50 +++++++++++++------------------------------- buildroot/rebuild.py | 4 +--- utils.py | 20 +++++------------- 3 files changed, 20 insertions(+), 54 deletions(-) diff --git a/boot-qemu.py b/boot-qemu.py index 41c8a7d..c258128 100755 --- a/boot-qemu.py +++ b/boot-qemu.py @@ -108,9 +108,7 @@ def _get_default_smp_value(self) -> int: # * /../../../.config (if the image is in arch/*/boot/) # * /config (if the image is in a TuxMake folder) possible_locations = ['.config', '../../../.config', 'config'] - configuration = utils.find_first_file( - self.kernel_dir, possible_locations, required=False - ) + configuration = utils.find_first_file(self.kernel_dir, possible_locations, required=False) config_nr_cpus = 8 # sensible default based on treewide defaults, if configuration != utils.UNINIT_PATH: @@ -136,16 +134,10 @@ def _get_kernel_ver_tuple(self, decomp_prog: str) -> tuple[int, ...]: decomp = subprocess.run(decomp_cmd, capture_output=True, check=True) utils.check_cmd('strings') - strings = subprocess.run( - 'strings', capture_output=True, check=True, input=decomp.stdout - ) + strings = subprocess.run('strings', capture_output=True, check=True, input=decomp.stdout) strings_stdout = strings.stdout.decode(encoding='utf-8', errors='ignore') - if not ( - match := re.search( - r'^Linux version (\d+\.\d+\.\d+)', strings_stdout, flags=re.M - ) - ): + if not (match := re.search(r'^Linux version (\d+\.\d+\.\d+)', strings_stdout, flags=re.M)): raise RuntimeError(f"Could not find Linux version in {self.kernel}?") return tuple(int(x) for x in match.groups()[0].split('.')) @@ -505,7 +497,9 @@ def __init__(self) -> None: bios = Path(utils.BOOT_UTILS, 'images', self._initrd_arch, 'QEMU_EFI.fd') if not bios.exists(): bios.parent.mkdir(exist_ok=True, parents=True) - firmware_url = f"https://github.com/loongson/Firmware/raw/main/LoongArchVirtMachine/{bios.name}" + firmware_url = ( + f"https://github.com/loongson/Firmware/raw/main/LoongArchVirtMachine/{bios.name}" + ) utils.green(f"Downloading LoongArch firmware from {firmware_url}...") curl_cmd = ['curl', '-LSs', '-o', bios, firmware_url] subprocess.run(curl_cmd, check=True) @@ -694,9 +688,7 @@ def run(self) -> None: Path('OVMF/OVMF_VARS.fd'), # Debian and Ubuntu ] ovmf_vars = utils.find_first_file(usr_share, ovmf_vars_locations) - self._efi_vars = Path( - utils.BOOT_UTILS, 'images', self._initrd_arch, ovmf_vars.name - ) + self._efi_vars = Path(utils.BOOT_UTILS, 'images', self._initrd_arch, ovmf_vars.name) # This file is in /usr/share, so it must be copied in order to be # modified. shutil.copyfile(ovmf_vars, self._efi_vars) @@ -720,12 +712,8 @@ def guess_arch(kernel_arg: Path) -> str: # # Note: 'required=False' just to provide our own exception. vmlinux_locations = ['vmlinux', '../../../vmlinux'] - if not ( - vmlinux := utils.find_first_file(kernel_dir, vmlinux_locations, required=False) - ): - raise RuntimeError( - 'Architecture was not provided and vmlinux could not be found!' - ) + if not (vmlinux := utils.find_first_file(kernel_dir, vmlinux_locations, required=False)): + raise RuntimeError('Architecture was not provided and vmlinux could not be found!') if not (file := shutil.which('file')): raise RuntimeError("Architecture was not provided and 'file' is not installed!") @@ -783,9 +771,7 @@ def parse_arguments(): help="The architecture to boot. If omitted, value will be guessed based on 'vmlinux' if available. Possible values are: %(choices)s", metavar='ARCH', ) - parser.add_argument( - '--efi', action='store_true', help='Boot kernel via UEFI (x86_64 only)' - ) + parser.add_argument('--efi', action='store_true', help='Boot kernel via UEFI (x86_64 only)') parser.add_argument( '-g', '--gdb', @@ -855,9 +841,7 @@ def parse_arguments(): args = parse_arguments() if not (kernel_location := Path(args.kernel_location).resolve()).exists(): - raise FileNotFoundError( - f"Supplied kernel location ('{kernel_location}') does not exist!" - ) + raise FileNotFoundError(f"Supplied kernel location ('{kernel_location}') does not exist!") if not (arch := args.architecture): arch = guess_arch(kernel_location) @@ -900,9 +884,7 @@ def parse_arguments(): if args.efi: runner.efi = runner.supports_efi if not runner.efi: - utils.yellow( - f"EFI boot requested on unsupported architecture ('{arch}'), ignoring..." - ) + utils.yellow(f"EFI boot requested on unsupported architecture ('{arch}'), ignoring...") if args.gdb: runner.gdb = True @@ -921,13 +903,9 @@ def parse_arguments(): if args.modules: if not (modules := Path(args.modules).resolve()).exists(): - raise FileNotFoundError( - f"Supplied modules .cpio ('{modules}') does not exist?" - ) + raise FileNotFoundError(f"Supplied modules .cpio ('{modules}') does not exist?") if not args.memory: - utils.yellow( - 'Memory not specified, the default may be too small for modules...' - ) + utils.yellow('Memory not specified, the default may be too small for modules...') runner.modules = modules if args.no_kvm: diff --git a/buildroot/rebuild.py b/buildroot/rebuild.py index 073bf03..15875c0 100755 --- a/buildroot/rebuild.py +++ b/buildroot/rebuild.py @@ -175,9 +175,7 @@ def parse_arguments(): if not shutil.which('zstd'): raise RuntimeError('zstd could not be found on your system, please install it!') - architectures = ( - SUPPORTED_ARCHES if 'all' in args.architectures else args.architectures - ) + architectures = SUPPORTED_ARCHES if 'all' in args.architectures else args.architectures download_and_extract_buildroot() for arch in architectures: diff --git a/utils.py b/utils.py index df02bbf..ce0a13e 100755 --- a/utils.py +++ b/utils.py @@ -128,9 +128,7 @@ def get_full_kernel_path( elif arch: kernel = kernel_location.joinpath("arch", arch, "boot", image) else: - die( - f"Kernel image ('{image}') is in the arch/ directory but 'arch' was not provided!" - ) + die(f"Kernel image ('{image}') is in the arch/ directory but 'arch' was not provided!") if not kernel.exists(): die(f"Kernel ('{kernel}') does not exist!") @@ -160,13 +158,9 @@ def get_gh_json(endpoint: str) -> dict[str, Any]: curl_cmd.append(endpoint) try: - curl_out = subprocess.run( - curl_cmd, capture_output=True, check=True, text=True - ).stdout + curl_out = subprocess.run(curl_cmd, capture_output=True, check=True, text=True).stdout except subprocess.CalledProcessError as err: - raise RuntimeError( - f"Failed to query GitHub API at {endpoint}: {err.stderr}" - ) from err + raise RuntimeError(f"Failed to query GitHub API at {endpoint}: {err.stderr}") from err return json.loads(curl_out) @@ -201,9 +195,7 @@ def prepare_initrd( # querying the GitHub API at all. if gh_json_file and gh_json_file != UNINIT_PATH: if not gh_json_file.exists(): - raise FileNotFoundError( - f"Provided GitHub JSON file ('{gh_json_file}') does not exist!" - ) + raise FileNotFoundError(f"Provided GitHub JSON file ('{gh_json_file}') does not exist!") gh_json_rel = json.loads(gh_json_file.read_text(encoding='utf-8')) else: # Make sure that the current user is not rate limited by GitHub, @@ -214,9 +206,7 @@ def prepare_initrd( # and cached the result, we can query for the latest release to make sure # that we are up to date. if (remaining := gh_json_rl['resources']['core']['remaining']) > 0: - gh_json_rel = get_gh_json( - f"https://api.github.com/repos/{REPO}/releases/latest" - ) + gh_json_rel = get_gh_json(f"https://api.github.com/repos/{REPO}/releases/latest") elif not src.exists(): limit = gh_json_rl['resources']['core']['limit'] raise RuntimeError( From d3700c792d0ba6bb847c08b9888ef44e17f4dff0 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 13 Apr 2026 16:42:38 -0700 Subject: [PATCH 3/8] ruff.toml: Enable isort Signed-off-by: Nathan Chancellor --- ruff.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/ruff.toml b/ruff.toml index f148a6d..da9c47a 100644 --- a/ruff.toml +++ b/ruff.toml @@ -13,6 +13,7 @@ select = [ 'C4', # flake8-comprehensions 'E', # pycodestyle 'F', # pyflakes + 'I', # isort 'PIE', # flake8-pie 'PL', # pylint 'PTH', # flake8-use-pathlib From e318419ef7b30271baf450af21af17a3b5739c94 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 13 Apr 2026 16:42:53 -0700 Subject: [PATCH 4/8] boot-utils: Result of 'ruff check --fix .' after enabling isort Signed-off-by: Nathan Chancellor --- boot-qemu.py | 7 +++---- boot-uml.py | 2 +- buildroot/rebuild.py | 4 ++-- utils.py | 6 +++--- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/boot-qemu.py b/boot-qemu.py index c258128..d0aed59 100755 --- a/boot-qemu.py +++ b/boot-qemu.py @@ -1,22 +1,21 @@ #!/usr/bin/env python3 # pylint: disable=invalid-name -from argparse import ArgumentParser -from collections.abc import Sequence import contextlib import os -from pathlib import Path import platform import re import shlex import shutil import subprocess import sys +from argparse import ArgumentParser +from collections.abc import Sequence +from pathlib import Path from typing import Any, Union import utils - SUPPORTED_ARCHES = [ 'arm', 'arm32_v5', diff --git a/boot-uml.py b/boot-uml.py index c537cfd..54e2382 100755 --- a/boot-uml.py +++ b/boot-uml.py @@ -2,8 +2,8 @@ # pylint: disable=invalid-name import argparse -from pathlib import Path import subprocess +from pathlib import Path import utils diff --git a/buildroot/rebuild.py b/buildroot/rebuild.py index 15875c0..a11be27 100755 --- a/buildroot/rebuild.py +++ b/buildroot/rebuild.py @@ -1,11 +1,11 @@ #!/usr/bin/env python3 -from argparse import ArgumentParser import datetime import os -from pathlib import Path import shutil import subprocess +from argparse import ArgumentParser +from pathlib import Path BUILDROOT_VERSION = '2024.02.8' SUPPORTED_ARCHES = [ diff --git a/utils.py b/utils.py index ce0a13e..3a662f2 100755 --- a/utils.py +++ b/utils.py @@ -1,12 +1,12 @@ #!/usr/bin/env python3 -from collections.abc import Iterable import json import os -from pathlib import Path -import subprocess import shutil +import subprocess import sys +from collections.abc import Iterable +from pathlib import Path from typing import Any, NoReturn, Optional, Union BOOT_UTILS = Path(__file__).resolve().parent From ae3982af7cac2f36f86b493ca6e24a45575a5091 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 13 Apr 2026 16:43:43 -0700 Subject: [PATCH 5/8] ruff.toml: Enable refurb Signed-off-by: Nathan Chancellor --- ruff.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/ruff.toml b/ruff.toml index da9c47a..dcb6dd8 100644 --- a/ruff.toml +++ b/ruff.toml @@ -13,6 +13,7 @@ select = [ 'C4', # flake8-comprehensions 'E', # pycodestyle 'F', # pyflakes + 'FURB', # refurb 'I', # isort 'PIE', # flake8-pie 'PL', # pylint From cd007119da9b53a2a057105ef0eb4ce2349117b8 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 13 Apr 2026 16:44:25 -0700 Subject: [PATCH 6/8] boot-qemu.py: Use re.MULTILINE instead of re.M As suggested by the refurb rules from ruff: FURB167 [*] Use of regular expression alias `re.M` --> boot-qemu.py:140:93 | 138 | strings_stdout = strings.stdout.decode(encoding='utf-8', errors='ignore') 139 | 140 | if not (match := re.search(r'^Linux version (\d+\.\d+\.\d+)', strings_stdout, flags=re.M)): | ^^^^ 141 | raise RuntimeError(f"Could not find Linux version in {self.kernel}?") | help: Replace with `re.MULTILINE` Signed-off-by: Nathan Chancellor --- boot-qemu.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/boot-qemu.py b/boot-qemu.py index d0aed59..52b37b6 100755 --- a/boot-qemu.py +++ b/boot-qemu.py @@ -136,7 +136,11 @@ def _get_kernel_ver_tuple(self, decomp_prog: str) -> tuple[int, ...]: strings = subprocess.run('strings', capture_output=True, check=True, input=decomp.stdout) strings_stdout = strings.stdout.decode(encoding='utf-8', errors='ignore') - if not (match := re.search(r'^Linux version (\d+\.\d+\.\d+)', strings_stdout, flags=re.M)): + if not ( + match := re.search( + r'^Linux version (\d+\.\d+\.\d+)', strings_stdout, flags=re.MULTILINE + ) + ): raise RuntimeError(f"Could not find Linux version in {self.kernel}?") return tuple(int(x) for x in match.groups()[0].split('.')) From 91854f915ac19235f511b88579644c27d46e46f4 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 13 Apr 2026 16:46:08 -0700 Subject: [PATCH 7/8] boot-qemu.py: Eliminate single item container in _get_kernel_ver_tuple() As pointed out by the refurb rules in ruff.toml: FURB171 Membership test against single-item container --> boot-qemu.py:130:12 | 129 | utils.check_cmd(decomp_prog) 130 | if decomp_prog in ('gzip',): | ^^^^^^^^^^^^^^^^^^^^^^^^ 131 | decomp_cmd = [decomp_prog, '-c', '-d', self.kernel] 132 | else: | help: Convert to equality test Signed-off-by: Nathan Chancellor --- boot-qemu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot-qemu.py b/boot-qemu.py index 52b37b6..959fdc1 100755 --- a/boot-qemu.py +++ b/boot-qemu.py @@ -126,7 +126,7 @@ def _get_kernel_ver_tuple(self, decomp_prog: str) -> tuple[int, ...]: raise RuntimeError('No kernel set?') utils.check_cmd(decomp_prog) - if decomp_prog in ('gzip',): + if decomp_prog == 'gzip': decomp_cmd = [decomp_prog, '-c', '-d', self.kernel] else: raise RuntimeError(f"Unsupported decompression program ('{decomp_prog}')?") From 3744a8891a7e1b297dbfd48df2f616ad5fb1a29c Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 13 Apr 2026 16:47:20 -0700 Subject: [PATCH 8/8] ruff.toml: Enable several other Ruff lints There are no instances of these currently but they all seem like relatively safe additions (even if DTZ may never get triggered since this project does not use datetime). Signed-off-by: Nathan Chancellor --- ruff.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ruff.toml b/ruff.toml index dcb6dd8..ab0ab0f 100644 --- a/ruff.toml +++ b/ruff.toml @@ -11,10 +11,13 @@ select = [ 'ARG', # flake8-unused-arguments 'B', # flake8-bugbear 'C4', # flake8-comprehensions + 'DTZ', # flake8-datetimes 'E', # pycodestyle 'F', # pyflakes 'FURB', # refurb 'I', # isort + 'N', # pep8-naming + 'PERF', # perflint 'PIE', # flake8-pie 'PL', # pylint 'PTH', # flake8-use-pathlib @@ -23,6 +26,8 @@ select = [ 'S', # flake8-bandit 'SIM', # flake8-simplify 'SLF', # flake8-self + 'TC', # flake8-type-checking + 'TRY', # tryceratops 'UP', # pyupgrade 'W', # pycodestyle ] @@ -35,4 +40,5 @@ ignore = [ 'PLR2004', # magic-value-comparison 'S603', # subprocess-without-shell-equals-true 'S607', # start-process-with-partial-path + 'TRY003', # raise-vanilla-args ]