[PATCH 00/11] buildman: Pylint cleanups
From: Simon Glass <simon.glass@canonical.com> This series cleans up pylint warnings across several buildman modules, bringing them all to 10.00/10: - main.py: Remove dead imports, fix docstrings, fix control flow - bsettings.py: Add docstrings, fix exception handling, use f-strings - test_bsettings.py: Use tools.read_file/write_file helpers - toolchain.py: Rename CamelCase methods to snake_case, add docstrings, document public members, use f-strings, fix various warnings - test_boards.py: Fix long lines, unused variables The toolchain.py changes are split into multiple commits for easier review, as the file required significant updates. Simon Glass (11): buildman: Fix pylint warnings in main.py claude: Drop mention of --no-ext-diff buildman: Fix pylint warnings in bsettings.py buildman: Use tools.read_file/write_file in test_bsettings.py buildman: Rename toolchain methods to snake_case buildman: Fix docstrings in toolchain.py buildman: Make MyHTMLParser.re_arch private buildman: Document all Toolchain public members buildman: Use f-strings in toolchain.py buildman: Fix remaining pylint warnings in toolchain.py buildman: Fix pylint warnings in test_boards.py CLAUDE.md | 1 - tools/buildman/bsettings.py | 60 +++--- tools/buildman/builder.py | 2 +- tools/buildman/builderthread.py | 6 +- tools/buildman/control.py | 16 +- tools/buildman/func_test.py | 6 +- tools/buildman/main.py | 30 ++- tools/buildman/test.py | 90 ++++---- tools/buildman/test_boards.py | 72 ++++--- tools/buildman/test_bsettings.py | 16 +- tools/buildman/toolchain.py | 350 +++++++++++++++++-------------- tools/qconfig.py | 8 +- 12 files changed, 346 insertions(+), 311 deletions(-) -- 2.43.0 base-commit: 37a183535e61f03ad872b085c358bc7fe0a0a5ba branch: bml
From: Simon Glass <simon.glass@canonical.com> Fix the remaining pylint warnings: - Remove dead Python 3.6 importlib_resources fallback import - Fix docstring parameter name (verbosity -> verbose) - Remove unnecessary elif/else after return statements - Add missing return statements for consistent function returns Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/buildman/main.py | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/tools/buildman/main.py b/tools/buildman/main.py index 22be946b37d..914dfe04988 100755 --- a/tools/buildman/main.py +++ b/tools/buildman/main.py @@ -6,11 +6,7 @@ """See README for more information""" -try: - import importlib.resources -except ImportError: - # for Python 3.6 - import importlib_resources +import importlib.resources import os import sys @@ -33,7 +29,7 @@ def run_tests(skip_net_tests, debug, verbose, args): Args: skip_net_tests (bool): True to skip tests which need the network debug (bool): True to run in debugging mode (full traceback) - verbosity (int): Verbosity level to use (0-4) + verbose (int): Verbosity level to use (0-4) args (list of str): List of tests to run, empty to run all """ # These imports are here since tests are not available when buildman is @@ -87,27 +83,27 @@ def run_buildman(): if cmdline.HAS_TESTS and args.test: return run_tests(args.skip_net_tests, args.debug, args.verbose, args) - elif cmdline.HAS_TESTS and args.coverage: + if cmdline.HAS_TESTS and args.coverage: run_test_coverage() + return 0 - elif args.full_help: + if args.full_help: if hasattr(importlib.resources, 'files'): dirpath = importlib.resources.files('buildman') tools.print_full_help(str(dirpath.joinpath('README.rst'))) else: with importlib.resources.path('buildman', 'README.rst') as readme: tools.print_full_help(str(readme)) - + return 0 # Build selected commits for selected boards - else: - try: - tout.init(tout.INFO if args.verbose else tout.WARNING) - bsettings.setup(args.config_file) - ret_code = control.do_buildman(args) - finally: - tout.uninit() - return ret_code + try: + tout.init(tout.INFO if args.verbose else tout.WARNING) + bsettings.setup(args.config_file) + ret_code = control.do_buildman(args) + finally: + tout.uninit() + return ret_code if __name__ == "__main__": -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> This is not needed anymore, so drop it. The .gitconfig file now has this: [diff] tool = meld prompt = true Signed-off-by: Simon Glass <simon.glass@canonical.com> --- CLAUDE.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index aaec9cc031d..5923cd7d8dd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -58,7 +58,6 @@ um py -B sandbox <test_name> - The `um` tool is the preferred build method for this codebase - Always run `make mrproper` if you encounter build issues - The sandbox build creates a test environment for U-Boot that runs on the host system -- When using `git diff`, add `--no-ext-diff` to avoid external diff tools that may not work in this environment - `um build` shows no output if everything was ok! - Remember not to cd into the build directory; run U-Boot directly in the source dir - Do not run in-tree builds; always use the crosfw script or 'make O=/tmp/...' -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> - Add module docstring and define settings at module level - Fix docstrings: correct param names, add types, remove redundant returns - Add docstrings for add_file() and add_section() - Remove pointless except:raise and unused variable in get_items() - Remove unnecessary global statements in set_item() - Add encoding='utf-8' to open() calls - Rename param to avoid shadowing global config_fname - Use with statement for file handling - Convert % formatting to f-strings - Remove unnecessary semicolon - Add pylint disable comments for intentional global usage Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/buildman/bsettings.py | 60 ++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/tools/buildman/bsettings.py b/tools/buildman/bsettings.py index a7358cfc08a..1af2bc66101 100644 --- a/tools/buildman/bsettings.py +++ b/tools/buildman/bsettings.py @@ -1,26 +1,30 @@ # SPDX-License-Identifier: GPL-2.0+ # Copyright (c) 2012 The Chromium OS Authors. +"""Handles settings for buildman, reading from a config file.""" + import configparser -import os import io +import os +# pylint: disable=C0103 +settings = None config_fname = None def setup(fname=''): """Set up the buildman settings module by reading config files Args: - config_fname: Config filename to read ('' for default) + fname (str): Config filename to read ('' for default) """ - global settings - global config_fname + global settings # pylint: disable=W0603 + global config_fname # pylint: disable=W0603 settings = configparser.ConfigParser() if fname is not None: config_fname = fname if config_fname == '': - config_fname = '%s/.buildman' % os.getenv('HOME') + config_fname = f"{os.getenv('HOME')}/.buildman" if not os.path.exists(config_fname): print('No config file found ~/.buildman\nCreating one...\n') create_buildman_config_file(config_fname) @@ -29,32 +33,40 @@ def setup(fname=''): settings.read(config_fname) def add_file(data): + """Add settings from a string + + Args: + data (str): Config data in INI format + """ settings.read_file(io.StringIO(data)) def add_section(name): + """Add a new section to the settings + + Args: + name (str): Name of section to add + """ settings.add_section(name) def get_items(section): """Get the items from a section of the config. Args: - section: name of section to retrieve + section (str): name of section to retrieve Returns: - List of (name, value) tuples for the section + list of tuple: List of (name, value) tuples for the section """ try: return settings.items(section) - except configparser.NoSectionError as e: + except configparser.NoSectionError: return [] - except: - raise def get_global_item_value(name): """Get an item from the 'global' section of the config. Args: - name: name of item to retrieve + name (str): name of item to retrieve Returns: str: Value of item, or None if not present @@ -63,30 +75,20 @@ def get_global_item_value(name): def set_item(section, tag, value): """Set an item and write it back to the settings file""" - global settings - global config_fname - settings.set(section, tag, value) if config_fname is not None: - with open(config_fname, 'w') as fd: + with open(config_fname, 'w', encoding='utf-8') as fd: settings.write(fd) -def create_buildman_config_file(config_fname): +def create_buildman_config_file(cfgname): """Creates a new config file with no tool chain information. Args: - config_fname: Config filename to create - - Returns: - None + cfgname (str): Config filename to create """ try: - f = open(config_fname, 'w') - except IOError: - print("Couldn't create buildman config file '%s'\n" % config_fname) - raise - - print('''[toolchain] + with open(cfgname, 'w', encoding='utf-8') as out: + print('''[toolchain] # name = path # e.g. x86 = /opt/gcc-4.6.3-nolibc/x86_64-linux other = / @@ -108,5 +110,7 @@ x86 = i386 # snapper-boards=ENABLE_AT91_TEST=1 # snapper9260=${snapper-boards} BUILD_TAG=442 # snapper9g45=${snapper-boards} BUILD_TAG=443 -''', file=f) - f.close(); +''', file=out) + except IOError: + print(f"Couldn't create buildman config file '{cfgname}'\n") + raise -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Replace direct open() calls with tools.read_file() and tools.write_file() for consistency with other U-Boot Python code. Also move shutil import to top level. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/buildman/test_bsettings.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/tools/buildman/test_bsettings.py b/tools/buildman/test_bsettings.py index 524281f49b0..87cc3c19dd9 100644 --- a/tools/buildman/test_bsettings.py +++ b/tools/buildman/test_bsettings.py @@ -4,11 +4,13 @@ """Tests for bsettings.py""" import os +import shutil import tempfile import unittest from unittest import mock from buildman import bsettings +from u_boot_pylib import tools class TestBsettings(unittest.TestCase): @@ -18,7 +20,6 @@ class TestBsettings(unittest.TestCase): self._tmpdir = tempfile.mkdtemp() def tearDown(self): - import shutil shutil.rmtree(self._tmpdir) def test_setup_no_file(self): @@ -44,8 +45,8 @@ class TestBsettings(unittest.TestCase): def test_setup_existing_file(self): """Test setup() reads existing config file""" config_file = os.path.join(self._tmpdir, 'test.buildman') - with open(config_file, 'w') as f: - f.write('[toolchain]\narm = /opt/arm\n') + tools.write_file(config_file, '[toolchain]\narm = /opt/arm\n', + binary=False) bsettings.setup(config_file) items = bsettings.get_items('toolchain') @@ -88,8 +89,7 @@ class TestBsettings(unittest.TestCase): def test_set_item(self): """Test set_item() sets value and writes to file""" config_file = os.path.join(self._tmpdir, 'test_set.buildman') - with open(config_file, 'w') as f: - f.write('[toolchain]\n') + tools.write_file(config_file, '[toolchain]\n', binary=False) bsettings.setup(config_file) bsettings.set_item('toolchain', 'newkey', 'newvalue') @@ -99,8 +99,7 @@ class TestBsettings(unittest.TestCase): self.assertEqual('newvalue', items['newkey']) # Value should be written to file - with open(config_file) as f: - content = f.read() + content = tools.read_file(config_file, binary=False) self.assertIn('newkey', content) self.assertIn('newvalue', content) @@ -122,8 +121,7 @@ class TestBsettings(unittest.TestCase): bsettings.create_buildman_config_file(config_file) self.assertTrue(os.path.exists(config_file)) - with open(config_file) as f: - content = f.read() + content = tools.read_file(config_file, binary=False) self.assertIn('[toolchain]', content) self.assertIn('[toolchain-prefix]', content) self.assertIn('[toolchain-alias]', content) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Rename all CamelCase methods in toolchain.py to snake_case to follow Python naming conventions and fix pylint warnings. Toolchain class: - GetPriority() -> get_priority() - GetWrapper() -> get_wrapper() - GetEnvArgs() -> get_env_args() - MakeEnvironment() -> make_environment() - MakeArgs() -> make_args() Toolchains class: - GetPathList() -> get_path_list() - GetSettings() -> get_settings() - Add() -> add() - ScanPath() -> scan_path() - ScanPathEnv() -> scan_path_env() - Scan() -> scan() - List() -> list() - Select() -> select() - ResolveReferences() -> resolve_references() - GetMakeArguments() -> get_make_arguments() - LocateArchUrl() -> locate_arch_url() - Unpack() -> unpack() - TestSettingsHasPath() -> test_settings_has_path() - ListArchs() -> list_archs() - FetchAndInstall() -> fetch_and_install() Update all callers in buildman and qconfig.py. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/buildman/builder.py | 2 +- tools/buildman/builderthread.py | 6 +-- tools/buildman/control.py | 16 +++--- tools/buildman/func_test.py | 6 +-- tools/buildman/test.py | 90 ++++++++++++++++----------------- tools/buildman/toolchain.py | 84 +++++++++++++++--------------- tools/qconfig.py | 8 +-- 7 files changed, 106 insertions(+), 106 deletions(-) diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py index e218aa4184a..28943a5a9b8 100644 --- a/tools/buildman/builder.py +++ b/tools/buildman/builder.py @@ -435,7 +435,7 @@ class Builder: key (str): Variable name value (str): Variable value """ - env = toolchain.MakeEnvironment(self.full_path) + env = toolchain.make_environment(self.full_path) if self.dtc: env[b'DTC'] = tools.to_bytes(self.dtc) return env diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py index 3d1b656531d..0fd589934fe 100644 --- a/tools/buildman/builderthread.py +++ b/tools/buildman/builderthread.py @@ -274,8 +274,8 @@ class BuilderThread(threading.Thread): args.append('NO_LTO=1') if self.builder.reproducible_builds: args.append('SOURCE_DATE_EPOCH=0') - args.extend(self.builder.toolchains.GetMakeArguments(brd)) - args.extend(self.toolchain.MakeArgs()) + args.extend(self.builder.toolchains.get_make_arguments(brd)) + args.extend(self.toolchain.make_args()) return args, cwd, src_dir def _reconfigure(self, commit, brd, cwd, args, env, config_args, config_out, @@ -549,7 +549,7 @@ class BuilderThread(threading.Thread): # We are going to have to build it. First, get a toolchain if not self.toolchain: try: - self.toolchain = self.builder.toolchains.Select(brd.arch) + self.toolchain = self.builder.toolchains.select(brd.arch) except ValueError as err: result.return_code = 10 result.stdout = '' diff --git a/tools/buildman/control.py b/tools/buildman/control.py index f43d8fcf715..88e8338c599 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -152,11 +152,11 @@ def show_toolchain_prefix(brds, toolchains): board_selected = brds.get_selected_dict() tc_set = set() for brd in board_selected.values(): - tc_set.add(toolchains.Select(brd.arch)) + tc_set.add(toolchains.select(brd.arch)) if len(tc_set) != 1: sys.exit('Supplied boards must share one toolchain') tchain = tc_set.pop() - print(tchain.GetEnvArgs(toolchain.VAR_CROSS_COMPILE)) + print(tchain.get_env_args(toolchain.VAR_CROSS_COMPILE)) def show_arch(brds): """Show information about a the architecture used by one or more boards @@ -330,19 +330,19 @@ def do_fetch_arch(toolchains, col, fetch_arch): int: Return code for buildman """ if fetch_arch == 'list': - sorted_list = toolchains.ListArchs() + sorted_list = toolchains.list_archs() print(col.build( col.BLUE, f"Available architectures: {' '.join(sorted_list)}\n")) return 0 if fetch_arch == 'all': - fetch_arch = ','.join(toolchains.ListArchs()) + fetch_arch = ','.join(toolchains.list_archs()) print(col.build(col.CYAN, f'\nDownloading toolchains: {fetch_arch}')) for arch in fetch_arch.split(','): print() - ret = toolchains.FetchAndInstall(arch) + ret = toolchains.fetch_and_install(arch) if ret: return ret return 0 @@ -374,10 +374,10 @@ def get_toolchains(toolchains, col, override_toolchain, fetch_arch, return do_fetch_arch(toolchains, col, fetch_arch) if no_toolchains: - toolchains.GetSettings() - toolchains.Scan(list_tool_chains and verbose) + toolchains.get_settings() + toolchains.scan(list_tool_chains and verbose) if list_tool_chains: - toolchains.List() + toolchains.list() print() return 0 return toolchains diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py index 6167ea525e7..3ecbd22613f 100644 --- a/tools/buildman/func_test.py +++ b/tools/buildman/func_test.py @@ -194,8 +194,8 @@ class TestFunctional(unittest.TestCase): bsettings.setup(None) bsettings.add_file(settings_data) self.setupToolchains() - self._toolchains.Add('arm-gcc', test=False) - self._toolchains.Add('powerpc-gcc', test=False) + self._toolchains.add('arm-gcc', test=False) + self._toolchains.add('powerpc-gcc', test=False) self._boards = boards.Boards() for brd in BOARDS: self._boards.add_board(board.Board(*brd)) @@ -232,7 +232,7 @@ class TestFunctional(unittest.TestCase): def setupToolchains(self): self._toolchains = toolchain.Toolchains() - self._toolchains.Add('gcc', test=False) + self._toolchains.add('gcc', test=False) def _RunBuildman(self, *args): all_args = [self._buildman_pathname] + list(args) diff --git a/tools/buildman/test.py b/tools/buildman/test.py index 8269dfec2ba..3d153619d5d 100644 --- a/tools/buildman/test.py +++ b/tools/buildman/test.py @@ -166,11 +166,11 @@ class TestBuild(unittest.TestCase): # Set up the toolchains self.toolchains = toolchain.Toolchains() - self.toolchains.Add('arm-linux-gcc', test=False) - self.toolchains.Add('sparc-linux-gcc', test=False) - self.toolchains.Add('powerpc-linux-gcc', test=False) - self.toolchains.Add('/path/to/aarch64-linux-gcc', test=False) - self.toolchains.Add('gcc', test=False) + self.toolchains.add('arm-linux-gcc', test=False) + self.toolchains.add('sparc-linux-gcc', test=False) + self.toolchains.add('powerpc-linux-gcc', test=False) + self.toolchains.add('/path/to/aarch64-linux-gcc', test=False) + self.toolchains.add('gcc', test=False) # Avoid sending any output terminal.set_print_test_mode() @@ -594,82 +594,82 @@ class TestBuild(unittest.TestCase): self.CheckDirs(build, '') def testToolchainAliases(self): - self.assertTrue(self.toolchains.Select('arm') != None) + self.assertTrue(self.toolchains.select('arm') != None) with self.assertRaises(ValueError): - self.toolchains.Select('no-arch') + self.toolchains.select('no-arch') with self.assertRaises(ValueError): - self.toolchains.Select('x86') + self.toolchains.select('x86') self.toolchains = toolchain.Toolchains() - self.toolchains.Add('x86_64-linux-gcc', test=False) - self.assertTrue(self.toolchains.Select('x86') != None) + self.toolchains.add('x86_64-linux-gcc', test=False) + self.assertTrue(self.toolchains.select('x86') != None) self.toolchains = toolchain.Toolchains() - self.toolchains.Add('i386-linux-gcc', test=False) - self.assertTrue(self.toolchains.Select('x86') != None) + self.toolchains.add('i386-linux-gcc', test=False) + self.assertTrue(self.toolchains.select('x86') != None) def testToolchainDownload(self): """Test that we can download toolchains""" if use_network: with terminal.capture() as (stdout, stderr): - url = self.toolchains.LocateArchUrl('arm') + url = self.toolchains.locate_arch_url('arm') self.assertRegex(url, 'https://www.kernel.org/pub/tools/' 'crosstool/files/bin/x86_64/.*/' 'x86_64-gcc-.*-nolibc[-_]arm-.*linux-gnueabi.tar.xz') def testGetEnvArgs(self): """Test the GetEnvArgs() function""" - tc = self.toolchains.Select('arm') + tc = self.toolchains.select('arm') self.assertEqual('arm-linux-', - tc.GetEnvArgs(toolchain.VAR_CROSS_COMPILE)) - self.assertEqual('', tc.GetEnvArgs(toolchain.VAR_PATH)) + tc.get_env_args(toolchain.VAR_CROSS_COMPILE)) + self.assertEqual('', tc.get_env_args(toolchain.VAR_PATH)) self.assertEqual('arm', - tc.GetEnvArgs(toolchain.VAR_ARCH)) - self.assertEqual('', tc.GetEnvArgs(toolchain.VAR_MAKE_ARGS)) + tc.get_env_args(toolchain.VAR_ARCH)) + self.assertEqual('', tc.get_env_args(toolchain.VAR_MAKE_ARGS)) - tc = self.toolchains.Select('sandbox') - self.assertEqual('', tc.GetEnvArgs(toolchain.VAR_CROSS_COMPILE)) + tc = self.toolchains.select('sandbox') + self.assertEqual('', tc.get_env_args(toolchain.VAR_CROSS_COMPILE)) - self.toolchains.Add('/path/to/x86_64-linux-gcc', test=False) - tc = self.toolchains.Select('x86') + self.toolchains.add('/path/to/x86_64-linux-gcc', test=False) + tc = self.toolchains.select('x86') self.assertEqual('/path/to', - tc.GetEnvArgs(toolchain.VAR_PATH)) + tc.get_env_args(toolchain.VAR_PATH)) tc.override_toolchain = 'clang' self.assertEqual('HOSTCC=clang CC=clang', - tc.GetEnvArgs(toolchain.VAR_MAKE_ARGS)) + tc.get_env_args(toolchain.VAR_MAKE_ARGS)) # Test config with ccache wrapper bsettings.setup(None) bsettings.add_file(settings_data_wrapper) - tc = self.toolchains.Select('arm') + tc = self.toolchains.select('arm') self.assertEqual('ccache arm-linux-', - tc.GetEnvArgs(toolchain.VAR_CROSS_COMPILE)) + tc.get_env_args(toolchain.VAR_CROSS_COMPILE)) - tc = self.toolchains.Select('sandbox') - self.assertEqual('', tc.GetEnvArgs(toolchain.VAR_CROSS_COMPILE)) + tc = self.toolchains.select('sandbox') + self.assertEqual('', tc.get_env_args(toolchain.VAR_CROSS_COMPILE)) def testMakeEnvironment(self): - """Test the MakeEnvironment function""" + """Test the make_environment function""" os.environ.pop('CROSS_COMPILE', None) - tc = self.toolchains.Select('arm') - env = tc.MakeEnvironment(False) + tc = self.toolchains.select('arm') + env = tc.make_environment(False) self.assertEqual(env[b'CROSS_COMPILE'], b'arm-linux-') - tc = self.toolchains.Select('sandbox') - env = tc.MakeEnvironment(False) + tc = self.toolchains.select('sandbox') + env = tc.make_environment(False) self.assertTrue(b'CROSS_COMPILE' not in env) # Test config with ccache wrapper bsettings.setup(None) bsettings.add_file(settings_data_wrapper) - tc = self.toolchains.Select('arm') - env = tc.MakeEnvironment(False) + tc = self.toolchains.select('arm') + env = tc.make_environment(False) self.assertEqual(env[b'CROSS_COMPILE'], b'ccache arm-linux-') - tc = self.toolchains.Select('sandbox') - env = tc.MakeEnvironment(False) + tc = self.toolchains.select('sandbox') + env = tc.make_environment(False) self.assertTrue(b'CROSS_COMPILE' not in env) def testPrepareOutputSpace(self): @@ -942,7 +942,7 @@ class TestBuild(unittest.TestCase): self.assertEqual(self.finish_time, self.cur_time) def call_make_environment(self, tchn, full_path, in_env=None): - """Call Toolchain.MakeEnvironment() and process the result + """Call Toolchain.make_environment() and process the result Args: tchn (Toolchain): Toolchain to use @@ -958,7 +958,7 @@ class TestBuild(unittest.TestCase): which were added) str: Full value of the new PATH variable """ - env = tchn.MakeEnvironment(full_path, env=in_env) + env = tchn.make_environment(full_path, env=in_env) # Get the original environment orig_env = dict(os.environb if in_env is None else in_env) @@ -983,7 +983,7 @@ class TestBuild(unittest.TestCase): def test_toolchain_env(self): """Test PATH and other environment settings for toolchains""" # Use a toolchain which has a path, so that full_path makes a difference - tchn = self.toolchains.Select('aarch64') + tchn = self.toolchains.select('aarch64') # Normal cases diff = self.call_make_environment(tchn, full_path=False)[0] @@ -1044,13 +1044,13 @@ class TestBuild(unittest.TestCase): build = builder.Builder(self.toolchains, self.base_dir, None, 0, 2, dtc_skip=True) - tch = self.toolchains.Select('arm') + tch = self.toolchains.select('arm') env = build.make_environment(tch) self.assertIn(b'DTC', env) # Try the normal case, i.e. not skipping the dtc build build = builder.Builder(self.toolchains, self.base_dir, None, 0, 2) - tch = self.toolchains.Select('arm') + tch = self.toolchains.select('arm') env = build.make_environment(tch) self.assertNotIn(b'DTC', env) finally: @@ -1065,12 +1065,12 @@ class TestBuild(unittest.TestCase): # Set up the toolchains home = os.path.expanduser('~') toolchains = toolchain.Toolchains() - toolchains.GetSettings() + toolchains.get_settings() self.assertEqual([f'{home}/mypath'], toolchains.paths) # Check scanning with terminal.capture() as (stdout, _): - toolchains.Scan(verbose=True, raise_on_error=False) + toolchains.scan(verbose=True, raise_on_error=False) lines = iter(stdout.getvalue().splitlines() + ['##done']) self.assertEqual('Scanning for tool chains', next(lines)) self.assertEqual(f" - scanning prefix '{home}/mypath-x86-'", @@ -1087,7 +1087,7 @@ class TestBuild(unittest.TestCase): # Check adding a toolchain with terminal.capture() as (stdout, _): - toolchains.Add('~/aarch64-linux-gcc', test=True, verbose=True) + toolchains.add('~/aarch64-linux-gcc', test=True, verbose=True) lines = iter(stdout.getvalue().splitlines() + ['##done']) self.assertEqual('Tool chain test: BAD', next(lines)) self.assertEqual(f'Command: {home}/aarch64-linux-gcc --version', diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index 5e5bb4b0aed..346bb349dfe 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -91,12 +91,12 @@ class Toolchain: if self.arch == 'sandbox' and override_toolchain: self.gcc = override_toolchain - env = self.MakeEnvironment(False) + env = self.make_environment(False) # As a basic sanity check, run the C compiler with --version cmd = [fname, '--version'] if priority == PRIORITY_CALC: - self.priority = self.GetPriority(fname) + self.priority = self.get_priority(fname) else: self.priority = priority if test: @@ -116,7 +116,7 @@ class Toolchain: else: self.ok = True - def GetPriority(self, fname): + def get_priority(self, fname): """Return the priority of the toolchain. Toolchains are ranked according to their suitability by their @@ -136,7 +136,7 @@ class Toolchain: return PRIORITY_CALC + prio return PRIORITY_CALC + prio - def GetWrapper(self, show_warning=True): + def get_wrapper(self, show_warning=True): """Get toolchain wrapper from the setting file. """ value = '' @@ -148,7 +148,7 @@ class Toolchain: return value - def GetEnvArgs(self, which): + def get_env_args(self, which): """Get an environment variable/args value based on the the toolchain Args: @@ -158,7 +158,7 @@ class Toolchain: Value of that environment variable or arguments """ if which == VAR_CROSS_COMPILE: - wrapper = self.GetWrapper() + wrapper = self.get_wrapper() base = '' if self.arch == 'sandbox' else self.path if (base == '' and self.cross == ''): return '' @@ -168,14 +168,14 @@ class Toolchain: elif which == VAR_ARCH: return self.arch elif which == VAR_MAKE_ARGS: - args = self.MakeArgs() + args = self.make_args() if args: return ' '.join(args) return '' else: raise ValueError('Unknown arg to GetEnvArgs (%d)' % which) - def MakeEnvironment(self, full_path, env=None): + def make_environment(self, full_path, env=None): """Returns an environment for using the toolchain. This takes the current environment and adds CROSS_COMPILE so that @@ -206,7 +206,7 @@ class Toolchain: """ env = dict(env or os.environb) - wrapper = self.GetWrapper() + wrapper = self.get_wrapper() if self.override_toolchain: # We'll use MakeArgs() to provide this @@ -238,7 +238,7 @@ class Toolchain: return env - def MakeArgs(self): + def make_args(self): """Create the 'make' arguments for a toolchain This is only used when the toolchain is being overridden. Since the @@ -277,7 +277,7 @@ class Toolchains: self.override_toolchain = override_toolchain self._make_flags = dict(bsettings.get_items('make-flags')) - def GetPathList(self, show_warning=True): + def get_path_list(self, show_warning=True): """Get a list of available toolchain paths Args: @@ -304,16 +304,16 @@ class Toolchains: paths.append(fname) return paths - def GetSettings(self, show_warning=True): + def get_settings(self, show_warning=True): """Get toolchain settings from the settings file. Args: show_warning: True to show a warning if there are no tool chains. """ self.prefixes = bsettings.get_items('toolchain-prefix') - self.paths += self.GetPathList(show_warning) + self.paths += self.get_path_list(show_warning) - def Add(self, fname, test=True, verbose=False, priority=PRIORITY_CALC, + def add(self, fname, test=True, verbose=False, priority=PRIORITY_CALC, arch=None): """Add a toolchain to our list @@ -341,7 +341,7 @@ class Toolchains: (toolchain.gcc, toolchain.priority, toolchain.arch, self.toolchains[toolchain.arch].priority))) - def ScanPath(self, path, verbose): + def scan_path(self, path, verbose): """Scan a path for a valid toolchain Args: @@ -359,7 +359,7 @@ class Toolchains: fnames.append(fname) return fnames - def ScanPathEnv(self, fname): + def scan_path_env(self, fname): """Scan the PATH environment variable for a given filename. Args: @@ -375,7 +375,7 @@ class Toolchains: pathname_list.append(pathname) return pathname_list - def Scan(self, verbose, raise_on_error=True): + def scan(self, verbose, raise_on_error=True): """Scan for available toolchains and select the best for each arch. We look for all the toolchains we can file, figure out the @@ -390,15 +390,15 @@ class Toolchains: fname = os.path.expanduser(value) if verbose: print(" - scanning prefix '%s'" % fname) if os.path.exists(fname): - self.Add(fname, True, verbose, PRIORITY_FULL_PREFIX, name) + self.add(fname, True, verbose, PRIORITY_FULL_PREFIX, name) continue fname += 'gcc' if os.path.exists(fname): - self.Add(fname, True, verbose, PRIORITY_PREFIX_GCC, name) + self.add(fname, True, verbose, PRIORITY_PREFIX_GCC, name) continue - fname_list = self.ScanPathEnv(fname) + fname_list = self.scan_path_env(fname) for f in fname_list: - self.Add(f, True, verbose, PRIORITY_PREFIX_GCC_PATH, name) + self.add(f, True, verbose, PRIORITY_PREFIX_GCC_PATH, name) if not fname_list: msg = f"No tool chain found for prefix '{fname}'" if raise_on_error: @@ -407,11 +407,11 @@ class Toolchains: print(f'Error: {msg}') for path in self.paths: if verbose: print(" - scanning path '%s'" % path) - fnames = self.ScanPath(path, verbose) + fnames = self.scan_path(path, verbose) for fname in fnames: - self.Add(fname, True, verbose) + self.add(fname, True, verbose) - def List(self): + def list(self): """List out the selected toolchains for each architecture""" col = terminal.Color() print(col.build(col.BLUE, 'List of available toolchains (%d):' % @@ -422,7 +422,7 @@ class Toolchains: else: print('None') - def Select(self, arch): + def select(self, arch): """Returns the toolchain for a given architecture Args: @@ -441,7 +441,7 @@ class Toolchains: raise ValueError("No tool chain found for arch '%s'" % arch) return self.toolchains[arch] - def ResolveReferences(self, var_dict, args): + def resolve_references(self, var_dict, args): """Resolve variable references in a string This converts ${blah} within the string to the value of blah. @@ -455,12 +455,12 @@ class Toolchains: Returns: >>> bsettings.setup(None) >>> tcs = Toolchains() - >>> tcs.Add('fred', False) + >>> tcs.add('fred', False) >>> var_dict = {'oblique' : 'OBLIQUE', 'first' : 'fi${second}rst', \ 'second' : '2nd'} - >>> tcs.ResolveReferences(var_dict, 'this=${oblique}_set') + >>> tcs.resolve_references(var_dict, 'this=${oblique}_set') 'this=OBLIQUE_set' - >>> tcs.ResolveReferences(var_dict, 'this=${oblique}_set${first}nd') + >>> tcs.resolve_references(var_dict, 'this=${oblique}_set${first}nd') 'this=OBLIQUE_setfi2ndrstnd' """ re_var = re.compile(r'(\$\{[-_a-z0-9A-Z]{1,}\})') @@ -474,7 +474,7 @@ class Toolchains: args = args[:m.start(0)] + value + args[m.end(0):] return args - def GetMakeArguments(self, brd): + def get_make_arguments(self, brd): """Returns 'make' arguments for a given board The flags are in a section called 'make-flags'. Flags are named @@ -500,7 +500,7 @@ class Toolchains: 'make' flags for that board, or '' if none """ self._make_flags['target'] = brd.target - arg_str = self.ResolveReferences(self._make_flags, + arg_str = self.resolve_references(self._make_flags, self._make_flags.get(brd.target, '')) args = re.findall(r"(?:\".*?\"|\S)+", arg_str) i = 0 @@ -512,7 +512,7 @@ class Toolchains: i += 1 return args - def LocateArchUrl(self, fetch_arch): + def locate_arch_url(self, fetch_arch): """Find a toolchain available online Look in standard places for available toolchains. At present the @@ -548,7 +548,7 @@ class Toolchains: return arch, links return None - def Unpack(self, fname, dest): + def unpack(self, fname, dest): """Unpack a tar file Args: @@ -562,18 +562,18 @@ class Toolchains: dirs = stdout.splitlines()[1].split('/')[:2] return '/'.join(dirs) - def TestSettingsHasPath(self, path): + def test_settings_has_path(self, path): """Check if buildman will find this toolchain Returns: True if the path is in settings, False if not """ - paths = self.GetPathList(False) + paths = self.get_path_list(False) return path in paths - def ListArchs(self): + def list_archs(self): """List architectures with available toolchains to download""" - host_arch, archives = self.LocateArchUrl('list') + host_arch, archives = self.locate_arch_url('list') re_arch = re.compile('[-a-z0-9.]*[-_]([^-]*)-.*') arch_set = set() for archive in archives: @@ -584,7 +584,7 @@ class Toolchains: arch_set.add(arch.group(1)) return sorted(arch_set) - def FetchAndInstall(self, arch): + def fetch_and_install(self, arch): """Fetch and install a new toolchain arch: @@ -593,7 +593,7 @@ class Toolchains: # Fist get the URL for this architecture col = terminal.Color() print(col.build(col.BLUE, "Downloading toolchain for arch '%s'" % arch)) - url = self.LocateArchUrl(arch) + url = self.locate_arch_url(arch) if not url: print(("Cannot find toolchain for arch '%s' - use 'list' to list" % arch)) @@ -609,7 +609,7 @@ class Toolchains: return 1 print(col.build(col.GREEN, 'Unpacking to: %s' % dest), end=' ') sys.stdout.flush() - path = self.Unpack(tarfile, dest) + path = self.unpack(tarfile, dest) os.remove(tarfile) os.rmdir(tmpdir) print() @@ -617,7 +617,7 @@ class Toolchains: # Check that the toolchain works print(col.build(col.GREEN, 'Testing')) dirpath = os.path.join(dest, path) - compiler_fname_list = self.ScanPath(dirpath, True) + compiler_fname_list = self.scan_path(dirpath, True) if not compiler_fname_list: print('Could not locate C compiler - fetch failed.') return 1 @@ -627,7 +627,7 @@ class Toolchains: toolchain = Toolchain(compiler_fname_list[0], True, True) # Make sure that it will be found by buildman - if not self.TestSettingsHasPath(dirpath): + if not self.test_settings_has_path(dirpath): print(("Adding 'download' to config file '%s'" % bsettings.config_fname)) bsettings.set_item('toolchain', 'download', '%s/*/*' % dest) diff --git a/tools/qconfig.py b/tools/qconfig.py index eca6f5b1e1c..70d53b5f8d9 100755 --- a/tools/qconfig.py +++ b/tools/qconfig.py @@ -506,14 +506,14 @@ class Slot: arch = self.parser.get_arch() try: - tchain = self.toolchains.Select(arch) + tchain = self.toolchains.select(arch) except ValueError: self.log.append(self.col.build( self.col.YELLOW, f"Tool chain for '{arch}' is missing: do nothing")) self.finish(False) return - env = tchain.MakeEnvironment(False) + env = tchain.make_environment(False) cmd = list(self.make_cmd) cmd.append('KCONFIG_IGNORE_DUPLICATES=1') @@ -745,8 +745,8 @@ def move_config(args): # Get toolchains to use toolchains = toolchain.Toolchains() - toolchains.GetSettings() - toolchains.Scan(verbose=False) + toolchains.get_settings() + toolchains.scan(verbose=False) if args.git_ref: reference_src = ReferenceSource(args.git_ref) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add module docstring and class docstring for MyHTMLParser. Add type documentation to all function parameters and return values. Fix incorrect parameter names in docstrings (arch -> fetch_arch, args -> arch). Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/buildman/toolchain.py | 104 ++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 45 deletions(-) diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index 346bb349dfe..07adadffaaa 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ # Copyright (c) 2012 The Chromium OS Authors. -# + +"""Handles finding and using toolchains for building U-Boot.""" import re import glob @@ -20,8 +21,9 @@ from u_boot_pylib import tools (VAR_CROSS_COMPILE, VAR_PATH, VAR_ARCH, VAR_MAKE_ARGS) = range(4) -# Simple class to collect links from a page class MyHTMLParser(HTMLParser): + """Simple class to collect links from a page""" + def __init__(self, arch): """Create a new parser @@ -30,7 +32,7 @@ class MyHTMLParser(HTMLParser): the one for the given architecture (or None if not found). Args: - arch: Architecture to search for + arch (str): Architecture to search for """ HTMLParser.__init__(self) self.arch_link = None @@ -38,6 +40,7 @@ class MyHTMLParser(HTMLParser): self.re_arch = re.compile('[-_]%s-' % arch) def handle_starttag(self, tag, attrs): + """Handle a start tag in the HTML being parsed""" if tag == 'a': for tag, value in attrs: if tag == 'href': @@ -123,9 +126,10 @@ class Toolchain: filename prefix. Args: - fname: Filename of toolchain + fname (str): Filename of toolchain + Returns: - Priority of toolchain, PRIORITY_CALC=highest, 20=lowest. + int: Priority of toolchain, PRIORITY_CALC=highest, 20=lowest. """ priority_list = ['-elf', '-unknown-linux-gnu', '-linux', '-none-linux-gnueabi', '-none-linux-gnueabihf', '-uclinux', @@ -152,10 +156,10 @@ class Toolchain: """Get an environment variable/args value based on the the toolchain Args: - which: VAR_... value to get + which (int): VAR_... value to get Returns: - Value of that environment variable or arguments + str: Value of that environment variable or arguments """ if which == VAR_CROSS_COMPILE: wrapper = self.get_wrapper() @@ -196,13 +200,14 @@ class Toolchain: buildman will still respect the venv. Args: - full_path: Return the full path in CROSS_COMPILE and don't set - PATH + full_path (bool): Return the full path in CROSS_COMPILE and don't + set PATH env (dict of bytes): Original environment, used for testing + Returns: - Dict containing the (bytes) environment to use. This is based on the - current environment, with changes as needed to CROSS_COMPILE, PATH - and LC_ALL. + dict of bytes: Environment to use. This is based on the current + environment, with changes as needed to CROSS_COMPILE, PATH + and LC_ALL. """ env = dict(env or os.environb) @@ -281,11 +286,12 @@ class Toolchains: """Get a list of available toolchain paths Args: - show_warning: True to show a warning if there are no tool chains. + show_warning (bool): True to show a warning if there are no tool + chains. Returns: - List of strings, each a path to a toolchain mentioned in the - [toolchain] section of the settings file. + list of str: List of paths to toolchains mentioned in the + [toolchain] section of the settings file. """ toolchains = bsettings.get_items('toolchain') if show_warning and not toolchains: @@ -308,7 +314,8 @@ class Toolchains: """Get toolchain settings from the settings file. Args: - show_warning: True to show a warning if there are no tool chains. + show_warning (bool): True to show a warning if there are no tool + chains. """ self.prefixes = bsettings.get_items('toolchain-prefix') self.paths += self.get_path_list(show_warning) @@ -321,10 +328,11 @@ class Toolchains: architecture if it is a higher priority than the others. Args: - fname: Filename of toolchain's gcc driver - test: True to run the toolchain to test it - priority: Priority to use for this toolchain - arch: Toolchain architecture, or None if not known + fname (str): Filename of toolchain's gcc driver + test (bool): True to run the toolchain to test it + verbose (bool): True to print out progress information + priority (int): Priority to use for this toolchain + arch (str): Toolchain architecture, or None if not known """ toolchain = Toolchain(fname, test, verbose, priority, arch, self.override_toolchain) @@ -345,10 +353,11 @@ class Toolchains: """Scan a path for a valid toolchain Args: - path: Path to scan - verbose: True to print out progress information + path (str): Path to scan + verbose (bool): True to print out progress information + Returns: - Filename of C compiler if found, else None + list of str: Filenames of C compilers found """ fnames = [] for subdir in ['.', 'bin', 'usr/bin']: @@ -363,9 +372,10 @@ class Toolchains: """Scan the PATH environment variable for a given filename. Args: - fname: Filename to scan for + fname (str): Filename to scan for + Returns: - List of matching pathanames, or [] if none + list of str: List of matching pathnames, or [] if none """ pathname_list = [] for path in os.environ["PATH"].split(os.pathsep): @@ -383,7 +393,9 @@ class Toolchains: highest priority toolchain for each arch. Args: - verbose: True to print out progress information + verbose (bool): True to print out progress information + raise_on_error (bool): True to raise an error if a toolchain is + not found """ if verbose: print('Scanning for tool chains') for name, value in self.prefixes: @@ -426,10 +438,10 @@ class Toolchains: """Returns the toolchain for a given architecture Args: - args: Name of architecture (e.g. 'arm', 'ppc_8xx') + arch (str): Name of architecture (e.g. 'arm', 'ppc_8xx') - returns: - toolchain object, or None if none found + Returns: + Toolchain: toolchain object, or None if none found """ for tag, value in bsettings.get_items('toolchain-alias'): if arch == tag: @@ -447,12 +459,13 @@ class Toolchains: This converts ${blah} within the string to the value of blah. This function works recursively. - Resolved string - Args: - var_dict: Dictionary containing variables and their values - args: String containing make arguments + var_dict (dict): Dictionary containing variables and their values + args (str): String containing make arguments + Returns: + str: Resolved string + >>> bsettings.setup(None) >>> tcs = Toolchains() >>> tcs.add('fred', False) @@ -495,9 +508,10 @@ class Toolchains: A special 'target' variable is set to the board target. Args: - brd: Board object for the board to check. + brd (Board): Board object for the board to check. + Returns: - 'make' flags for that board, or '' if none + list of str: 'make' flags for that board, or [] if none """ self._make_flags['target'] = brd.target arg_str = self.resolve_references(self._make_flags, @@ -519,13 +533,12 @@ class Toolchains: only standard place is at kernel.org. Args: - arch: Architecture to look for, or 'list' for all + fetch_arch (str): Architecture to look for, or 'list' for all + Returns: - If fetch_arch is 'list', a tuple: - Machine architecture (e.g. x86_64) - List of toolchains - else - URL containing this toolchain, if avaialble, else None + tuple or str or None: If fetch_arch is 'list', a tuple of + (machine architecture, list of toolchains). Otherwise the + URL containing this toolchain, if available, else None. """ arch = command.output_one_line('uname', '-m') if arch == 'aarch64': @@ -552,11 +565,12 @@ class Toolchains: """Unpack a tar file Args: - fname: Filename to unpack - dest: Destination directory + fname (str): Filename to unpack + dest (str): Destination directory + Returns: - Directory name of the first entry in the archive, without the - trailing / + str: Directory name of the first entry in the archive, without + the trailing / """ stdout = command.output('tar', 'xvfJ', fname, '-C', dest) dirs = stdout.splitlines()[1].split('/')[:2] -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The re_arch member is only used internally by handle_starttag(), so rename it to _re_arch to indicate it's private. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/buildman/toolchain.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index 07adadffaaa..68fea72bf6c 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -22,7 +22,13 @@ from u_boot_pylib import tools (VAR_CROSS_COMPILE, VAR_PATH, VAR_ARCH, VAR_MAKE_ARGS) = range(4) class MyHTMLParser(HTMLParser): - """Simple class to collect links from a page""" + """Simple class to collect links from a page + + Public members: + arch_link (str): URL of the toolchain for the desired architecture, + or None if not found + links (list of str): List of URLs for all .xz archives found + """ def __init__(self, arch): """Create a new parser @@ -37,7 +43,7 @@ class MyHTMLParser(HTMLParser): HTMLParser.__init__(self) self.arch_link = None self.links = [] - self.re_arch = re.compile('[-_]%s-' % arch) + self._re_arch = re.compile('[-_]%s-' % arch) def handle_starttag(self, tag, attrs): """Handle a start tag in the HTML being parsed""" @@ -46,7 +52,7 @@ class MyHTMLParser(HTMLParser): if tag == 'href': if value and value.endswith('.xz'): self.links.append(value) - if self.re_arch.search(value): + if self._re_arch.search(value): self.arch_link = value -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add missing 'ok' member to the class docstring and add type annotations to all documented members. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/buildman/toolchain.py | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index 68fea72bf6c..7ccb56a74aa 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -60,25 +60,30 @@ class Toolchain: """A single toolchain Public members: - gcc: Full path to C compiler - path: Directory path containing C compiler - cross: Cross compile string, e.g. 'arm-linux-' - arch: Architecture of toolchain as determined from the first - component of the filename. E.g. arm-linux-gcc becomes arm - priority: Toolchain priority (0=highest, 20=lowest) - override_toolchain: Toolchain to use for sandbox, overriding the normal - one + gcc (str): Full path to C compiler + path (str): Directory path containing C compiler + cross (str): Cross compile string, e.g. 'arm-linux-' + arch (str): Architecture of toolchain as determined from the first + component of the filename. E.g. arm-linux-gcc becomes arm + priority (int): Toolchain priority (0=highest, 20=lowest) + override_toolchain (str): Toolchain to use for sandbox, overriding the + normal one + ok (bool): True if the toolchain works, False otherwise """ def __init__(self, fname, test, verbose=False, priority=PRIORITY_CALC, arch=None, override_toolchain=None): """Create a new toolchain object. Args: - fname: Filename of the gcc component, possibly with ~ or $HOME in it - test: True to run the toolchain to test it - verbose: True to print out the information - priority: Priority to use for this toolchain, or PRIORITY_CALC to - calculate it + fname (str): Filename of the gcc component, possibly with ~ or + $HOME in it + test (bool): True to run the toolchain to test it + verbose (bool): True to print out the information + priority (int): Priority to use for this toolchain, or + PRIORITY_CALC to calculate it + arch (str): Architecture of toolchain, or None to detect from + filename + override_toolchain (str): Toolchain to use for sandbox, or None """ fname = os.path.expanduser(fname) self.gcc = fname -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Replace all string formatting with f-strings for better readability and consistency with modern Python style. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/buildman/toolchain.py | 69 +++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index 7ccb56a74aa..90f56813300 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -43,7 +43,7 @@ class MyHTMLParser(HTMLParser): HTMLParser.__init__(self) self.arch_link = None self.links = [] - self._re_arch = re.compile('[-_]%s-' % arch) + self._re_arch = re.compile(f'[-_]{arch}-') def handle_starttag(self, tag, attrs): """Handle a start tag in the HTML being parsed""" @@ -120,8 +120,7 @@ class Toolchain: if verbose: print('Tool chain test: ', end=' ') if self.ok: - print("OK, arch='%s', priority %d" % (self.arch, - self.priority)) + print(f"OK, arch='{self.arch}', priority {self.priority}") else: print('BAD') print(f"Command: {' '.join(cmd)}") @@ -188,7 +187,7 @@ class Toolchain: return ' '.join(args) return '' else: - raise ValueError('Unknown arg to GetEnvArgs (%d)' % which) + raise ValueError(f'Unknown arg to GetEnvArgs ({which})') def make_environment(self, full_path, env=None): """Returns an environment for using the toolchain. @@ -266,8 +265,8 @@ class Toolchain: List of arguments to pass to 'make' """ if self.override_toolchain: - return ['HOSTCC=%s' % self.override_toolchain, - 'CC=%s' % self.override_toolchain] + return [f'HOSTCC={self.override_toolchain}', + f'CC={self.override_toolchain}'] return [] @@ -306,11 +305,10 @@ class Toolchains: """ toolchains = bsettings.get_items('toolchain') if show_warning and not toolchains: - print(("Warning: No tool chains. Please run 'buildman " - "--fetch-arch all' to download all available toolchains, or " - "add a [toolchain] section to your buildman config file " - "%s. See buildman.rst for details" % - bsettings.config_fname)) + print(f"Warning: No tool chains. Please run 'buildman " + f"--fetch-arch all' to download all available toolchains, or " + f"add a [toolchain] section to your buildman config file " + f"{bsettings.config_fname}. See buildman.rst for details") paths = [] for name, value in toolchains: @@ -355,10 +353,10 @@ class Toolchains: if add_it: self.toolchains[toolchain.arch] = toolchain elif verbose: - print(("Toolchain '%s' at priority %d will be ignored because " - "another toolchain for arch '%s' has priority %d" % - (toolchain.gcc, toolchain.priority, toolchain.arch, - self.toolchains[toolchain.arch].priority))) + print(f"Toolchain '{toolchain.gcc}' at priority " + f"{toolchain.priority} will be ignored because another " + f"toolchain for arch '{toolchain.arch}' has priority " + f"{self.toolchains[toolchain.arch].priority}") def scan_path(self, path, verbose): """Scan a path for a valid toolchain @@ -373,9 +371,9 @@ class Toolchains: fnames = [] for subdir in ['.', 'bin', 'usr/bin']: dirname = os.path.join(path, subdir) - if verbose: print(" - looking in '%s'" % dirname) + if verbose: print(f" - looking in '{dirname}'") for fname in glob.glob(dirname + '/*gcc'): - if verbose: print(" - found '%s'" % fname) + if verbose: print(f" - found '{fname}'") fnames.append(fname) return fnames @@ -411,7 +409,8 @@ class Toolchains: if verbose: print('Scanning for tool chains') for name, value in self.prefixes: fname = os.path.expanduser(value) - if verbose: print(" - scanning prefix '%s'" % fname) + if verbose: + print(f" - scanning prefix '{fname}'") if os.path.exists(fname): self.add(fname, True, verbose, PRIORITY_FULL_PREFIX, name) continue @@ -429,7 +428,7 @@ class Toolchains: else: print(f'Error: {msg}') for path in self.paths: - if verbose: print(" - scanning path '%s'" % path) + if verbose: print(f" - scanning path '{path}'") fnames = self.scan_path(path, verbose) for fname in fnames: self.add(fname, True, verbose) @@ -437,11 +436,12 @@ class Toolchains: def list(self): """List out the selected toolchains for each architecture""" col = terminal.Color() - print(col.build(col.BLUE, 'List of available toolchains (%d):' % - len(self.toolchains))) + print(col.build( + col.BLUE, + f'List of available toolchains ({len(self.toolchains)}):')) if len(self.toolchains): for key, value in sorted(self.toolchains.items()): - print('%-10s: %s' % (key, value.gcc)) + print(f'{key:10}: {value.gcc}') else: print('None') @@ -461,7 +461,7 @@ class Toolchains: return self.toolchains[alias] if not arch in self.toolchains: - raise ValueError("No tool chain found for arch '%s'" % arch) + raise ValueError(f"No tool chain found for arch '{arch}'") return self.toolchains[arch] def resolve_references(self, var_dict, args): @@ -558,8 +558,8 @@ class Toolchains: versions = ['14.2.0', '13.2.0'] links = [] for version in versions: - url = '%s/%s/%s/' % (base, arch, version) - print('Checking: %s' % url) + url = f'{base}/{arch}/{version}/' + print(f'Checking: {url}') response = urllib.request.urlopen(url) html = tools.to_string(response.read()) parser = MyHTMLParser(fetch_arch) @@ -617,11 +617,11 @@ class Toolchains: """ # Fist get the URL for this architecture col = terminal.Color() - print(col.build(col.BLUE, "Downloading toolchain for arch '%s'" % arch)) + print(col.build(col.BLUE, f"Downloading toolchain for arch '{arch}'")) url = self.locate_arch_url(arch) if not url: - print(("Cannot find toolchain for arch '%s' - use 'list' to list" % - arch)) + print(f"Cannot find toolchain for arch '{arch}' - " + "use 'list' to list") return 2 home = os.environ['HOME'] dest = os.path.join(home, '.buildman-toolchains') @@ -632,7 +632,7 @@ class Toolchains: tarfile, tmpdir = tools.download(url, '.buildman') if not tarfile: return 1 - print(col.build(col.GREEN, 'Unpacking to: %s' % dest), end=' ') + print(col.build(col.GREEN, f'Unpacking to: {dest}'), end=' ') sys.stdout.flush() path = self.unpack(tarfile, dest) os.remove(tarfile) @@ -647,13 +647,14 @@ class Toolchains: print('Could not locate C compiler - fetch failed.') return 1 if len(compiler_fname_list) != 1: - print(col.build(col.RED, 'Warning, ambiguous toolchains: %s' % - ', '.join(compiler_fname_list))) + print(col.build(col.RED, + f"Warning, ambiguous toolchains: " + f"{', '.join(compiler_fname_list)}")) toolchain = Toolchain(compiler_fname_list[0], True, True) # Make sure that it will be found by buildman if not self.test_settings_has_path(dirpath): - print(("Adding 'download' to config file '%s'" % - bsettings.config_fname)) - bsettings.set_item('toolchain', 'download', '%s/*/*' % dest) + print(f"Adding 'download' to config file " + f"'{bsettings.config_fname}'") + bsettings.set_item('toolchain', 'download', f'{dest}/*/*') return 0 -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Fix various pylint warnings: - Remove unused import tempfile - Split urllib imports onto separate lines - Rename loop variable 'tag' to 'attr' to avoid redefining argument - Use enumerate instead of range(len()) - Remove unused show_warning parameter from get_wrapper() - Prefix unused loop variables with underscore - Remove unnecessary elif/else after return/raise statements - Split multiple statements on single lines - Use 'with' for urllib.request.urlopen resource management - Add pylint disable comments for functions with many arguments This brings toolchain.py to pylint 10.00/10. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/buildman/toolchain.py | 64 ++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index 90f56813300..8ec1dbdebba 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -8,8 +8,9 @@ import glob from html.parser import HTMLParser import os import sys -import tempfile -import urllib.request, urllib.error, urllib.parse +import urllib.error +import urllib.parse +import urllib.request from buildman import bsettings from u_boot_pylib import command @@ -48,8 +49,8 @@ class MyHTMLParser(HTMLParser): def handle_starttag(self, tag, attrs): """Handle a start tag in the HTML being parsed""" if tag == 'a': - for tag, value in attrs: - if tag == 'href': + for attr, value in attrs: + if attr == 'href': if value and value.endswith('.xz'): self.links.append(value) if self._re_arch.search(value): @@ -70,6 +71,7 @@ class Toolchain: normal one ok (bool): True if the toolchain works, False otherwise """ + # pylint: disable=too-many-arguments,too-many-positional-arguments def __init__(self, fname, test, verbose=False, priority=PRIORITY_CALC, arch=None, override_toolchain=None): """Create a new toolchain object. @@ -145,16 +147,16 @@ class Toolchain: '-none-linux-gnueabi', '-none-linux-gnueabihf', '-uclinux', '-none-eabi', '-gentoo-linux-gnu', '-linux-gnueabi', '-linux-gnueabihf', '-le-linux', '-uclinux'] - for prio in range(len(priority_list)): - if priority_list[prio] in fname: + for prio, item in enumerate(priority_list): + if item in fname: return PRIORITY_CALC + prio return PRIORITY_CALC + prio - def get_wrapper(self, show_warning=True): + def get_wrapper(self): """Get toolchain wrapper from the setting file. """ value = '' - for name, value in bsettings.get_items('toolchain-wrapper'): + for _, value in bsettings.get_items('toolchain-wrapper'): if not value: print("Warning: Wrapper not found") if value: @@ -177,17 +179,16 @@ class Toolchain: if (base == '' and self.cross == ''): return '' return wrapper + os.path.join(base, self.cross) - elif which == VAR_PATH: + if which == VAR_PATH: return self.path - elif which == VAR_ARCH: + if which == VAR_ARCH: return self.arch - elif which == VAR_MAKE_ARGS: + if which == VAR_MAKE_ARGS: args = self.make_args() if args: return ' '.join(args) return '' - else: - raise ValueError(f'Unknown arg to GetEnvArgs ({which})') + raise ValueError(f'Unknown arg to GetEnvArgs ({which})') def make_environment(self, full_path, env=None): """Returns an environment for using the toolchain. @@ -311,7 +312,7 @@ class Toolchains: f"{bsettings.config_fname}. See buildman.rst for details") paths = [] - for name, value in toolchains: + for _, value in toolchains: fname = os.path.expanduser(value) if '*' in value: paths += glob.glob(fname) @@ -329,6 +330,7 @@ class Toolchains: self.prefixes = bsettings.get_items('toolchain-prefix') self.paths += self.get_path_list(show_warning) + # pylint: disable=too-many-arguments,too-many-positional-arguments def add(self, fname, test=True, verbose=False, priority=PRIORITY_CALC, arch=None): """Add a toolchain to our list @@ -371,9 +373,11 @@ class Toolchains: fnames = [] for subdir in ['.', 'bin', 'usr/bin']: dirname = os.path.join(path, subdir) - if verbose: print(f" - looking in '{dirname}'") + if verbose: + print(f" - looking in '{dirname}'") for fname in glob.glob(dirname + '/*gcc'): - if verbose: print(f" - found '{fname}'") + if verbose: + print(f" - found '{fname}'") fnames.append(fname) return fnames @@ -406,7 +410,8 @@ class Toolchains: raise_on_error (bool): True to raise an error if a toolchain is not found """ - if verbose: print('Scanning for tool chains') + if verbose: + print('Scanning for tool chains') for name, value in self.prefixes: fname = os.path.expanduser(value) if verbose: @@ -425,10 +430,10 @@ class Toolchains: msg = f"No tool chain found for prefix '{fname}'" if raise_on_error: raise ValueError(msg) - else: - print(f'Error: {msg}') + print(f'Error: {msg}') for path in self.paths: - if verbose: print(f" - scanning path '{path}'") + if verbose: + print(f" - scanning path '{path}'") fnames = self.scan_path(path, verbose) for fname in fnames: self.add(fname, True, verbose) @@ -560,14 +565,14 @@ class Toolchains: for version in versions: url = f'{base}/{arch}/{version}/' print(f'Checking: {url}') - response = urllib.request.urlopen(url) - html = tools.to_string(response.read()) - parser = MyHTMLParser(fetch_arch) - parser.feed(html) - if fetch_arch == 'list': - links += parser.links - elif parser.arch_link: - return url + parser.arch_link + with urllib.request.urlopen(url) as response: + html = tools.to_string(response.read()) + parser = MyHTMLParser(fetch_arch) + parser.feed(html) + if fetch_arch == 'list': + links += parser.links + elif parser.arch_link: + return url + parser.arch_link if fetch_arch == 'list': return arch, links return None @@ -650,7 +655,8 @@ class Toolchains: print(col.build(col.RED, f"Warning, ambiguous toolchains: " f"{', '.join(compiler_fname_list)}")) - toolchain = Toolchain(compiler_fname_list[0], True, True) + # Instantiate to verify the toolchain works + Toolchain(compiler_fname_list[0], True, True) # Make sure that it will be found by buildman if not self.test_settings_has_path(dirpath): -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Fix various pylint warnings: - Shorten long lines to fit within 80 characters - Replace unused variables with underscore (_) - Add pylint disable comment for too-many-public-methods - Add pylint disable comment for protected-access (needed to test cleanup of internal _tmpfile) This brings test_boards.py to pylint 10.00/10. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- tools/buildman/test_boards.py | 72 +++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/tools/buildman/test_boards.py b/tools/buildman/test_boards.py index 66eb82bc755..0cb1f072543 100644 --- a/tools/buildman/test_boards.py +++ b/tools/buildman/test_boards.py @@ -22,13 +22,16 @@ from u_boot_pylib import tools BOARDS = [ - ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 0', 'board0', ''], + ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 0', 'board0', ''], ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 1', 'board1', ''], - ['Active', 'powerpc', 'powerpc', '', 'Tester', 'PowerPC board 1', 'board2', ''], - ['Active', 'sandbox', 'sandbox', '', 'Tester', 'Sandbox board', 'board4', ''], + ['Active', 'powerpc', 'powerpc', '', 'Tester', 'PowerPC board 1', + 'board2', ''], + ['Active', 'sandbox', 'sandbox', '', 'Tester', 'Sandbox board', + 'board4', ''], ] +# pylint: disable=too-many-public-methods class TestBoards(unittest.TestCase): """Test boards.py functionality""" @@ -71,8 +74,8 @@ class TestBoards(unittest.TestCase): # Test normal boards.cfg file boards_cfg = os.path.join(self._base_dir, 'boards.cfg') content = '''# Comment line -Active arm armv7 - Tester ARM_Board_0 board0 config0 maint@test.com -Active powerpc ppc mpc85xx Tester PPC_Board_1 board2 config2 maint2@test.com +Active arm armv7 - Tester ARM0 board0 config0 m@t.co +Active powerpc ppc mpc85xx Tester PPC1 board2 config2 m@t.co ''' tools.write_file(boards_cfg, content.encode('utf-8')) @@ -97,15 +100,15 @@ Active powerpc ppc mpc85xx Tester PPC_Board_1 board2 config2 maint2@t # Test with more than 8 fields (extra fields ignored) boards_cfg = os.path.join(self._base_dir, 'boards_extra.cfg') - content = '''Active arm armv7 soc Tester Board target config maint extra -''' + content = ('Active arm armv7 soc Tester Board target ' + 'config maint extra\n') tools.write_file(boards_cfg, content.encode('utf-8')) brds = boards.Boards() brds.read_boards(boards_cfg) self.assertEqual('config', brds.get_list()[0].cfg_name) def test_boards_methods(self): - """Test Boards helper methods: get_dict, get_selected_names, find_by_target""" + """Test Boards helper methods""" brds = boards.Boards() for brd in BOARDS: brds.add_board(board.Board(*brd)) @@ -124,7 +127,8 @@ Active powerpc ppc mpc85xx Tester PPC_Board_1 board2 config2 maint2@t brds2 = boards.Boards() for brd in BOARDS: brds2.add_board(board.Board(*brd)) - result, warnings = brds2.select_boards([], brds=['nonexistent', 'board0']) + _, warnings = brds2.select_boards([], + brds=['nonexistent', 'board0']) self.assertEqual(1, len(warnings)) self.assertIn('nonexistent', warnings[0]) @@ -132,7 +136,7 @@ Active powerpc ppc mpc85xx Tester PPC_Board_1 board2 config2 maint2@t found = brds.find_by_target('board0') self.assertEqual('arm', found.arch) - with terminal.capture() as (stdout, stderr): + with terminal.capture(): with self.assertRaises(ValueError) as exc: brds.find_by_target('nonexistent') self.assertIn('nonexistent', str(exc.exception)) @@ -181,7 +185,7 @@ endif tools.write_file(defconfig, 'CONFIG_TARGET_RISCV_BOARD=y\n', False) # Test riscv64 (no RV32I) - res, warnings = scanner.scan(defconfig, False) + res, _ = scanner.scan(defconfig, False) self.assertEqual('riscv64', res['arch']) # Test riscv32 (with RV32I) @@ -191,7 +195,7 @@ config ARCH_RV32I ''' tools.write_file(kc_file, riscv32_kconfig) scanner = boards.KconfigScanner(src) - res, warnings = scanner.scan(defconfig, False) + res, _ = scanner.scan(defconfig, False) self.assertEqual('riscv32', res['arch']) finally: tools.write_file(kc_file, orig_kc_data) @@ -207,7 +211,7 @@ config ARCH_RV32I tools.write_file(main, new_data, binary=False) try: - params_list, warnings = self._boards.build_board_list(config_dir, src) + params_list, _ = self._boards.build_board_list(config_dir, src) self.assertEqual(2, len(params_list)) finally: tools.write_file(main, orig_data, binary=False) @@ -218,22 +222,22 @@ config ARCH_RV32I brds = boards.Boards() # Test force=False, quiet=False (normal generation) - with terminal.capture() as (stdout, stderr): + with terminal.capture(): brds.ensure_board_list(outfile, jobs=1, force=False, quiet=False) self.assertTrue(os.path.exists(outfile)) # Test force=True (regenerate even if current) - with terminal.capture() as (stdout, stderr): + with terminal.capture() as (stdout, _): brds.ensure_board_list(outfile, jobs=1, force=True, quiet=False) self.assertTrue(os.path.exists(outfile)) # Test quiet=True (minimal output) - with terminal.capture() as (stdout, stderr): + with terminal.capture() as (stdout, _): brds.ensure_board_list(outfile, jobs=1, force=False, quiet=True) self.assertNotIn('Checking', stdout.getvalue()) # Test quiet=True when up to date (no output) - with terminal.capture() as (stdout, stderr): + with terminal.capture() as (stdout, _): result = brds.ensure_board_list(outfile, jobs=1, force=False, quiet=True) self.assertTrue(result) @@ -297,7 +301,7 @@ Active arm armv7 - Tester Board board0 options maint tools.write_file(defconfig, 'CONFIG_SYS_ARCH="arm"\n', False) try: scanner = boards.KconfigScanner(src) - res, warnings = scanner.scan(defconfig, warn_targets=True) + _, warnings = scanner.scan(defconfig, warn_targets=True) self.assertEqual(1, len(warnings)) self.assertIn('No TARGET_NO_TARGET enabled', warnings[0]) finally: @@ -314,7 +318,7 @@ config TARGET_BOARD0_DUP try: scanner = boards.KconfigScanner(src) defconfig = os.path.join(src, 'configs', 'board0_defconfig') - res, warnings = scanner.scan(defconfig, warn_targets=True) + _, warnings = scanner.scan(defconfig, warn_targets=True) self.assertEqual(1, len(warnings)) self.assertIn('Duplicate TARGET_xxx', warnings[0]) finally: @@ -332,7 +336,8 @@ config TARGET_BOARD0_DUP targets=[['CONFIG_ARM', 'y']]) with mock.patch('qconfig.find_config') as mock_find, \ - mock.patch.object(tools, 'read_file', return_value='CONFIG_TEST=y'): + mock.patch.object(tools, 'read_file', + return_value='CONFIG_TEST=y'): mock_find.return_value = {'board0', 'board1'} result = brds.scan_extended(None, ext) self.assertEqual({'board0', 'board1'}, result) @@ -380,7 +385,7 @@ config TARGET_BOARD0_DUP 'configs/board2_defconfig'] mock_find.return_value = {'board0', 'board1', 'board2'} result = brds.scan_extended(None, ext) - # Should be intersection: {board0, board2} & {board0, board1, board2} + # Result is intersection of regex and find_config results self.assertEqual({'board0', 'board2'}, result) def test_parse_extended(self): @@ -479,7 +484,7 @@ Active arm armv7 - Tester Board board0 config0 maint # Simulate a leftover temp file tmpfile = os.path.join(self._base_dir, 'leftover.tmp') tools.write_file(tmpfile, b'temp') - scanner._tmpfile = tmpfile + scanner._tmpfile = tmpfile # pylint: disable=protected-access # Delete the scanner - should clean up the temp file del scanner @@ -520,8 +525,9 @@ endif try: scanner = boards.KconfigScanner(src) defconfig = os.path.join(src, 'aarch64_defconfig') - tools.write_file(defconfig, 'CONFIG_TARGET_AARCH64_BOARD=y\n', False) - res, warnings = scanner.scan(defconfig, False) + tools.write_file(defconfig, + 'CONFIG_TARGET_AARCH64_BOARD=y\n', False) + res, _ = scanner.scan(defconfig, False) # Should be fixed up to aarch64 self.assertEqual('aarch64', res['arch']) finally: @@ -550,11 +556,11 @@ endif brds = boards.Boards() # First generate the file - with terminal.capture() as (stdout, stderr): + with terminal.capture(): brds.ensure_board_list(outfile, jobs=1, force=False, quiet=False) # Run again - should say "up to date" - with terminal.capture() as (stdout, stderr): + with terminal.capture() as (stdout, _): result = brds.ensure_board_list(outfile, jobs=1, force=False, quiet=False) self.assertTrue(result) @@ -568,7 +574,7 @@ endif # Mock build_board_list to return warnings with mock.patch.object(brds, 'build_board_list') as mock_build: mock_build.return_value = ([], ['WARNING: test warning']) - with terminal.capture() as (stdout, stderr): + with terminal.capture() as (_, stderr): result = brds.ensure_board_list(outfile, jobs=1, force=True, quiet=False) self.assertFalse(result) @@ -601,7 +607,7 @@ endif with mock.patch('qconfig.find_config') as mock_find, \ mock.patch.object(tools, 'read_file', return_value=''), \ mock.patch('glob.glob') as mock_glob, \ - terminal.capture() as (stdout, stderr): + terminal.capture() as (stdout, _): mock_glob.return_value = [] # No matches mock_find.return_value = set() result = brds.scan_extended(None, ext) @@ -652,7 +658,7 @@ endif tools.write_file(defconfig, 'CONFIG_TARGET_RISCV_TEST=y\n', False) scanner = boards.KconfigScanner(src) - res, warnings = scanner.scan(defconfig, False) + res, _ = scanner.scan(defconfig, False) # Should default to riscv64 when ARCH_RV32I lookup fails self.assertEqual('riscv64', res['arch']) @@ -676,7 +682,7 @@ endif # Get the result from the queue result = queue.get(timeout=5) - params, warnings = result + params, _ = result self.assertEqual('board0', params['target']) self.assertEqual('arm', params['arch']) @@ -691,7 +697,7 @@ endif try: brds = boards.Boards() - params_list, warnings = brds.scan_defconfigs(config_dir, src, 1) + params_list, _ = brds.scan_defconfigs(config_dir, src, 1) # Hidden file should not be in results targets = [p['target'] for p in params_list] @@ -716,8 +722,8 @@ N: .* # Mock os.walk to return a path that doesn't start with 'configs/' # when walking the configs directory. This tests line 443. - def mock_walk(path): - # Return paths with 'configs/' prefix (normal) and without (edge case) + def mock_walk(_path): + # Return paths with and without 'configs/' prefix yield (os.path.join(src, 'configs'), [], ['board0_defconfig']) # This path will have 'other/' prefix after srcdir removal yield (os.path.join(src, 'other'), [], ['fred_defconfig']) -- 2.43.0
participants (1)
-
Simon Glass