From 1562895af7b537d620536e6a060942bcda595289 Mon Sep 17 00:00:00 2001 From: Nathan Ruiz Date: Sun, 15 Sep 2024 12:08:30 +0000 Subject: [PATCH] ci/lint: add pyupgrade check --- TOOLS/docutils-wrapper.py | 2 +- TOOLS/dylib_unhell.py | 102 ++++++++++++++++------------- TOOLS/file2string.py | 7 +- TOOLS/gen-interface-changes.py | 5 +- TOOLS/gen-mpv-desktop.py | 2 +- TOOLS/macos-swift-lib-directory.py | 2 +- TOOLS/matroska.py | 26 ++++---- TOOLS/osxbundle.py | 10 +-- TOOLS/stats-conv.py | 11 ++-- ci/lint-commit-msg.py | 13 ++-- pyproject.toml | 1 + 11 files changed, 98 insertions(+), 83 deletions(-) diff --git a/TOOLS/docutils-wrapper.py b/TOOLS/docutils-wrapper.py index 41aa063a6b..23c3552fd2 100755 --- a/TOOLS/docutils-wrapper.py +++ b/TOOLS/docutils-wrapper.py @@ -27,7 +27,7 @@ import sys def convert_depfile(output, depfile): - with open(depfile, "r") as f: + with open(depfile) as f: deps = f.readlines() with open(depfile, "w") as f: diff --git a/TOOLS/dylib_unhell.py b/TOOLS/dylib_unhell.py index 66d0a4474e..871cd5d711 100755 --- a/TOOLS/dylib_unhell.py +++ b/TOOLS/dylib_unhell.py @@ -1,11 +1,11 @@ #!/usr/bin/env python3 -import re +import json import os -import sys +import re import shutil import subprocess -import json +import sys from functools import partial sys_re = re.compile("^/System") @@ -20,13 +20,13 @@ def is_user_lib(objfile, libname): "libSystem." not in libname and \ "libc." not in libname and \ "libgcc." not in libname and \ - not os.path.basename(libname) == "Python" and \ + os.path.basename(libname) != "Python" and \ os.path.basename(objfile) not in libname and \ "libswift" not in libname def otool(objfile, rapths): - command = "otool -L '%s' | grep -e '\t' | awk '{ print $1 }'" % objfile - output = subprocess.check_output(command, shell = True, universal_newlines=True) + command = f"otool -L '{objfile}' | grep -e '\t' | awk '{{ print $1 }}'" + output = subprocess.check_output(command, shell=True, universal_newlines=True) libs = set(filter(partial(is_user_lib, objfile), output.split())) libs_resolved = set() @@ -41,16 +41,16 @@ def otool(objfile, rapths): def get_rapths(objfile): rpaths = [] - command = "otool -l '%s' | grep -A2 LC_RPATH | grep path" % objfile - pathRe = re.compile(r"^\s*path (.*) \(offset \d*\)$") + command = f"otool -l '{objfile}' | grep -A2 LC_RPATH | grep path" + path_re = re.compile(r"^\s*path (.*) \(offset \d*\)$") try: - result = subprocess.check_output(command, shell = True, universal_newlines=True) + result = subprocess.check_output(command, shell=True, universal_newlines=True) except Exception: return rpaths for line in result.splitlines(): - line_clean = pathRe.search(line).group(1).strip() + line_clean = path_re.search(line).group(1).strip() # resolve @loader_path if line_clean.startswith("@loader_path/"): line_clean = line_clean[len("@loader_path/"):] @@ -66,13 +66,11 @@ def get_rpaths_dev_tools(binary): 'grep "Xcode\\|CommandLineTools"' ) result = subprocess.check_output(command, shell = True, universal_newlines=True) - pathRe = re.compile(r"^\s*path (.*) \(offset \d*\)$") - output = [] - - for line in result.splitlines(): - output.append(pathRe.search(line).group(1).strip()) - - return output + path_re = re.compile(r"^\s*path (.*) \(offset \d*\)$") + return [ + path_re.search(line).group(1).strip() + for line in result.splitlines() + ] def resolve_lib_path(objfile, lib, rapths): if os.path.exists(lib): @@ -108,10 +106,9 @@ def get_homebrew_prefix(): result = "/opt/homebrew" try: result = subprocess.check_output( - "brew --prefix", + ["brew", "--prefix"], universal_newlines=True, - shell=True, - stderr=subprocess.DEVNULL + stderr=subprocess.DEVNULL, ).strip() except Exception: pass @@ -136,7 +133,16 @@ def install_name_tool_add_rpath(rpath, binary): def install_name_tool_delete_rpath(rpath, binary): subprocess.call(["install_name_tool", "-delete_rpath", rpath, binary]) -def libraries(objfile, result = dict(), result_relative = set(), rapths = []): +def libraries(objfile, result=None, result_relative=None, rapths=None): + if result is None: + result = {} + + if result_relative is None: + result_relative = set() + + if rapths is None: + rapths = [] + rapths = get_rapths(objfile) + rapths libs_list, libs_relative = otool(objfile, rapths) result[objfile] = libs_list @@ -185,38 +191,40 @@ def process_libraries(libs_dict, libs_dyn, binary): install_name_tool_change(lib, lib_name(lib), binary) def process_swift_libraries(binary): - command = ["xcrun", "--find", "swift-stdlib-tool"] - swiftStdlibTool = subprocess.check_output(command, universal_newlines=True).strip() + swift_stdlib_tool = subprocess.check_output( + ["xcrun", "--find", "swift-stdlib-tool"], + universal_newlines=True, + ).strip() # from xcode11 on the dynamic swift libs reside in a separate directory from # the std one, might need versioned paths for future swift versions - swiftLibPath = os.path.join(swiftStdlibTool, "../../lib/swift-5.0/macosx") - swiftLibPath = os.path.abspath(swiftLibPath) + swift_lib_path = os.path.join(swift_stdlib_tool, "../../lib/swift-5.0/macosx") + swift_lib_path = os.path.abspath(swift_lib_path) command = [ - swiftStdlibTool, "--copy", "--platform", "macosx", "--scan-executable", - binary, "--destination", lib_path(binary) + swift_stdlib_tool, "--copy", "--platform", "macosx", + "--scan-executable", binary, "--destination", lib_path(binary), ] - if os.path.exists(swiftLibPath): - command.extend(["--source-libraries", swiftLibPath]) + if os.path.exists(swift_lib_path): + command.extend(["--source-libraries", swift_lib_path]) subprocess.check_output(command, universal_newlines=True) print(">> setting additional rpath for swift libraries") install_name_tool_add_rpath("@executable_path/lib", binary) -def process_vulkan_loader(binary, loaderName, loaderRelativeFolder, libraryNode): +def process_vulkan_loader(binary, loader_name, loader_relative_folder, library_node): # https://github.com/KhronosGroup/Vulkan-Loader/blob/main/docs/LoaderDriverInterface.md#example-macos-driver-search-path # https://github.com/KhronosGroup/Vulkan-Loader/blob/main/docs/LoaderLayerInterface.md#macos-layer-discovery loaderSystemSearchFolders = [ - os.path.join(os.path.expanduser("~"), ".config", loaderRelativeFolder), - os.path.join("/etc/xdg", loaderRelativeFolder), - os.path.join("/usr/local/etc", loaderRelativeFolder), - os.path.join("/etc", loaderRelativeFolder), - os.path.join(os.path.expanduser("~"), ".local/share", loaderRelativeFolder), - os.path.join("/usr/local/share", loaderRelativeFolder), - os.path.join("/usr/share/vulkan", loaderRelativeFolder), - os.path.join(get_homebrew_prefix(), "share", loaderRelativeFolder), + os.path.join(os.path.expanduser("~"), ".config", loader_relative_folder), + os.path.join("/etc/xdg", loader_relative_folder), + os.path.join("/usr/local/etc", loader_relative_folder), + os.path.join("/etc", loader_relative_folder), + os.path.join(os.path.expanduser("~"), ".local/share", loader_relative_folder), + os.path.join("/usr/local/share", loader_relative_folder), + os.path.join("/usr/share/vulkan", loader_relative_folder), + os.path.join(get_homebrew_prefix(), "share", loader_relative_folder), ] loaderSystemFolder = "" @@ -226,35 +234,35 @@ def process_vulkan_loader(binary, loaderName, loaderRelativeFolder, libraryNode) break if not loaderSystemFolder: - print(">>> could not find loader folder " + loaderRelativeFolder) + print(">>> could not find loader folder " + loader_relative_folder) return - loaderBundleFolder = os.path.join(resources_path(binary), loaderRelativeFolder) - loaderSystemPath = os.path.join(loaderSystemFolder, loaderName) - loaderBundlePath = os.path.join(loaderBundleFolder, loaderName) + loaderBundleFolder = os.path.join(resources_path(binary), loader_relative_folder) + loaderSystemPath = os.path.join(loaderSystemFolder, loader_name) + loaderBundlePath = os.path.join(loaderBundleFolder, loader_name) libraryRelativeFolder = "../../../Frameworks/" if not os.path.exists(loaderSystemPath): - print(">>> could not find loader " + loaderName) + print(">>> could not find loader " + loader_name) return if not os.path.exists(loaderBundleFolder): os.makedirs(loaderBundleFolder) - loaderSystemFile = open(loaderSystemPath, "r") + loaderSystemFile = open(loaderSystemPath) loaderJsonData = json.load(loaderSystemFile) - libraryPath = loaderJsonData[libraryNode]["library_path"] + libraryPath = loaderJsonData[library_node]["library_path"] librarySystemPath = os.path.join(loaderSystemFolder, libraryPath) if not os.path.exists(librarySystemPath): print(">>> could not find loader library " + librarySystemPath) return - print(">>> modifiying and writing loader json " + loaderName) + print(">>> modifiying and writing loader json " + loader_name) loaderBundleFile = open(loaderBundlePath, "w") loaderLibraryName = os.path.basename(librarySystemPath) library_path = os.path.join(libraryRelativeFolder, loaderLibraryName) - loaderJsonData[libraryNode]["library_path"] = library_path + loaderJsonData[library_node]["library_path"] = library_path json.dump(loaderJsonData, loaderBundleFile, indent=4) print(">>> copying loader library " + loaderLibraryName) diff --git a/TOOLS/file2string.py b/TOOLS/file2string.py index 094176df5e..93efcc0ee6 100755 --- a/TOOLS/file2string.py +++ b/TOOLS/file2string.py @@ -25,10 +25,11 @@ import os import sys -def file2string(infilename, infile, outfile): - outfile.write("// Generated from %s\n\n" % infilename) - conv = ["\\%03o" % c for c in range(256)] +def file2string(infilename, infile, outfile): + outfile.write(f"// Generated from {infilename}\n\n") + + conv = [f"\\{c:03o}" for c in range(256)] safe_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" \ "0123456789!#%&'()*+,-./:;<=>[]^_{|}~ " diff --git a/TOOLS/gen-interface-changes.py b/TOOLS/gen-interface-changes.py index 9d8d1b8f59..affbe92054 100755 --- a/TOOLS/gen-interface-changes.py +++ b/TOOLS/gen-interface-changes.py @@ -26,11 +26,12 @@ import textwrap from shutil import which from subprocess import check_output + def add_new_entries(docs_dir, out, git): changes_dir = pathlib.Path(docs_dir) / "interface-changes" files = [] for f in pathlib.Path(changes_dir).glob("*.txt"): - if f.is_file() and not f.name == "example.txt": + if f.is_file() and f.name != "example.txt": timestamp = check_output([git, "log", "--format=%ct", "-n", "1", "--", f], encoding="UTF-8") if timestamp: @@ -73,7 +74,7 @@ if __name__ == "__main__": docs_dir = pathlib.Path(sys.argv[0]).resolve().parents[1] / "DOCS" interface_changes = docs_dir / "interface-changes.rst" - with open(interface_changes, "r") as f: + with open(interface_changes) as f: lines = [line.rstrip() for line in f] ver_line = " --- mpv 0." + major_version + ".0 ---" diff --git a/TOOLS/gen-mpv-desktop.py b/TOOLS/gen-mpv-desktop.py index f09498bb82..681633acda 100755 --- a/TOOLS/gen-mpv-desktop.py +++ b/TOOLS/gen-mpv-desktop.py @@ -24,7 +24,7 @@ import sys from subprocess import check_output if __name__ == "__main__": - with open(sys.argv[1], "r", encoding="UTF-8") as f: + with open(sys.argv[1], encoding="UTF-8") as f: next(f) mpv_desktop = dict([line.split("=", 1) for line in f]) diff --git a/TOOLS/macos-swift-lib-directory.py b/TOOLS/macos-swift-lib-directory.py index 2c2b149413..72b79d9d18 100755 --- a/TOOLS/macos-swift-lib-directory.py +++ b/TOOLS/macos-swift-lib-directory.py @@ -29,7 +29,7 @@ def find_swift_lib(): swift_lib_dir = os.path.join( xcode_path, - "Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx" + "Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx", ) if os.path.isdir(swift_lib_dir): return swift_lib_dir diff --git a/TOOLS/matroska.py b/TOOLS/matroska.py index 6b0c8a4556..9de9b07340 100755 --- a/TOOLS/matroska.py +++ b/TOOLS/matroska.py @@ -5,8 +5,8 @@ Can also be used to directly parse Matroska files and display their contents. """ import sys -from math import ldexp from binascii import hexlify +from math import ldexp # # This file is part of mpv. @@ -263,11 +263,11 @@ def camelcase_to_words(name): parts.append(name[start:]) return "_".join(parts).lower() -class MatroskaElement(object): +class MatroskaElement: def __init__(self, name, elid, valtype, namespace): self.name = name - self.definename = "{0}_ID_{1}".format(namespace, name.upper()) + self.definename = f"{namespace}_ID_{name.upper()}" self.fieldname = camelcase_to_words(name) self.structname = "ebml_" + self.fieldname self.elid = elid @@ -296,7 +296,7 @@ def parse_elems(elements, namespace): subelements = [] for el in elements: if isinstance(el, str): - name, hexid, eltype = [x.strip() for x in el.split(",")] + name, hexid, eltype = (x.strip() for x in el.split(",")) hexid = hexid.lower() multiple = name.endswith("*") name = name.strip("*") @@ -320,7 +320,7 @@ def generate_C_header(out): printf(out) for el in elementlist: - printf(out, "#define {0.definename:40} 0x{0.elid}".format(el)) + printf(out, f"#define {el.definename:40} 0x{el.elid}") printf(out) @@ -328,14 +328,14 @@ def generate_C_header(out): if not el.subelements: continue printf(out) - printf(out, "struct {0.structname} {{".format(el)) + printf(out, f"struct {el.structname} {{") length = max(len(subel.valname) for subel, multiple in el.subelements)+1 for subel, multiple in el.subelements: printf(out, " {e.valname:{length}} {star}{e.fieldname};".format( e=subel, length=length, star=" *"[multiple])) printf(out) for subel, multiple in el.subelements: - printf(out, " int n_{0.fieldname};".format(subel)) + printf(out, f" int n_{subel.fieldname};") printf(out, "};") for el in elementlist: @@ -355,14 +355,14 @@ def generate_C_definitions(out): printf(out) if el.subelements: printf(out, "#define N", el.fieldname) - printf(out, 'E_S("{0}", {1})'.format(el.name, len(el.subelements))) + printf(out, f'E_S("{el.name}", {len(el.subelements)})') for subel, multiple in el.subelements: - printf(out, "F({0.definename}, {0.fieldname}, {1})".format( - subel, int(multiple))) + msg = f"F({subel.definename}, {subel.fieldname}, {int(multiple)})" + printf(out, msg) printf(out, "}};") printf(out, "#undef N") else: - printf(out, 'E("{0.name}", {0.fieldname}, {0.ebmltype})'.format(el)) + printf(out, f'E("{el.name}", {el.fieldname}, {el.ebmltype})') def read(s, length): t = s.read(length) @@ -449,11 +449,11 @@ def parse_one(s, depth, parent, maxlen): if idelem is None: dec = "(UNKNOWN)" else: - dec = "({0.name})".format(idelem) + dec = f"({idelem.name})" if len(t) < 20: t = hexlify(t).decode("ascii") else: - t = "<{0} bytes>".format(len(t)) + t = f"<{len(t)} bytes>" print("binary", t, dec) elif elem.valtype == "uint": print("uint", read_uint(s, length)) diff --git a/TOOLS/osxbundle.py b/TOOLS/osxbundle.py index c440918e5f..c21661c318 100755 --- a/TOOLS/osxbundle.py +++ b/TOOLS/osxbundle.py @@ -1,13 +1,15 @@ #!/usr/bin/env python3 +import fileinput import os import shutil -import fileinput -import dylib_unhell import subprocess from optparse import OptionParser +import dylib_unhell + + def bundle_path(binary_name): - return "%s.app" % binary_name + return f"{binary_name}.app" def bundle_name(binary_name): return os.path.basename(bundle_path(binary_name)) @@ -72,7 +74,7 @@ def main(): version = bundle_version(src_path).rstrip() - print("Creating macOS application bundle (version: %s)..." % version) + print(f"Creating macOS application bundle (version: {version})...") print("> copying bundle skeleton") copy_bundle(binary_name, src_path) print("> copying binary") diff --git a/TOOLS/stats-conv.py b/TOOLS/stats-conv.py index 794c41fc57..d6baee5a0c 100755 --- a/TOOLS/stats-conv.py +++ b/TOOLS/stats-conv.py @@ -1,8 +1,9 @@ #!/usr/bin/env python3 -from PyQt6 import QtWidgets -import pyqtgraph as pg -import sys import re +import sys + +import pyqtgraph as pg +from PyQt6 import QtWidgets filename = sys.argv[1] @@ -77,7 +78,7 @@ colors = [ (1.0, 0.0, 0.0), (0.75, 0.75, 0), (0.0, 0.75, 0.75), - (0.75, 0, 0.75) + (0.75, 0, 0.75), ] def mkColor(t): @@ -85,7 +86,7 @@ def mkColor(t): SCALE = 1e6 # microseconds to seconds -with open(filename, "r") as file: +with open(filename) as file: for line in file: line = line.split("#")[0].strip() if not line: diff --git a/ci/lint-commit-msg.py b/ci/lint-commit-msg.py index 859519080a..f6862b35fd 100755 --- a/ci/lint-commit-msg.py +++ b/ci/lint-commit-msg.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 -import os -import sys import json -import subprocess +import os import re -from typing import Dict, Tuple, Callable, Optional +import subprocess +import sys +from typing import Callable, Dict, Optional, Tuple + def call(cmd) -> str: sys.stdout.flush() @@ -16,7 +17,7 @@ lint_rules: Dict[str, Tuple[Callable, str]] = {} # A lint rule should return True if everything is okay def lint_rule(description: str): def f(func): - assert func.__name__ not in lint_rules.keys() + assert func.__name__ not in lint_rules lint_rules[func.__name__] = (func, description) return f @@ -100,7 +101,7 @@ def line_too_long(body): return revert or len(body[0]) <= 72 @lint_rule( - "Prefix should not include file extension (use `vo_gpu: ...` not `vo_gpu.c: ...`)" + "Prefix should not include file extension (use `vo_gpu: ...` not `vo_gpu.c: ...`)", ) def no_file_exts(body): return not re.search(r"[a-z0-9]\.([chm]|cpp|swift|py): ", body[0]) diff --git a/pyproject.toml b/pyproject.toml index cca05c6e4e..be20dde845 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,5 +5,6 @@ line-length = 100 select = [ "F", # pyflakes "E", "W", # pycodestyle + "UP", # pyupgrade "Q", # flake8-quotes ]