From 21105fce8b5bc897d3000fb3aafd3ab094066813 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 12 Dec 2022 14:23:03 +0200 Subject: [PATCH 1/7] Remove compatibilty for Python < 3.3 --- Tools/iobench/iobench.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Tools/iobench/iobench.py b/Tools/iobench/iobench.py index b0a7feb92e4f92..250a4558903d02 100644 --- a/Tools/iobench/iobench.py +++ b/Tools/iobench/iobench.py @@ -309,14 +309,7 @@ def run_test_family(tests, mode_filter, files, open_func, *make_args): } print("Python %s" % sys.version) - if sys.version_info < (3, 3): - if sys.maxunicode > 0xffff: - text = "UCS-4 (wide build)" - else: - text = "UTF-16 (narrow build)" - else: - text = "PEP 393" - print("Unicode: %s" % text) + print("Unicode: PEP 393") print(platform.platform()) binary_files = list(get_binary_files()) text_files = list(get_text_files()) From 25663f3dab7214cf8229b2d2957ee9a18e2661e6 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 12 Dec 2022 14:25:07 +0200 Subject: [PATCH 2/7] Remove compatibilty for Python 2 --- Tools/iobench/iobench.py | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/Tools/iobench/iobench.py b/Tools/iobench/iobench.py index 250a4558903d02..5005c3ca8ebb0f 100644 --- a/Tools/iobench/iobench.py +++ b/Tools/iobench/iobench.py @@ -14,11 +14,6 @@ TEXT_ENCODING = 'utf8' NEWLINES = 'lf' -# Compatibility -try: - xrange -except NameError: - xrange = range def text_open(fn, mode, encoding=None): try: @@ -103,7 +98,7 @@ def seek_forward_bytewise(f): f.seek(0, 2) size = f.tell() f.seek(0, 0) - for i in xrange(0, size - 1): + for i in range(0, size - 1): f.seek(i, 0) @with_open_mode("r") @@ -113,7 +108,7 @@ def seek_forward_blockwise(f): f.seek(0, 2) size = f.tell() f.seek(0, 0) - for i in xrange(0, size - 1, 1000): + for i in range(0, size - 1, 1000): f.seek(i, 0) @with_open_mode("rb") @@ -137,28 +132,28 @@ def read_seek_blockwise(f): @with_sizes("small") def write_bytewise(f, source): """ write one unit at a time """ - for i in xrange(0, len(source)): + for i in range(0, len(source)): f.write(source[i:i+1]) @with_open_mode("w") @with_sizes("medium") def write_small_chunks(f, source): """ write 20 units at a time """ - for i in xrange(0, len(source), 20): + for i in range(0, len(source), 20): f.write(source[i:i+20]) @with_open_mode("w") @with_sizes("medium") def write_medium_chunks(f, source): """ write 4096 units at a time """ - for i in xrange(0, len(source), 4096): + for i in range(0, len(source), 4096): f.write(source[i:i+4096]) @with_open_mode("w") @with_sizes("large") def write_large_chunks(f, source): """ write 1e6 units at a time """ - for i in xrange(0, len(source), 1000000): + for i in range(0, len(source), 1000000): f.write(source[i:i+1000000]) @@ -167,7 +162,7 @@ def write_large_chunks(f, source): def modify_bytewise(f, source): """ modify one unit at a time """ f.seek(0) - for i in xrange(0, len(source)): + for i in range(0, len(source)): f.write(source[i:i+1]) @with_open_mode("w+") @@ -175,7 +170,7 @@ def modify_bytewise(f, source): def modify_small_chunks(f, source): """ modify 20 units at a time """ f.seek(0) - for i in xrange(0, len(source), 20): + for i in range(0, len(source), 20): f.write(source[i:i+20]) @with_open_mode("w+") @@ -183,7 +178,7 @@ def modify_small_chunks(f, source): def modify_medium_chunks(f, source): """ modify 4096 units at a time """ f.seek(0) - for i in xrange(0, len(source), 4096): + for i in range(0, len(source), 4096): f.write(source[i:i+4096]) @with_open_mode("wb+") @@ -191,7 +186,7 @@ def modify_medium_chunks(f, source): def modify_seek_forward_bytewise(f, source): """ alternate write & seek one unit """ f.seek(0) - for i in xrange(0, len(source), 2): + for i in range(0, len(source), 2): f.write(source[i:i+1]) f.seek(i+2) @@ -200,7 +195,7 @@ def modify_seek_forward_bytewise(f, source): def modify_seek_forward_blockwise(f, source): """ alternate write & seek 1000 units """ f.seek(0) - for i in xrange(0, len(source), 2000): + for i in range(0, len(source), 2000): f.write(source[i:i+1000]) f.seek(i+2000) @@ -210,7 +205,7 @@ def modify_seek_forward_blockwise(f, source): def read_modify_bytewise(f, source): """ alternate read & write one unit """ f.seek(0) - for i in xrange(0, len(source), 2): + for i in range(0, len(source), 2): f.read(1) f.write(source[i+1:i+2]) @@ -219,7 +214,7 @@ def read_modify_bytewise(f, source): def read_modify_blockwise(f, source): """ alternate read & write 1000 units """ f.seek(0) - for i in xrange(0, len(source), 2000): + for i in range(0, len(source), 2000): f.read(1000) f.write(source[i+1000:i+2000]) From e1dadc2f2a455f64498a533f57d1d7193ea23b93 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 12 Dec 2022 14:26:00 +0200 Subject: [PATCH 3/7] Remove compatibilty note for Python 2.6 and 3.0-3.6 --- Tools/iobench/iobench.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/Tools/iobench/iobench.py b/Tools/iobench/iobench.py index 5005c3ca8ebb0f..dbd65e131f7653 100644 --- a/Tools/iobench/iobench.py +++ b/Tools/iobench/iobench.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -# This file should be kept compatible with both Python 2.6 and Python >= 3.0. - import itertools import os import platform From 1ee3e500b54f2b282bbe7f28827b959b4a0c7cb3 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 12 Dec 2022 14:31:01 +0200 Subject: [PATCH 4/7] Remove compatibilty for Python 2 --- Tools/iobench/iobench.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Tools/iobench/iobench.py b/Tools/iobench/iobench.py index dbd65e131f7653..ec01a9e6ee5291 100644 --- a/Tools/iobench/iobench.py +++ b/Tools/iobench/iobench.py @@ -16,10 +16,9 @@ def text_open(fn, mode, encoding=None): try: return open(fn, mode, encoding=encoding or TEXT_ENCODING) except TypeError: - if 'r' in mode: - mode += 'U' # 'U' mode is needed only in Python 2.x return open(fn, mode) + def get_file_sizes(): for s in ['20 KiB', '400 KiB', '10 MiB']: size, unit = s.split() From 902f9a2c39652f136499c96385f19292c2ed6a70 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 12 Dec 2022 14:33:13 +0200 Subject: [PATCH 5/7] Whitespace between functions --- Tools/iobench/iobench.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Tools/iobench/iobench.py b/Tools/iobench/iobench.py index ec01a9e6ee5291..8d3adc34803808 100644 --- a/Tools/iobench/iobench.py +++ b/Tools/iobench/iobench.py @@ -25,19 +25,23 @@ def get_file_sizes(): size = int(size) * {'KiB': 1024, 'MiB': 1024 ** 2}[unit] yield s.replace(' ', ''), size + def get_binary_files(): return ((name + ".bin", size) for name, size in get_file_sizes()) + def get_text_files(): return (("%s-%s-%s.txt" % (name, TEXT_ENCODING, NEWLINES), size) for name, size in get_file_sizes()) + def with_open_mode(mode): def decorate(f): f.file_open_mode = mode return f return decorate + def with_sizes(*sizes): def decorate(f): f.file_sizes = sizes @@ -55,6 +59,7 @@ def read_bytewise(f): while f.read(1): pass + @with_open_mode("r") @with_sizes("medium") def read_small_chunks(f): @@ -63,6 +68,7 @@ def read_small_chunks(f): while f.read(20): pass + @with_open_mode("r") @with_sizes("medium") def read_big_chunks(f): @@ -71,6 +77,7 @@ def read_big_chunks(f): while f.read(4096): pass + @with_open_mode("r") @with_sizes("small", "medium", "large") def read_whole_file(f): @@ -79,6 +86,7 @@ def read_whole_file(f): while f.read(): pass + @with_open_mode("rt") @with_sizes("medium") def read_lines(f): @@ -87,6 +95,7 @@ def read_lines(f): for line in f: pass + @with_open_mode("r") @with_sizes("medium") def seek_forward_bytewise(f): @@ -97,6 +106,7 @@ def seek_forward_bytewise(f): for i in range(0, size - 1): f.seek(i, 0) + @with_open_mode("r") @with_sizes("medium") def seek_forward_blockwise(f): @@ -107,6 +117,7 @@ def seek_forward_blockwise(f): for i in range(0, size - 1, 1000): f.seek(i, 0) + @with_open_mode("rb") @with_sizes("medium") def read_seek_bytewise(f): @@ -115,6 +126,7 @@ def read_seek_bytewise(f): while f.read(1): f.seek(1, 1) + @with_open_mode("rb") @with_sizes("medium") def read_seek_blockwise(f): @@ -131,6 +143,7 @@ def write_bytewise(f, source): for i in range(0, len(source)): f.write(source[i:i+1]) + @with_open_mode("w") @with_sizes("medium") def write_small_chunks(f, source): @@ -138,6 +151,7 @@ def write_small_chunks(f, source): for i in range(0, len(source), 20): f.write(source[i:i+20]) + @with_open_mode("w") @with_sizes("medium") def write_medium_chunks(f, source): @@ -145,6 +159,7 @@ def write_medium_chunks(f, source): for i in range(0, len(source), 4096): f.write(source[i:i+4096]) + @with_open_mode("w") @with_sizes("large") def write_large_chunks(f, source): @@ -161,6 +176,7 @@ def modify_bytewise(f, source): for i in range(0, len(source)): f.write(source[i:i+1]) + @with_open_mode("w+") @with_sizes("medium") def modify_small_chunks(f, source): @@ -169,6 +185,7 @@ def modify_small_chunks(f, source): for i in range(0, len(source), 20): f.write(source[i:i+20]) + @with_open_mode("w+") @with_sizes("medium") def modify_medium_chunks(f, source): @@ -177,6 +194,7 @@ def modify_medium_chunks(f, source): for i in range(0, len(source), 4096): f.write(source[i:i+4096]) + @with_open_mode("wb+") @with_sizes("medium") def modify_seek_forward_bytewise(f, source): @@ -186,6 +204,7 @@ def modify_seek_forward_bytewise(f, source): f.write(source[i:i+1]) f.seek(i+2) + @with_open_mode("wb+") @with_sizes("medium") def modify_seek_forward_blockwise(f, source): @@ -195,6 +214,7 @@ def modify_seek_forward_blockwise(f, source): f.write(source[i:i+1000]) f.seek(i+2000) + # XXX the 2 following tests don't work with py3k's text IO @with_open_mode("wb+") @with_sizes("medium") @@ -205,6 +225,7 @@ def read_modify_bytewise(f, source): f.read(1) f.write(source[i+1:i+2]) + @with_open_mode("wb+") @with_sizes("medium") def read_modify_blockwise(f, source): @@ -233,6 +254,7 @@ def read_modify_blockwise(f, source): read_modify_bytewise, read_modify_blockwise, ] + def run_during(duration, func): _t = time.time n = 0 @@ -248,6 +270,7 @@ def run_during(duration, func): real = (end[4] if start[4] else time.time()) - real_start return n, real, sum(end[0:2]) - sum(start[0:2]) + def warm_cache(filename): with open(filename, "rb") as f: f.read() @@ -322,6 +345,7 @@ def run_test_family(tests, mode_filter, files, open_func, *make_args): # Binary writes if "b" in options and "w" in options: print("\n** Binary append **\n") + def make_test_source(name, size): with open(name, "rb") as f: return f.read() @@ -331,6 +355,7 @@ def make_test_source(name, size): # Text writes if "t" in options and "w" in options: print("\n** Text append **\n") + def make_test_source(name, size): with text_open(name, "r") as f: return f.read() @@ -340,6 +365,7 @@ def make_test_source(name, size): # Binary overwrites if "b" in options and "w" in options: print("\n** Binary overwrite **\n") + def make_test_source(name, size): with open(name, "rb") as f: return f.read() @@ -349,6 +375,7 @@ def make_test_source(name, size): # Text overwrites if "t" in options and "w" in options: print("\n** Text overwrite **\n") + def make_test_source(name, size): with text_open(name, "r") as f: return f.read() @@ -398,6 +425,7 @@ def prepare_files(): f.write(head) f.write(tail) + def main(): global TEXT_ENCODING, NEWLINES @@ -455,6 +483,7 @@ def main(): prepare_files() run_all_tests(test_options) + if __name__ == "__main__": main() From 59f2f14c8e890fe932413c4426798fabbf8ef8d8 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 12 Dec 2022 14:45:43 +0200 Subject: [PATCH 6/7] Use f-strings --- Tools/iobench/iobench.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Tools/iobench/iobench.py b/Tools/iobench/iobench.py index 8d3adc34803808..c2c3ae07d58984 100644 --- a/Tools/iobench/iobench.py +++ b/Tools/iobench/iobench.py @@ -31,7 +31,7 @@ def get_binary_files(): def get_text_files(): - return (("%s-%s-%s.txt" % (name, TEXT_ENCODING, NEWLINES), size) + return ((f"{name}-{TEXT_ENCODING}-{NEWLINES}.txt", size) for name, size in get_file_sizes()) @@ -280,9 +280,7 @@ def run_all_tests(options): def print_label(filename, func): name = re.split(r'[-.]', filename)[0] out.write( - ("[%s] %s... " - % (name.center(7), func.__doc__.strip()) - ).ljust(52)) + f"[{name.center(7)}] {func.__doc__.strip()}... ".ljust(52)) out.flush() def print_results(size, n, real, cpu): @@ -290,8 +288,9 @@ def print_results(size, n, real, cpu): bw = ("%4d MiB/s" if bw > 100 else "%.3g MiB/s") % bw out.write(bw.rjust(12) + "\n") if cpu < 0.90 * real: - out.write(" warning: test above used only %d%% CPU, " - "result may be flawed!\n" % (100.0 * cpu / real)) + out.write(" warning: test above used only " + f"{100.0 * cpu / real}% CPU, " + "result may be flawed!\n") def run_one_test(name, size, open_func, test_func, *args): mode = test_func.file_open_mode @@ -322,7 +321,7 @@ def run_test_family(tests, mode_filter, files, open_func, *make_args): "large": 2, } - print("Python %s" % sys.version) + print(f"Python {sys.version}") print("Unicode: PEP 393") print(platform.platform()) binary_files = list(get_binary_files()) @@ -330,7 +329,7 @@ def run_test_family(tests, mode_filter, files, open_func, *make_args): if "b" in options: print("Binary unit = one byte") if "t" in options: - print("Text unit = one character (%s-decoded)" % TEXT_ENCODING) + print(f"Text unit = one character ({TEXT_ENCODING}-decoded)") # Binary reads if "b" in options and "r" in options: @@ -399,7 +398,7 @@ def prepare_files(): break else: raise RuntimeError( - "Couldn't find chunk marker in %s !" % __file__) + f"Couldn't find chunk marker in {__file__} !") if NEWLINES == "all": it = itertools.cycle(["\n", "\r", "\r\n"]) else: @@ -445,7 +444,7 @@ def main(): help="run write & modify tests") parser.add_option("-E", "--encoding", action="store", dest="encoding", default=None, - help="encoding for text tests (default: %s)" % TEXT_ENCODING) + help=f"encoding for text tests (default: {TEXT_ENCODING})") parser.add_option("-N", "--newlines", action="store", dest="newlines", default='lf', help="line endings for text tests " @@ -458,7 +457,7 @@ def main(): parser.error("unexpected arguments") NEWLINES = options.newlines.lower() if NEWLINES not in ('lf', 'cr', 'crlf', 'all'): - parser.error("invalid 'newlines' option: %r" % NEWLINES) + parser.error(f"invalid 'newlines' option: {NEWLINES!r}") test_options = "" if options.read: From 3936f0d9e1d8c240ed38c8083c5f92c2aa460b0b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 30 Jan 2023 16:29:47 +0200 Subject: [PATCH 7/7] Use builtin % formatter Co-authored-by: Alex Waygood --- Tools/iobench/iobench.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/iobench/iobench.py b/Tools/iobench/iobench.py index c2c3ae07d58984..4017149ec91630 100644 --- a/Tools/iobench/iobench.py +++ b/Tools/iobench/iobench.py @@ -289,7 +289,7 @@ def print_results(size, n, real, cpu): out.write(bw.rjust(12) + "\n") if cpu < 0.90 * real: out.write(" warning: test above used only " - f"{100.0 * cpu / real}% CPU, " + f"{cpu / real:%} CPU, " "result may be flawed!\n") def run_one_test(name, size, open_func, test_func, *args):