Python fixes from `ruff check`
diff --git a/.circleci/config.yml b/.circleci/config.yml index 4ddd33b..5b1d3f5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml
@@ -75,7 +75,7 @@ .\test\test_bazel.ps1 jobs: - flake8: + lint: executor: ubuntu steps: - checkout @@ -85,12 +85,12 @@ apt-get update -q apt-get install -q -y python3-pip - run: - name: python3 flake8 + name: python lint command: | python3 -m pip install --upgrade pip - python3 -m pip install flake8==7.1.1 + python3 -m pip install flake8==7.1.1 ruff==0.14.1 python3 -m flake8 --show-source --statistics --extend-exclude=./scripts - + python3 -m ruff check test-linux: executor: ubuntu environment: @@ -315,9 +315,9 @@ - test-bazel-windows workflows: - flake8: + lint: jobs: - - flake8 + - lint test-linux: jobs: - test-linux
diff --git a/bazel/emscripten_toolchain/link_wrapper.py b/bazel/emscripten_toolchain/link_wrapper.py index 0e2573d..2215a2f 100644 --- a/bazel/emscripten_toolchain/link_wrapper.py +++ b/bazel/emscripten_toolchain/link_wrapper.py
@@ -14,7 +14,6 @@ bazel path. """ -from __future__ import print_function import argparse import os @@ -24,7 +23,7 @@ # Only argument should be @path/to/parameter/file assert sys.argv[1][0] == '@', sys.argv param_filename = sys.argv[1][1:] -param_file_args = [line.strip() for line in open(param_filename, 'r').readlines()] +param_file_args = [line.strip() for line in open(param_filename).readlines()] # Re-write response file if needed. if any(' ' in a for a in param_file_args): @@ -151,7 +150,7 @@ '--add-section=external_debug_info=' + base_name + '_debugsection.tmp']) # Make sure we have at least one output file. -if not len(files): +if not files: print('emcc.py did not appear to output any known files!') sys.exit(1)
diff --git a/emsdk.py b/emsdk.py index 19b9947..abdfbbc 100644 --- a/emsdk.py +++ b/emsdk.py
@@ -5,7 +5,6 @@ # found in the LICENSE file. import copy -from collections import OrderedDict import errno import json import multiprocessing @@ -20,14 +19,16 @@ import sysconfig import tarfile import zipfile +from collections import OrderedDict + if os.name == 'nt': - import winreg import ctypes.wintypes + import winreg from urllib.parse import urljoin from urllib.request import urlopen -if sys.version_info < (3, 2): +if sys.version_info < (3, 2): # noqa: UP036 print(f'error: emsdk requires python 3.2 or above ({sys.executable} {sys.version})', file=sys.stderr) sys.exit(1) @@ -50,7 +51,10 @@ # being run. Useful for debugging. VERBOSE = int(os.getenv('EMSDK_VERBOSE', '0')) QUIET = int(os.getenv('EMSDK_QUIET', '0')) -TTY_OUTPUT = not os.getenv('EMSDK_NOTTY', not sys.stdout.isatty()) +if os.getenv('EMSDK_NOTTY'): + TTY_OUTPUT = False +else: + TTY_OUTPUT = sys.stdout.isatty() def info(msg): @@ -131,7 +135,7 @@ # platform.machine() may return AMD64 on windows, so standardize the case. machine = os.getenv('EMSDK_ARCH', platform.machine().lower()) -if machine.startswith('x64') or machine.startswith('amd64') or machine.startswith('x86_64'): +if machine.startswith(('x64', 'amd64', 'x86_64')): ARCH = 'x86_64' elif machine.endswith('86'): ARCH = 'x86' @@ -323,7 +327,7 @@ os.chmod(path, stat.S_IWRITE) func(path) else: - raise + raise exc_info[1] shutil.rmtree(d, onerror=remove_readonly_and_try_again) except Exception as e: debug_print('remove_tree threw an exception, ignoring: ' + str(e)) @@ -718,7 +722,7 @@ # On success, returns the filename on the disk pointing to the destination file that was produced # On failure, returns None. def download_file(url, dstpath, download_even_if_exists=False, - filename_prefix='', silent=False): + filename_prefix=''): debug_print(f'download_file(url={url}, dstpath={dstpath})') file_name = get_download_target(url, dstpath, filename_prefix) @@ -934,19 +938,19 @@ return os.path.join(build_dir, 'bin') -def build_env(generator): - build_env = os.environ.copy() +def build_env(): + env = os.environ.copy() # To work around a build issue with older Mac OS X builds, add -stdlib=libc++ to all builds. # See https://groups.google.com/forum/#!topic/emscripten-discuss/5Or6QIzkqf0 if MACOS: - build_env['CXXFLAGS'] = ((build_env['CXXFLAGS'] + ' ') if hasattr(build_env, 'CXXFLAGS') else '') + '-stdlib=libc++' + env['CXXFLAGS'] = ((env['CXXFLAGS'] + ' ') if hasattr(env, 'CXXFLAGS') else '') + '-stdlib=libc++' if WINDOWS: # MSBuild.exe has an internal mechanism to avoid N^2 oversubscription of threads in its two-tier build model, see # https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/ - build_env['UseMultiToolTask'] = 'true' - build_env['EnforceProcessCountAcrossBuilds'] = 'true' - return build_env + env['UseMultiToolTask'] = 'true' + env['EnforceProcessCountAcrossBuilds'] = 'true' + return env # Find path to cmake executable, as one of the activated tools, in PATH, or from installed tools. @@ -1010,7 +1014,7 @@ # Build try: print('Running build: ' + str(make)) - ret = subprocess.check_call(make, cwd=build_root, env=build_env(CMAKE_GENERATOR)) + ret = subprocess.check_call(make, cwd=build_root, env=build_env()) if ret != 0: errlog('Build failed with exit code {ret}!') errlog('Working directory: ' + build_root) @@ -1024,7 +1028,7 @@ return True -def cmake_configure(generator, build_root, src_root, build_type, extra_cmake_args=[]): +def cmake_configure(generator, build_root, src_root, build_type, extra_cmake_args): debug_print('cmake_configure(generator=' + str(generator) + ', build_root=' + str(build_root) + ', src_root=' + str(src_root) + ', build_type=' + str(build_type) + ', extra_cmake_args=' + str(extra_cmake_args) + ')') # Configure if not os.path.isdir(build_root): @@ -1057,7 +1061,7 @@ # Create a file 'recmake.bat/sh' in the build root that user can call to # manually recmake the build tree with the previous build params open(os.path.join(build_root, 'recmake.' + ('bat' if WINDOWS else 'sh')), 'w').write(' '.join(map(quote_parens, cmdline))) - ret = subprocess.check_call(cmdline, cwd=build_root, env=build_env(CMAKE_GENERATOR)) + ret = subprocess.check_call(cmdline, cwd=build_root, env=build_env()) if ret != 0: errlog('CMake invocation failed with exit code {ret}!') errlog('Working directory: ' + build_root) @@ -1085,9 +1089,7 @@ def xcode_sdk_version(): try: - output = subprocess.check_output(['xcrun', '--show-sdk-version']) - if sys.version_info >= (3,): - output = output.decode('utf8') + output = subprocess.check_output(['xcrun', '--show-sdk-version'], universal_newlines=True) return output.strip().split('.') except Exception: return subprocess.checkplatform.mac_ver()[0].split('.') @@ -1114,7 +1116,7 @@ 'arm64': 'ARM64', 'arm': 'ARM', 'x86_64': 'x64', - 'x86': 'x86' + 'x86': 'x86', } return arch_to_cmake_host_platform[ARCH] @@ -1152,7 +1154,7 @@ enable_assertions = ENABLE_LLVM_ASSERTIONS.lower() == 'on' or (ENABLE_LLVM_ASSERTIONS == 'auto' and build_type.lower() != 'release' and build_type.lower() != 'minsizerel') - if ARCH == 'x86' or ARCH == 'x86_64': + if ARCH in ('x86', 'x86_64'): targets_to_build = 'WebAssembly;X86' elif ARCH == 'arm': targets_to_build = 'WebAssembly;ARM' @@ -1506,7 +1508,7 @@ # Binaryen build scripts: def binaryen_build_root(tool): build_root = tool.installation_path().strip() - if build_root.endswith('/') or build_root.endswith('\\'): + if build_root.endswith(('/', '\\')): build_root = build_root[:-1] generator_prefix = cmake_generator_prefix() build_root = build_root + generator_prefix + '_' + str(tool.bitness) + 'bit_binaryen' @@ -1561,19 +1563,18 @@ url = urljoin(emsdk_packages_url, archive) - def try_download(url, silent=False): - return download_file(url, download_dir, not KEEP_DOWNLOADS, - filename_prefix, silent=silent) + def try_download(url): + return download_file(url, download_dir, not KEEP_DOWNLOADS, filename_prefix) # Special hack for the wasm-binaries we transitioned from `.bzip2` to # `.xz`, but we can't tell from the version/url which one to use, so # try one and then fall back to the other. success = False if 'wasm-binaries' in archive and os.path.splitext(archive)[1] == '.xz': - success = try_download(url, silent=True) + success = try_download(url) if not success: alt_url = url.replace('.tar.xz', '.tbz2') - success = try_download(alt_url, silent=True) + success = try_download(alt_url) if success: url = alt_url @@ -1647,7 +1648,7 @@ EM_CONFIG_DICT.clear() lines = [] try: - lines = open(EM_CONFIG_PATH, "r").read().split('\n') + lines = open(EM_CONFIG_PATH).read().split('\n') except Exception: pass for line in lines: @@ -1999,14 +2000,13 @@ def is_installed_version(self): version_file_path = self.get_version_file_path() if os.path.isfile(version_file_path): - with open(version_file_path, 'r') as version_file: + with open(version_file_path) as version_file: return version_file.read().strip() == self.name return False def update_installed_version(self): with open(self.get_version_file_path(), 'w') as version_file: version_file.write(self.name + '\n') - return None def is_installed(self, skip_version_check=False): # If this tool/sdk depends on other tools, require that all dependencies are @@ -2178,7 +2178,7 @@ 'build_ninja': build_ninja, 'build_ccache': build_ccache, 'download_node_nightly': download_node_nightly, - 'download_firefox': download_firefox + 'download_firefox': download_firefox, } if hasattr(self, 'custom_install_script') and self.custom_install_script in custom_install_scripts: success = custom_install_scripts[self.custom_install_script](self) @@ -2425,11 +2425,11 @@ # Lists all legacy (pre-emscripten-releases) tagged versions directly in the Git # repositories. These we can pull and compile from source. def load_legacy_emscripten_tags(): - return open(sdk_path('legacy-emscripten-tags.txt'), 'r').read().split('\n') + return open(sdk_path('legacy-emscripten-tags.txt')).read().split('\n') def load_legacy_binaryen_tags(): - return open(sdk_path('legacy-binaryen-tags.txt'), 'r').read().split('\n') + return open(sdk_path('legacy-binaryen-tags.txt')).read().split('\n') def remove_prefix(s, prefix): @@ -2461,7 +2461,7 @@ def load_releases_info(): if not hasattr(load_releases_info, 'cached_info'): try: - text = open(sdk_path('emscripten-releases-tags.json'), 'r').read() + text = open(sdk_path('emscripten-releases-tags.json')).read() load_releases_info.cached_info = json.loads(text) except Exception as e: print('Error parsing emscripten-releases-tags.json!') @@ -2484,7 +2484,7 @@ tags = [] info = load_releases_info() - for version, sha in sorted(info['releases'].items(), key=lambda x: version_key(x[0])): + for _version, sha in sorted(info['releases'].items(), key=lambda x: version_key(x[0])): tags.append(sha) if extra_release_tag: @@ -2508,7 +2508,7 @@ def load_sdk_manifest(): try: - manifest = json.loads(open(sdk_path("emsdk_manifest.json"), "r").read()) + manifest = json.loads(open(sdk_path("emsdk_manifest.json")).read()) except Exception as e: print('Error parsing emsdk_manifest.json!') print(str(e)) @@ -2679,7 +2679,7 @@ if tools_to_activate: tools = [x for x in tools_to_activate if not x.is_sdk] - print('Setting the following tools as active:\n ' + '\n '.join(map(lambda x: str(x), tools))) + print('Setting the following tools as active:\n ' + '\n '.join([str(t) for t in tools])) print('') generate_em_config(tools_to_activate, permanently_activate, system) @@ -2889,9 +2889,9 @@ # of the SDK but we want to remove that from the current environment # if no such tool is active. # Ignore certain keys that are inputs to emsdk itself. - ignore_keys = set(['EMSDK_POWERSHELL', 'EMSDK_CSH', 'EMSDK_CMD', 'EMSDK_BASH', 'EMSDK_FISH', - 'EMSDK_NUM_CORES', 'EMSDK_NOTTY', 'EMSDK_KEEP_DOWNLOADS']) - env_keys_to_add = set(pair[0] for pair in env_vars_to_add) + ignore_keys = {'EMSDK_POWERSHELL', 'EMSDK_CSH', 'EMSDK_CMD', 'EMSDK_BASH', 'EMSDK_FISH', + 'EMSDK_NUM_CORES', 'EMSDK_NOTTY', 'EMSDK_KEEP_DOWNLOADS'} + env_keys_to_add = {pair[0] for pair in env_vars_to_add} for key in os.environ: if key.startswith('EMSDK_') or key in ('EM_CACHE', 'EM_CONFIG'): if key not in env_keys_to_add and key not in ignore_keys: @@ -2955,7 +2955,7 @@ return name -def main(args): +def main(args): # noqa: C901, PLR0911, PLR0912, PLR0915 if not args: errlog("Missing command; Type 'emsdk help' to get a list of commands.") return 1 @@ -3182,7 +3182,7 @@ sdk = find_sdk(name) return 'INSTALLED' if sdk and sdk.is_installed() else '' - if (LINUX or MACOS or WINDOWS) and (ARCH == 'x86' or ARCH == 'x86_64'): + if (LINUX or MACOS or WINDOWS) and ARCH in ('x86', 'x86_64'): print('The *recommended* precompiled SDK download is %s (%s).' % (find_latest_version(), find_latest_hash())) print() print('To install/activate it use:') @@ -3310,7 +3310,7 @@ elif cmd == 'update-tags': errlog('`update-tags` is not longer needed. To install the latest tot release just run `install tot`') return 0 - elif cmd == 'activate' or cmd == 'deactivate': + elif cmd in ('activate', 'deactivate'): if arg_permanent: print('Registering active Emscripten environment permanently') print('')
diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..3dbeb8b --- /dev/null +++ b/pyproject.toml
@@ -0,0 +1,74 @@ +[project] +requires-python = ">=3.2" + +[tool.ruff] +line-length = 100 +exclude = [ + "./cache/", + "./node_modules/", + "./site/source/_themes/", + "./site/source/conf.py", + "./system/lib/", + "./test/third_party/", + "./third_party/", + "./tools/filelock.py", + "./tools/scons/", + ".git", +] + +lint.select = [ + "ARG", + "ASYNC", + "B", + "C4", + "C90", + "COM", + "E", + "F", + "I", + "PERF", + "PIE", + "PL", + "UP", + "W", + "YTT", +] +lint.external = [ "D" ] +lint.ignore = [ + "B011", # See https://github.com/PyCQA/flake8-bugbear/issues/66 + "B023", + "B026", + "E402", + "E501", + "E721", + "E741", + "PERF203", + "PERF401", + "PLC0415", + "PLR0915", + "PLR1704", + "PLR5501", + "PLW0602", + "PLW0603", + "PLW1510", + "PLW2901", + "UP030", # TODO + "UP031", # TODO + "UP032", # TODO +] +lint.per-file-ignores."emrun.py" = [ "PLE0704" ] +lint.per-file-ignores."tools/ports/*.py" = [ "ARG001", "ARG005" ] +lint.per-file-ignores."test/other/ports/*.py" = [ "ARG001" ] +lint.per-file-ignores."test/parallel_testsuite.py" = [ "ARG002" ] +lint.per-file-ignores."test/test_benchmark.py" = [ "ARG002" ] +lint.mccabe.max-complexity = 51 # Recommended: 10 +lint.pylint.allow-magic-value-types = [ + "bytes", + "float", + "int", + "str", +] +lint.pylint.max-args = 15 # Recommended: 5 +lint.pylint.max-branches = 50 # Recommended: 12 +lint.pylint.max-returns = 16 # Recommended: 6 +lint.pylint.max-statements = 142 # Recommended: 50
diff --git a/scripts/update_bazel_workspace.py b/scripts/update_bazel_workspace.py index 637c355..ac7428b 100755 --- a/scripts/update_bazel_workspace.py +++ b/scripts/update_bazel_workspace.py
@@ -9,9 +9,10 @@ import json import os import re -import requests import sys +import requests + STORAGE_URL = 'https://storage.googleapis.com/webassembly/emscripten-releases-builds' EMSDK_ROOT = os.path.dirname(os.path.dirname(__file__)) @@ -51,7 +52,7 @@ def insert_revision(item): - with open(BAZEL_REVISIONS_FILE, 'r') as f: + with open(BAZEL_REVISIONS_FILE) as f: lines = f.readlines() lines.insert(lines.index('EMSCRIPTEN_TAGS = {\n') + 1, item) @@ -61,7 +62,7 @@ def update_module_version(version): - with open(BAZEL_MODULE_FILE, 'r') as f: + with open(BAZEL_MODULE_FILE) as f: content = f.read() pattern = r'(module\(\s*name = "emsdk",\s*version = )"\d+.\d+.\d+",\n\)' @@ -74,7 +75,7 @@ f.write(content) -def main(argv): +def main(): version, latest_hash = get_latest_info() update_module_version(version) item = revisions_item(version, latest_hash) @@ -84,4 +85,4 @@ if __name__ == '__main__': - sys.exit(main(sys.argv)) + sys.exit(main())
diff --git a/scripts/update_node.py b/scripts/update_node.py index 61e04f8..257bb74 100755 --- a/scripts/update_node.py +++ b/scripts/update_node.py
@@ -11,11 +11,12 @@ directory. """ -import urllib.request -import subprocess -import sys import os import shutil +import subprocess +import sys +import urllib.request + from zip import unzip_cmd, zip_cmd # When adjusting this version, visit
diff --git a/scripts/update_python.py b/scripts/update_python.py index f80327d..a9d9d60 100755 --- a/scripts/update_python.py +++ b/scripts/update_python.py
@@ -26,10 +26,11 @@ import multiprocessing import os import platform -import urllib.request import shutil import sys +import urllib.request from subprocess import check_call + from zip import unzip_cmd, zip_cmd version = '3.13.3'