From a6429b9ff0995ab9b3052112e11485eb49dac5c0 Mon Sep 17 00:00:00 2001 From: Cristian Maureira-Fredes Date: Thu, 31 Dec 2020 03:22:06 +0100 Subject: testing: use f-strings Change-Id: I55a614b5cabe9b3dcc45de17e7a22c47ae0e643d Reviewed-by: Christian Tismer Reviewed-by: Friedemann Kleint Reviewed-by: Qt CI Bot (cherry picked from commit 8c1b6d88c19633a7373c052a2af3f584ad2114f7) Reviewed-by: Qt Cherry-pick Bot --- testing/buildlog.py | 13 +++++------ testing/command.py | 62 +++++++++++++++++++++++-------------------------- testing/parser.py | 4 ++-- testing/runner.py | 39 ++++++++++++++----------------- testing/wheel_tester.py | 49 +++++++++++++++++++------------------- 5 files changed, 79 insertions(+), 88 deletions(-) diff --git a/testing/buildlog.py b/testing/buildlog.py index d9e960418..4e41cbaf5 100644 --- a/testing/buildlog.py +++ b/testing/buildlog.py @@ -86,10 +86,10 @@ class BuildLog(object): build_dir = f_contents_split[0] build_classifiers = "" except IndexError: - print(dedent(""" + print(dedent(f""" Error: There was an issue finding the build dir and its - characteristics, in the following considered file: '{}' - """.format(fpath))) + characteristics, in the following considered file: '{fpath}' + """)) sys.exit(1) if not os.path.exists(build_dir): @@ -100,7 +100,7 @@ class BuildLog(object): if os.path.exists(build_dir): print("Note: build_dir was probably moved.") else: - print("Warning: missing build dir %s" % build_dir) + print(f"Warning: missing build dir {build_dir}") continue entry = LogEntry(log_dir, build_dir, build_classifiers) build_history.append(entry) @@ -122,9 +122,8 @@ class BuildLog(object): if lst: def warn_problem(func, path, exc_info): cls, ins, _ = exc_info - print("rmtree({}) warning: problem with {}:\n {}: {}".format( - func.__name__, path, - cls.__name__, ins.args)) + print(f"rmtree({func.__name__}) warning: problem with " + f"{path}:\n {cls.__name__}: {ins.args}") lst.sort() log_dir = lst[-1] diff --git a/testing/command.py b/testing/command.py index 499ecaab7..5c4f58eca 100644 --- a/testing/command.py +++ b/testing/command.py @@ -108,7 +108,7 @@ def test_project(project, args, blacklist, runs): index = idx + 1 runner = TestRunner(builds.selected, project, index) print() - print("********* Start testing of %s *********" % project) + print(f"********* Start testing of {project} *********") print("Config: Using", " ".join(builds.classifiers)) print() if os.path.exists(runner.logfile) and args.skip: @@ -117,12 +117,11 @@ def test_project(project, args, blacklist, runs): if index > 1 and COIN_RERUN_FAILED_ONLY: rerun = rerun_list if not rerun: - print("--- no re-runs found, stopping before test {} ---" - .format(index)) + print(f"--- no re-runs found, stopping before test {index} ---") break else: rerun = None - runner.run("RUN {}:".format(idx + 1), rerun, 10 * 60) + runner.run(f"RUN {idx + 1}:", rerun, 10 * 60) results = TestParser(runner.logfile) r = 5 * [0] rerun_list = [] @@ -130,7 +129,7 @@ def test_project(project, args, blacklist, runs): fatal = False for item in results.iter_blacklist(blacklist): res = item.rich_result - sharp = "#" + str(item.sharp) + sharp = f"#{item.sharp}" mod_name = decorate(item.mod_name) print(f"RES {index}: Test {sharp:>4}: {res:<6} {mod_name}()") r[0] += 1 if res == "PASS" else 0 @@ -144,9 +143,8 @@ def test_project(project, args, blacklist, runs): if item.fatal: fatal = item print() - print("Totals:", sum(r), "tests.", - "{} passed, {} failed, {} skipped, {} blacklisted, {} bpassed." - .format(*r)) + print(f"Totals: {sum(r)} tests. " + f"{r[0]} passed, {r[1]} failed, {r[2]} skipped, {r[3]} blacklisted, {r[4]} bpassed.") print() print(f"********* Finished testing of {project} *********") print() @@ -163,16 +161,17 @@ def main(): start_time = timer() all_projects = "shiboken6 pyside6".split() tested_projects = "shiboken6 pyside6".split() + tested_projects_quoted = " ".join("'i'" for i in tested_projects) parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=dedent("""\ - Run the tests for some projects, default = '{}'. + Run the tests for some projects, default = {tested_projects_quoted}. - Testing is now repeated up to {rep} times, and errors are - only reported if they occur {thr} or more times. + Testing is now repeated up to {COIN_TESTING} times, and errors are + only reported if they occur {COIN_THRESHOLD} or more times. The environment variable COIN_RERUN_FAILED_ONLY controls if errors are only repeated if there are errors. The default is "1". - """.format("' '".join(tested_projects), thr=COIN_THRESHOLD, rep=COIN_TESTING))) + """)) subparsers = parser.add_subparsers(dest="subparser_name") # create the parser for the "test" command @@ -181,7 +180,7 @@ def main(): blacklist_default = os.path.join(script_dir, 'build_history', 'blacklist.txt') group.add_argument("--blacklist", "-b", type=argparse.FileType('r'), default=blacklist_default, - help='a Qt blacklist file (default: {})'.format(blacklist_default)) + help=f'a Qt blacklist file (default: {blacklist_default})') parser_test.add_argument("--skip", action='store_true', help="skip the tests if they were run before") parser_test.add_argument("--environ", nargs='+', @@ -191,8 +190,7 @@ def main(): parser_test.add_argument("--projects", nargs='+', type=str, default=tested_projects, choices=all_projects, - help="use '{}'' (default) or other projects" - .format("' '".join(tested_projects))) + help=f"use {tested_projects_quoted} (default) or other projects") parser_getcwd = subparsers.add_parser("getcwd") parser_getcwd.add_argument("filename", type=argparse.FileType('w'), help="write the build dir name into a file") @@ -242,15 +240,14 @@ def main(): print(dedent("""\ System: - Platform={platform} - Executable={executable} - Version={version_lf} - API version={api_version} + Platform={sys.__dict__["platform"]} + Executable={sys.__dict__["executable"]} + Version={sys.version.replace("\n", " ")} + API version={sys.__dict__["api_version"]} - Environment:""").format(version_lf=sys.version.replace("\n", " "), - **sys.__dict__)) + Environment:""")) for key, value in sorted(os.environ.items()): - print(" {}={}".format(key, value)) + print(f" {key}={value}") print() q = 5 * [0] @@ -267,9 +264,8 @@ def main(): q = list(map(lambda x, y: x + y, r, q)) if len(args.projects) > 1: - print("All above projects:", sum(q), "tests.", - "{} passed, {} failed, {} skipped, {} blacklisted, {} bpassed." - .format(*q)) + print(f"All above projects: {sum(q)} tests. " + f"{q[0]} passed, {q[1]} failed, {q[2]} skipped, {q[3]} blacklisted, {q[4]} bpassed.") print() tot_res = OrderedDict() @@ -279,7 +275,7 @@ def main(): runner = TestRunner(builds.selected, project, index) results = TestParser(runner.logfile) for item in results.iter_blacklist(bl): - key = project + ":" + item.mod_name + key = f"{project}:{item.mod_name}" tot_res.setdefault(key, []) tot_res[key].append(item.rich_result) tot_flaky = 0 @@ -312,8 +308,8 @@ def main(): continue empty = False padding = 6 * runs - txt = " ".join(("{:<{width}}".format(piece, width=5) for piece in res)) - txt = (txt + padding * " ")[:padding] + txt = " ".join((f"{piece:<5}" for piece in res)) + txt = (f"{txt}{padding * ' '}")[:padding] testpad = 36 if len(test) < testpad: test += (testpad - len(test)) * " " @@ -325,7 +321,7 @@ def main(): print("*" * 79) print() if runs > 1: - print("Total flaky tests: errors but not always = {}".format(tot_flaky)) + print(f"Total flaky tests: errors but not always = {tot_flaky}") print() else: print("For info about flaky tests, we need to perform more than one run.") @@ -342,8 +338,8 @@ def main(): # Now create an error if the criterion is met: try: if fatal: - raise ValueError("FATAL format error:", fatal) - err_crit = "'FAIL! >= {}'".format(fail_crit) + raise ValueError(f"FATAL format error: {fatal}") + err_crit = f"'FAIL! >= {fail_crit}'" fail_count = 0 for res in tot_res.values(): if res.count("FAIL!") >= fail_crit: @@ -353,9 +349,9 @@ def main(): elif fail_count > 1: raise ValueError(f"{fail_count} failures were not blacklisted " f"and met the criterion {err_crit}") - print("No test met the error criterion {}".format(err_crit)) + print(f"No test met the error criterion {err_crit}") finally: print() - print("Total time of whole Python script = {:0.2f} sec".format(used_time)) + print(f"Total time of whole Python script = {used_time:0.2f} sec") print() # eof diff --git a/testing/parser.py b/testing/parser.py index 16b3362c8..e22f94fda 100644 --- a/testing/parser.py +++ b/testing/parser.py @@ -145,9 +145,9 @@ def _parse_tests(test_log): if idx + 1 != item.idx: # The numbering is disrupted. Provoke an error in this line! passed = False - code += ", but lines are disrupted!" + code = f"{code}, but lines are disrupted!" result[idx] = item._replace(passed=False, - code=item.code + ", but lines are disrupted!", + code=f"{item.code}, but lines are disrupted!", fatal=True) break return result diff --git a/testing/runner.py b/testing/runner.py index 084ca60ec..a3bf2e265 100644 --- a/testing/runner.py +++ b/testing/runner.py @@ -43,7 +43,7 @@ import re import subprocess import inspect -from textwrap import dedent +from textwrap import dedent, indent from subprocess import TimeoutExpired # Get the dir path to the utils module @@ -66,9 +66,9 @@ class TestRunner(object): self.test_dir = os.path.join(built_path, project) log_dir = log_entry.log_dir if index is not None: - self.logfile = os.path.join(log_dir, project + ".{}.log".format(index)) + self.logfile = os.path.join(log_dir, f"{project}.{index}.log") else: - self.logfile = os.path.join(log_dir, project + ".log") + self.logfile = os.path.join(log_dir, f"{project}.log") os.environ['CTEST_OUTPUT_ON_FAILURE'] = '1' self._setup_clang() self._setup() @@ -82,7 +82,7 @@ class TestRunner(object): path = os.environ.get('PATH') if clang_bin_dir not in path: os.environ['PATH'] = clang_bin_dir + os.pathsep + path - print("Adding %s as detected by %s to PATH" % (clang_bin_dir, clang_dir[1])) + print(f"Adding {clang_bin_dir} as detected by {clang_dir[1]} to PATH") def _find_ctest_in_file(self, file_name): """ @@ -99,14 +99,14 @@ class TestRunner(object): # We have probably forgotten to build the tests. # Give a nice error message with a shortened but exact path. rel_path = os.path.relpath(file_name) - msg = dedent("""\n - {line} - ** ctest is not in '{}'. + msg = dedent(f"""\n + {'*' * 79} + ** ctest is not in '{rel_path}'. * Did you forget to build the tests with '--build-tests' in setup.py? - """).format(rel_path, line=79 * "*") + """) raise RuntimeError(msg) # the ctest program is on the left to look_for - assert line, "Did not find {}".format(look_for) + assert line, f"Did not find {look_for}" ctest = re.search(r'(\S+|"([^"]+)")\s+' + look_for, line).groups() return ctest[1] or ctest[0] @@ -126,8 +126,8 @@ class TestRunner(object): path = os.path.join(self.test_dir, candidate) if os.path.exists(path): return self._find_ctest_in_file(path) - raise RuntimeError('Cannot find any of the build system files {}.'.format( - ', '.join(candidate_files))) + raise RuntimeError("Cannot find any of the build system files " + f"{', '.join(candidate_files)}.") def _setup(self): self.ctestCommand = self._find_ctest() @@ -151,10 +151,10 @@ class TestRunner(object): # without a caret are interpreted as such which leads to weirdness. # Since we have all commands with explicit paths and don't use shell # commands, this should work fine. - print(dedent("""\ - running {cmd} - in {test_dir} - """).format(**self.__dict__)) + print(dedent(f"""\ + running {self.cmd} + in {self.test_dir} + """)) ctest_process = subprocess.Popen(self.cmd, cwd=self.test_dir, stdout=subprocess.PIPE, @@ -196,11 +196,8 @@ class TestRunner(object): if line.startswith(text_z): labelled = True - tee_src = dedent("""\ - import sys - {} - py_tee(sys.stdin, sys.stdout, '{label}') - """).format(dedent(inspect.getsource(py_tee)), label=label) + tee_src = dedent(inspect.getsource(py_tee)) + tee_src = f"import sys\n{tee_src}\npy_tee(sys.stdin, sys.stdout, '{label}')" tee_cmd = (sys.executable, "-E", "-u", "-c", tee_src) tee_process = subprocess.Popen(tee_cmd, cwd=self.test_dir, @@ -214,7 +211,7 @@ class TestRunner(object): ctest_process.kill() _ = ctest_process.communicate() # ctest lists to a temp file. Move it to the log - tmp_name = self.logfile + ".tmp" + tmp_name = f"{self.logfile}.tmp" if os.path.exists(tmp_name): if os.path.exists(self.logfile): os.unlink(self.logfile) diff --git a/testing/wheel_tester.py b/testing/wheel_tester.py index c09e2d8a7..9931f178e 100644 --- a/testing/wheel_tester.py +++ b/testing/wheel_tester.py @@ -79,23 +79,22 @@ log.set_verbosity(1) def find_executable(executable, command_line_value): value = command_line_value - option_str = '--{}'.format(executable) + option_str = f"--{executable}" if value: - log.info("{} option given: {}".format(option_str, value)) + log.info(f"{option_str} option given: {value}") if not os.path.exists(value): - raise RuntimeError("No executable exists at: {}".format(value)) + raise RuntimeError(f"No executable exists at: {value}") else: - log.info("No {} option given, trying to find {} in PATH.".format(option_str, executable)) + log.info(f"No {option_str} option given, trying to find {executable} in PATH.") paths = find_glob_in_path(executable) - log.info("{} executables found in PATH: {}".format(executable, paths)) + log.info(f"{executable} executables found in PATH: {paths}") if not paths: - raise RuntimeError( - "No {} option was specified and no {} was found " - "in PATH.".format(option_str, executable)) + raise RuntimeError(f"No {option_str} option was specified and no {executable} was " + "found in PATH.") else: value = paths[0] - log.info("Using {} found in PATH: {}".format(executable, value)) + log.info(f"Using {executable} found in PATH: {value}") log.info("") return value @@ -127,16 +126,16 @@ def clean_egg_info(): # safe to do so. paths = find_files_using_glob(setup_script_dir, "*.egg-info") for p in paths: - log.info("Removing {}".format(p)) + log.info(f"Removing {p}") rmtree(p) def install_wheel(wheel_path): - log.info("Installing wheel: {}".format(wheel_path)) + log.info(f"Installing wheel: {wheel_path}") exit_code = run_process([sys.executable, "-m", "pip", "install", wheel_path]) log.info("") if exit_code: - raise RuntimeError("Error while installing wheel {}".format(wheel_path)) + raise RuntimeError(f"Error while installing wheel {wheel_path}") def try_install_wheels(wheels_dir, py_version): @@ -145,16 +144,16 @@ def try_install_wheels(wheels_dir, py_version): all_wheels = find_files_using_glob(wheels_dir, all_wheels_pattern) if len(all_wheels) > 1: - log.info("Found the following wheels in {}: ".format(wheels_dir)) + log.info(f"Found the following wheels in {wheels_dir}: ") for wheel in all_wheels: log.info(wheel) else: - log.info("No wheels found in {}".format(wheels_dir)) + log.info(f"No wheels found in {wheels_dir}") log.info("") for p in package_prefix_names(): log.info(f"Trying to install {p}:") - pattern = "{}-*cp{}*.whl".format(p, int(float(py_version))) + pattern = f"{p}-*cp{int(float(py_version))}*.whl" files = find_files_using_glob(wheels_dir, pattern) if files and len(files) == 1: wheel_path = files[0] @@ -179,11 +178,11 @@ def generate_build_cmake(): else: args.extend(["-G", "NMake Makefiles"]) args.append("-DCMAKE_BUILD_TYPE=Release") - args.append("-Dpython_interpreter={}".format(sys.executable)) + args.append(f"-Dpython_interpreter={sys.executable}") # Specify prefix path so find_package(Qt5) works. qmake_dir = os.path.abspath(os.path.join(os.path.dirname(QMAKE_PATH), "..")) - args.append("-DCMAKE_PREFIX_PATH={}".format(qmake_dir)) + args.append(f"-DCMAKE_PREFIX_PATH={qmake_dir}") args.append("..") @@ -194,7 +193,7 @@ def generate_build_cmake(): def generate_build_qmake(): - exit_code = run_process([QMAKE_PATH, "..", "python_interpreter={}".format(sys.executable)]) + exit_code = run_process([QMAKE_PATH, "..", f"python_interpreter={sys.executable}"]) if exit_code: raise RuntimeError("Failure while running qmake.") log.info("") @@ -264,7 +263,7 @@ def run_make(): exit_code = run_process(args) if exit_code: - raise RuntimeError("Failure while running {}.".format(executable)) + raise RuntimeError(f"Failure while running {executable}.") log.info("") @@ -279,7 +278,7 @@ def run_make_install(): exit_code = run_process(args) if exit_code: - raise RuntimeError("Failed while running {} install.".format(executable)) + raise RuntimeError(f"Failed while running {executable} install.") log.info("") @@ -287,7 +286,7 @@ def run_compiled_script(binary_path): args = [binary_path] exit_code = run_process(args) if exit_code: - raise_error_pyinstaller("Failure while executing compiled script: {}".format(binary_path)) + raise_error_pyinstaller(f"Failure while executing compiled script: {binary_path}") log.info("") @@ -295,7 +294,7 @@ def execute_script(script_path, *extra): args = list(map(str, (sys.executable, script_path) + extra)) exit_code = run_process(args) if exit_code: - raise RuntimeError("Failure while executing script: {}".format(script_path)) + raise RuntimeError(f"Failure while executing script: {script_path}") log.info("") @@ -305,10 +304,10 @@ def prepare_build_folder(src_path, build_folder_name): # The script can be called for Python 3 wheels, so # preparing a build folder should clean any previous existing build. if os.path.exists(build_path): - log.info("Removing {}".format(build_path)) + log.info(f"Removing {build_path}") rmtree(build_path) - log.info("Creating {}".format(build_path)) + log.info(f"Creating {build_path}") os.makedirs(build_path) os.chdir(build_path) @@ -370,7 +369,7 @@ def try_build_examples(): def run_wheel_tests(install_wheels): wheels_dir = get_wheels_dir() - py_version = "{v.major}.{v.minor}".format(v=sys.version_info) + py_version = f"{sys.version_info.major}.{sys.version_info.minor}" if install_wheels: log.info("Attempting to install wheels.\n") -- cgit v1.2.3