diff --git a/.circleci/config.yml b/.circleci/config.yml index 3091affffee23..c605fb995c50f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -425,8 +425,8 @@ jobs: - checkout - pip-install - run: ruff check - # TODO (cclauss): When ruff supports rule E303 without --preview, remove following line - - run: ruff check --preview --select=E303 + # TODO (cclauss): When ruff supports rules E20,E30 without --preview, remove following line + - run: ruff check --preview --select=E20,E30 mypy: executor: focal steps: diff --git a/emcc.py b/emcc.py index a556a6f956149..70cdcfab89ddc 100644 --- a/emcc.py +++ b/emcc.py @@ -644,7 +644,7 @@ def run(args): print(compiler_rt.get_path(absolute=True)) return 0 - print_file_name = [a for a in newargs if a.startswith('-print-file-name=') or a.startswith('--print-file-name=')] + print_file_name = [a for a in newargs if a.startswith(('-print-file-name=', '--print-file-name='))] if print_file_name: libname = print_file_name[-1].split('=')[1] system_libpath = cache.get_lib_dir(absolute=True) @@ -1541,7 +1541,7 @@ def parse_value(text, expected_type): # places here. def parse_string_value(text): first = text[0] - if first == "'" or first == '"': + if first in {"'", '"'}: text = text.rstrip() if text[-1] != text[0] or len(text) < 2: raise ValueError(f'unclosed quoted string. expected final character to be "{text[0]}" and length to be greater than 1 in "{text[0]}"') @@ -1558,7 +1558,7 @@ def parse_string_list_members(text): if not len(current): raise ValueError('empty value in string list') first = current[0] - if not (first == "'" or first == '"'): + if first not in {"'", '"'}: result.append(current.rstrip()) else: start = index diff --git a/emrun.py b/emrun.py index 0d33218c2d747..a52def4e51113 100644 --- a/emrun.py +++ b/emrun.py @@ -817,7 +817,7 @@ def find_gpu_model(model): return gpu return None - for i in range(0, 16): + for i in range(16): try: hHardwareReg = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'HARDWARE') hDeviceMapReg = winreg.OpenKey(hHardwareReg, 'DEVICEMAP') @@ -1398,7 +1398,7 @@ def get_system_info(format_json): if len(gpus) == 1: info += 'GPU: ' + gpus[0]['model'] + ' with ' + str(gpus[0]['ram'] // 1024 // 1024) + " MB of VRAM\n" elif len(gpus) > 1: - for i in range(0, len(gpus)): + for i in range(len(gpus)): info += 'GPU' + str(i) + ": " + gpus[i]['model'] + ' with ' + str(gpus[i]['ram'] // 1024 // 1024) + ' MBs of VRAM\n' info += 'UUID: ' + unique_system_id return info.strip() @@ -1427,7 +1427,6 @@ def list_processes_by_name(exe_full_path): except Exception: # Fail gracefully if psutil not available logv('import psutil failed, unable to detect browser processes') - pass logv('Searching for processes by full path name "' + exe_full_path + '".. found ' + str(len(pids)) + ' entries') @@ -1637,7 +1636,7 @@ def run(args): # noqa: C901, PLR0912, PLR0915 file_to_serve = options.serve else: file_to_serve = '.' - file_to_serve_is_url = file_to_serve.startswith('file://') or file_to_serve.startswith('http://') or file_to_serve.startswith('https://') + file_to_serve_is_url = file_to_serve.startswith(('file://', 'http://', 'https://')) if options.serve_root: serve_dir = os.path.abspath(options.serve_root) @@ -1645,7 +1644,7 @@ def run(args): # noqa: C901, PLR0912, PLR0915 if file_to_serve == '.' or file_to_serve_is_url: serve_dir = os.path.abspath('.') else: - if file_to_serve.endswith('/') or file_to_serve.endswith('\\') or os.path.isdir(file_to_serve): + if file_to_serve.endswith(('/', '\\')) or os.path.isdir(file_to_serve): serve_dir = file_to_serve else: serve_dir = os.path.dirname(os.path.abspath(file_to_serve)) @@ -1684,7 +1683,7 @@ def run(args): # noqa: C901, PLR0912, PLR0915 return 1 elif options.browser == 'firefox': browser_app = 'org.mozilla.firefox/org.mozilla.gecko.BrowserApp' - elif options.browser == 'firefox_nightly' or options.browser == 'fenix': + elif options.browser in {'firefox_nightly', 'fenix'}: browser_app = 'org.mozilla.fenix/org.mozilla.gecko.BrowserApp' elif options.browser == 'chrome': browser_app = 'com.android.chrome/com.google.android.apps.chrome.Main' diff --git a/pyproject.toml b/pyproject.toml index 72076b0713590..5db694ed8e736 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ lint.select = [ "E", "F", "PERF", + "PIE", "PL", "W", "YTT", @@ -42,7 +43,6 @@ lint.ignore = [ "PERF203", "PERF401", "PLR1704", - "PLR1714", "PLR5501", "PLW0602", "PLW0603", diff --git a/requirements-dev.txt b/requirements-dev.txt index 84c824c5ee1b6..eccf8d30667b9 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,7 +6,7 @@ coverage[toml]==5.5 mypy==0.971 -ruff==0.8.2 +ruff==0.9.1 types-requests==2.27.14 unittest-xml-reporting==3.1.0 diff --git a/test/common.py b/test/common.py index d4b55c0483860..ea5d01a6f5308 100644 --- a/test/common.py +++ b/test/common.py @@ -637,7 +637,7 @@ def with_all_eh_sjlj(f): def metafunc(self, mode, *args, **kwargs): if DEBUG: print('parameterize:eh_mode=%s' % mode) - if mode == 'wasm' or mode == 'wasm_exnref': + if mode in {'wasm', 'wasm_exnref'}: # Wasm EH is currently supported only in wasm backend and V8 if self.is_wasm2js(): self.skipTest('wasm2js does not support wasm EH/SjLj') @@ -674,7 +674,7 @@ def with_all_sjlj(f): @wraps(f) def metafunc(self, mode, *args, **kwargs): - if mode == 'wasm' or mode == 'wasm_exnref': + if mode in {'wasm', 'wasm_exnref'}: if self.is_wasm2js(): self.skipTest('wasm2js does not support wasm SjLj') # FIXME Temporarily disabled. Enable this later when the bug is fixed. diff --git a/test/gen_large_switchcase.py b/test/gen_large_switchcase.py index e9f5cef0825f2..24c7adac873ee 100755 --- a/test/gen_large_switchcase.py +++ b/test/gen_large_switchcase.py @@ -10,7 +10,7 @@ cases = '' i = 1 incr = 1 -for _ in range(0, num_cases): +for _ in range(num_cases): cases += ' case ' + str(i) + ': return "' + str(i) + str(i) + str(i) + '";\n' i += incr incr = (incr % 5) + 1 diff --git a/test/runner.py b/test/runner.py index 5896fe4f15b9e..a07702a5e3dfc 100755 --- a/test/runner.py +++ b/test/runner.py @@ -314,6 +314,7 @@ def flattened_tests(loaded_tests): tests.extend(subsuite) return tests + def suite_for_module(module, tests): suite_supported = module.__name__ in ('test_core', 'test_other', 'test_posixtest') if not common.EMTEST_SAVE_DIR and not shared.DEBUG: diff --git a/test/test_browser.py b/test/test_browser.py index b16e2481d989f..baeffa5012ef9 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -285,7 +285,7 @@ def reftest(self, filename, reference, reference_slack=0, *args, **kwargs): """ reference = find_browser_test_file(reference) assert 'expected' not in kwargs - expected = [str(i) for i in range(0, reference_slack + 1)] + expected = [str(i) for i in range(reference_slack + 1)] self.make_reftest(reference) if '--proxy-to-worker' in self.emcc_args: assert 'post_build' not in kwargs diff --git a/test/test_other.py b/test/test_other.py index 23fe7c164cd9d..f618502be6262 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -1152,7 +1152,7 @@ def verify_includes(stderr): i = os.path.normpath(i) # we also allow for the cache include directory and llvm's own builtin includes. # all other include paths should be inside the sysroot. - if i.startswith(cachedir) or i.startswith(llvmroot): + if i.startswith((cachedir, llvmroot)): continue self.assertContained(path_from_root('system'), i) @@ -11374,7 +11374,7 @@ def print_percent(actual, expected): obtained_results[f] = size obtained_results[f_gz] = size_gz - if size != expected_size and (f.endswith('.js') or f.endswith('.html')): + if size != expected_size and (f.endswith(('.js', '.html'))): print('Contents of ' + f + ': ') print(read_file(f)) diff --git a/test/test_posixtest.py b/test/test_posixtest.py index 506ac006ae135..292f5d53a512d 100644 --- a/test/test_posixtest.py +++ b/test/test_posixtest.py @@ -24,7 +24,7 @@ class posixtest(RunnerCore): This class get populated dynamically below. """ - pass + pass # noqa: PIE790 def filter_tests(all_tests): diff --git a/test/test_posixtest_browser.py b/test/test_posixtest_browser.py index 98298aa668c9e..36be0c1792949 100644 --- a/test/test_posixtest_browser.py +++ b/test/test_posixtest_browser.py @@ -15,4 +15,3 @@ class posixtest_browser(BrowserCore): This class get populated dynamically below. """ - pass diff --git a/tools/emdump.py b/tools/emdump.py index 089d2a288df4a..04167e3546be6 100755 --- a/tools/emdump.py +++ b/tools/emdump.py @@ -122,14 +122,11 @@ def parse_parens(s): # Valid characters in Emscripten outputted JS content (in reality valid character set is much more complex, but do not need that here) def is_javascript_symbol_char(ch): i = ord(ch) - return (i >= 97 and i <= 122) or (i >= 65 and i <= 90) or (i >= 48 and i <= 57) or i == 36 or i == 95 # a-z, A-Z, 0-9, $, _ + return 97 <= i <= 122 or 65 <= i <= 90 or 48 <= i <= 57 or i in {36, 95} # a-z, A-Z, 0-9, $, _ def cxxfilt(): - filt = shutil.which('llvm-cxxfilt') - if filt: - return filt - return shutil.which('c++filt') + return shutil.which('llvm-cxxfilt') or shutil.which('c++filt') # Runs the given symbols list through c++filt to demangle. diff --git a/tools/emprofile.py b/tools/emprofile.py index 6b0259739a384..bbd4ce17eede5 100755 --- a/tools/emprofile.py +++ b/tools/emprofile.py @@ -44,7 +44,7 @@ def create_profiling_graph(outfile): if len(json_data.strip()) == 0: continue lines = json_data.split('\n') - lines = [x for x in lines if x != '[' and x != ']' and x != ',' and len(x.strip())] + lines = [x for x in lines if x not in {'[', ']', ','} and len(x.strip())] lines = [(x + ',') if not x.endswith(',') else x for x in lines] lines[-1] = lines[-1][:-1] json_data = '[' + '\n'.join(lines) + ']' @@ -96,7 +96,7 @@ def main(args): else: outfile = 'toolchain_profiler.results_' + time.strftime('%Y%m%d_%H%M') for i, arg in enumerate(args): - if arg.startswith('--outfile=') or arg.startswith('-o='): + if arg.startswith(('--outfile=', '-o=')): outfile = arg.split('=', 1)[1].strip().replace('.html', '') elif arg == '-o': outfile = args[i + 1].strip().replace('.html', '') diff --git a/tools/emscripten.py b/tools/emscripten.py index 0db61d81e9c61..8c1447caf4115 100644 --- a/tools/emscripten.py +++ b/tools/emscripten.py @@ -912,7 +912,7 @@ def install_wrapper(sym): # The emscripten stack functions are called very early (by writeStackCookie) before # the runtime is initialized so we can't create these wrappers that check for # runtimeInitialized. - if sym.startswith('_asan_') or sym.startswith('emscripten_stack_') or sym.startswith('_emscripten_stack_'): + if sym.startswith(('_asan_', 'emscripten_stack_', '_emscripten_stack_')): return False # Likewise `__trap` can occur before the runtime is initialized since it is used in # abort. diff --git a/tools/file_packager.py b/tools/file_packager.py index f2e2c7729fd01..c09236c74861e 100755 --- a/tools/file_packager.py +++ b/tools/file_packager.py @@ -428,7 +428,7 @@ def main(): # noqa: C901, PLR0912, PLR0915 plugin = utils.read_file(arg.split('=', 1)[1]) eval(plugin) # should append itself to plugins leading = '' - elif leading == 'preload' or leading == 'embed': + elif leading in {'preload', 'embed'}: mode = leading # position of @ if we're doing 'src@dst'. '__' is used to keep the index # same with the original if they escaped with '@@'. diff --git a/tools/link.py b/tools/link.py index 5d625eaa492ac..b69c38ac5df54 100644 --- a/tools/link.py +++ b/tools/link.py @@ -262,7 +262,7 @@ def is_supported(f): if using_lld: for flag, takes_arg in UNSUPPORTED_LLD_FLAGS.items(): # lld allows various flags to have either a single -foo or double --foo - if f.startswith(flag) or f.startswith('-' + flag): + if f.startswith((flag, '-' + flag)): diagnostics.warning('linkflags', 'ignoring unsupported linker flag: `%s`', f) # Skip the next argument if this linker flag takes and argument and that # argument was not specified as a separately (i.e. it was specified as @@ -275,7 +275,7 @@ def is_supported(f): return True, False # Silently ignore -l/-L flags when not using lld. If using lld allow # them to pass through the linker - if f.startswith('-l') or f.startswith('-L'): + if f.startswith(('-l', '-L')): return False, False diagnostics.warning('linkflags', 'ignoring unsupported linker flag: `%s`', f) return False, False diff --git a/tools/maint/gen_sig_info.py b/tools/maint/gen_sig_info.py index ae4a4c7371f0a..0f029e1c51d9f 100755 --- a/tools/maint/gen_sig_info.py +++ b/tools/maint/gen_sig_info.py @@ -176,7 +176,7 @@ def ignore_symbol(s, cxx): # Symbols that start with `emscripten_gl` or `emscripten_alc` are auto-generated # wrappers around GL and OpenGL symbols. Since they inherit their signature they # don't need to be auto-generated. - if s.startswith('emscripten_gl') or s.startswith('emscripten_alc'): + if s.startswith(('emscripten_gl', 'emscripten_alc')): return True if s.startswith('gl') and any(s.endswith(x) for x in ('NV', 'EXT', 'WEBGL', 'ARB', 'ANGLE')): return True diff --git a/tools/response_file.py b/tools/response_file.py index 93a2b939eba0c..fbe20a790aba2 100644 --- a/tools/response_file.py +++ b/tools/response_file.py @@ -84,7 +84,7 @@ def read_response_file(response_filename): # Guess encoding based on the file suffix components = os.path.basename(response_filename).split('.') encoding_suffix = components[-1].lower() - if len(components) > 1 and (encoding_suffix.startswith('utf') or encoding_suffix.startswith('cp') or encoding_suffix.startswith('iso') or encoding_suffix in ['ascii', 'latin-1']): + if len(components) > 1 and (encoding_suffix.startswith(('utf', 'cp', 'iso')) or encoding_suffix in {'ascii', 'latin-1'}): guessed_encoding = encoding_suffix else: # On windows, recent version of CMake emit rsp files containing diff --git a/tools/system_libs.py b/tools/system_libs.py index fefabe8195924..ea06d88515a74 100644 --- a/tools/system_libs.py +++ b/tools/system_libs.py @@ -672,8 +672,7 @@ def get_inheritance_tree(cls): """Returns all the classes in the inheritance tree of the current class.""" yield cls for subclass in cls.__subclasses__(): - for cls in subclass.get_inheritance_tree(): - yield cls + yield from subclass.get_inheritance_tree() @classmethod def get_all_variations(cls): @@ -1756,7 +1755,7 @@ def get_base_name(self): return name def can_use(self): - return super().can_use() and settings.MALLOC != 'none' and settings.MALLOC != 'mimalloc' + return super().can_use() and settings.MALLOC not in {'none', 'mimalloc'} @classmethod def vary_on(cls): diff --git a/tools/wasm-sourcemap.py b/tools/wasm-sourcemap.py index 15a8707231e6b..d94ff3e4d9067 100755 --- a/tools/wasm-sourcemap.py +++ b/tools/wasm-sourcemap.py @@ -121,7 +121,7 @@ def strip_debug_sections(wasm): name_len, name_pos = read_var_uint(wasm, section_body) name_end = name_pos + name_len name = wasm[name_pos:name_end] - if name == "linking" or name == "sourceMappingURL" or name.startswith("reloc..debug_") or name.startswith(".debug_"): + if name in {'linking', 'sourceMappingURL'} or name.startswith(('reloc..debug_', '.debug_')): continue # skip debug related sections stripped = stripped + wasm[section_start:pos]