diff options
-rw-r--r-- | .github/workflows/nightly.yml | 25 | ||||
-rw-r--r-- | qutebrowser/api/cmdutils.py | 31 | ||||
-rwxr-xr-x | scripts/dev/build_release.py | 84 | ||||
-rw-r--r-- | tox.ini | 2 |
4 files changed, 55 insertions, 87 deletions
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 2502d017b..18c12e053 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -19,47 +19,34 @@ jobs: toxenv: build-release-qt5 name: qt5-macos - os: windows-2019 - args: --64bit branch: main toxenv: build-release-qt5 - name: qt5-windows-64bit - - os: windows-2019 - args: --32bit - branch: main - toxenv: build-release-qt5 - name: qt5-windows-32bit - + name: qt5-windows - os: macos-11 args: --debug branch: main toxenv: build-release-qt5 name: qt5-macos-debug - os: windows-2019 - args: --64bit --debug - branch: main - toxenv: build-release-qt5 - name: qt5-windows-64bit-debug - - os: windows-2019 - args: --32bit --debug + args: --debug branch: main toxenv: build-release-qt5 - name: qt5-windows-32bit-debug + name: qt5-windows-debug - os: macos-11 toxenv: build-release name: macos - os: windows-2019 - args: --64bit toxenv: build-release - name: windows-64bit + name: windows - os: macos-11 args: --debug toxenv: build-release name: macos-debug - os: windows-2019 - args: --64bit --debug + args: --debug toxenv: build-release - name: windows-64bit-debug + name: windows-debug runs-on: "${{ matrix.os }}" timeout-minutes: 45 steps: diff --git a/qutebrowser/api/cmdutils.py b/qutebrowser/api/cmdutils.py index 067ebca92..0c367c6bf 100644 --- a/qutebrowser/api/cmdutils.py +++ b/qutebrowser/api/cmdutils.py @@ -35,7 +35,7 @@ Possible values: import inspect -from typing import Any, Callable, Iterable +from typing import Any, Callable, Iterable, Protocol, Optional, Dict, cast from qutebrowser.utils import qtutils from qutebrowser.commands import command, cmdexc @@ -90,7 +90,21 @@ def check_exclusive(flags: Iterable[bool], names: Iterable[str]) -> None: raise CommandError("Only one of {} can be given!".format(argstr)) -_CmdHandlerType = Callable[..., Any] +_CmdHandlerFunc = Callable[..., Any] + + +class _CmdHandlerType(Protocol): + + """A qutebrowser command function, which had qute_args patched on it. + + Applying @cmdutils.argument to a function will patch it with a qute_args attribute. + Below, we cast the decorated function to _CmdHandlerType to make mypy aware of this. + """ + + qute_args: Optional[Dict[str, command.ArgInfo]] + + def __call__(self, *args: Any, **kwargs: Any) -> Any: + ... class register: # noqa: N801,N806 pylint: disable=invalid-name @@ -118,7 +132,7 @@ class register: # noqa: N801,N806 pylint: disable=invalid-name # The arguments to pass to Command. self._kwargs = kwargs - def __call__(self, func: _CmdHandlerType) -> _CmdHandlerType: + def __call__(self, func: _CmdHandlerFunc) -> _CmdHandlerType: """Register the command before running the function. Gets called when a function should be decorated. @@ -158,7 +172,8 @@ class register: # noqa: N801,N806 pylint: disable=invalid-name # This is checked by future @cmdutils.argument calls so they fail # (as they'd be silently ignored otherwise) - func.qute_args = None # type: ignore[attr-defined] + func = cast(_CmdHandlerType, func) + func.qute_args = None return func @@ -210,19 +225,21 @@ class argument: # noqa: N801,N806 pylint: disable=invalid-name self._argname = argname # The name of the argument to handle. self._kwargs = kwargs # Valid ArgInfo members. - def __call__(self, func: _CmdHandlerType) -> _CmdHandlerType: + def __call__(self, func: _CmdHandlerFunc) -> _CmdHandlerType: funcname = func.__name__ if self._argname not in inspect.signature(func).parameters: raise ValueError("{} has no argument {}!".format(funcname, self._argname)) + + func = cast(_CmdHandlerType, func) if not hasattr(func, 'qute_args'): - func.qute_args = {} # type: ignore[attr-defined] + func.qute_args = {} elif func.qute_args is None: raise ValueError("@cmdutils.argument got called above (after) " "@cmdutils.register for {}!".format(funcname)) arginfo = command.ArgInfo(**self._kwargs) - func.qute_args[self._argname] = arginfo # type: ignore[attr-defined] + func.qute_args[self._argname] = arginfo return func diff --git a/scripts/dev/build_release.py b/scripts/dev/build_release.py index 1ddef5cc0..73689ea88 100755 --- a/scripts/dev/build_release.py +++ b/scripts/dev/build_release.py @@ -340,7 +340,7 @@ def build_mac( gh_token=gh_token) utils.print_title("Building .app via pyinstaller") - call_tox(f'pyinstaller-64bit{"-qt5" if qt5 else ""}', '-r', debug=debug) + call_tox(f'pyinstaller{"-qt5" if qt5 else ""}', '-r', debug=debug) utils.print_title("Patching .app") patch_mac_app(qt5=qt5) utils.print_title("Re-signing .app") @@ -388,18 +388,14 @@ def build_mac( ] -def _get_windows_python_path(x64: bool) -> pathlib.Path: +def _get_windows_python_path() -> pathlib.Path: """Get the path to Python.exe on Windows.""" parts = str(sys.version_info.major), str(sys.version_info.minor) ver = ''.join(parts) dot_ver = '.'.join(parts) - if x64: - path = rf'SOFTWARE\Python\PythonCore\{dot_ver}\InstallPath' - fallback = pathlib.Path('C:', f'Python{ver}', 'python.exe') - else: - path = rf'SOFTWARE\WOW6432Node\Python\PythonCore\{dot_ver}-32\InstallPath' - fallback = pathlib.Path('C:', f'Python{ver}-32', 'python.exe') + path = rf'SOFTWARE\Python\PythonCore\{dot_ver}\InstallPath' + fallback = pathlib.Path('C:', f'Python{ver}', 'python.exe') try: key = winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, path) @@ -409,47 +405,39 @@ def _get_windows_python_path(x64: bool) -> pathlib.Path: def _build_windows_single( - *, x64: bool, + *, qt5: bool, skip_packaging: bool, debug: bool, ) -> List[Artifact]: - """Build on Windows for a single architecture.""" - human_arch = '64-bit' if x64 else '32-bit' - utils.print_title(f"Running pyinstaller {human_arch}") + """Build on Windows for a single build type.""" + utils.print_title("Running pyinstaller") dist_path = pathlib.Path("dist") - arch = "x64" if x64 else "x86" - out_path = dist_path / f'qutebrowser-{qutebrowser.__version__}-{arch}' + out_path = dist_path / f'qutebrowser-{qutebrowser.__version__}' _maybe_remove(out_path) - python = _get_windows_python_path(x64=x64) - suffix = "64bit" if x64 else "32bit" - if qt5: - # FIXME:qt6 does this regress 391623d5ec983ecfc4512c7305c4b7a293ac3872? - suffix += "-qt5" - call_tox(f'pyinstaller-{suffix}', '-r', python=python, debug=debug) + python = _get_windows_python_path() + # FIXME:qt6 does this regress 391623d5ec983ecfc4512c7305c4b7a293ac3872? + suffix = "-qt5" if qt5 else "" + call_tox(f'pyinstaller{suffix}', '-r', python=python, debug=debug) out_pyinstaller = dist_path / "qutebrowser" shutil.move(out_pyinstaller, out_path) exe_path = out_path / 'qutebrowser.exe' - utils.print_title(f"Verifying {human_arch} exe") + utils.print_title("Verifying exe") verify_windows_exe(exe_path) - utils.print_title(f"Running {human_arch} smoke test") + utils.print_title("Running smoke test") smoke_test(exe_path, debug=debug, qt5=qt5) if skip_packaging: return [] - utils.print_title(f"Packaging {human_arch}") + utils.print_title("Packaging") return _package_windows_single( - nsis_flags=[] if x64 else ['/DX86'], out_path=out_path, - filename_arch='amd64' if x64 else 'win32', - desc_arch=human_arch, - desc_suffix='' if x64 else ' (only for 32-bit Windows!)', debug=debug, qt5=qt5, ) @@ -458,8 +446,6 @@ def _build_windows_single( def build_windows( *, gh_token: str, skip_packaging: bool, - only_32bit: bool, - only_64bit: bool, qt5: bool, debug: bool, ) -> List[Artifact]: @@ -470,37 +456,23 @@ def build_windows( utils.print_title("Building Windows binaries") - artifacts = [] - from scripts.dev import gen_versioninfo utils.print_title("Updating VersionInfo file") gen_versioninfo.main() - if not only_32bit: - artifacts += _build_windows_single( - x64=True, - skip_packaging=skip_packaging, - debug=debug, - qt5=qt5, - ) - if not only_64bit and qt5: - artifacts += _build_windows_single( - x64=False, + artifacts = [ + _build_windows_single( skip_packaging=skip_packaging, debug=debug, qt5=qt5, - ) - + ), + ] return artifacts def _package_windows_single( *, - nsis_flags: List[str], out_path: pathlib.Path, - desc_arch: str, - desc_suffix: str, - filename_arch: str, debug: bool, qt5: bool, ) -> List[Artifact]: @@ -508,15 +480,14 @@ def _package_windows_single( artifacts = [] dist_path = pathlib.Path("dist") - utils.print_subtitle(f"Building {desc_arch} installer...") + utils.print_subtitle("Building installer...") subprocess.run(['makensis.exe', - f'/DVERSION={qutebrowser.__version__}', *nsis_flags, + f'/DVERSION={qutebrowser.__version__}', 'misc/nsis/qutebrowser.nsi'], check=True) name_parts = [ 'qutebrowser', str(qutebrowser.__version__), - filename_arch, ] if debug: name_parts.append('debug') @@ -527,16 +498,15 @@ def _package_windows_single( artifacts.append(Artifact( path=dist_path / name, mimetype='application/vnd.microsoft.portable-executable', - description=f'Windows {desc_arch} installer{desc_suffix}', + description='Windows installer', )) - utils.print_subtitle(f"Zipping {desc_arch} standalone...") + utils.print_subtitle("Zipping standalone...") zip_name_parts = [ 'qutebrowser', str(qutebrowser.__version__), 'windows', 'standalone', - filename_arch, ] if debug: zip_name_parts.append('debug') @@ -549,7 +519,7 @@ def _package_windows_single( artifacts.append(Artifact( path=zip_path, mimetype='application/zip', - description=f'Windows {desc_arch} standalone{desc_suffix}', + description='Windows standalone', )) return artifacts @@ -720,10 +690,6 @@ def main() -> None: help="Skip confirmation before uploading.") parser.add_argument('--skip-packaging', action='store_true', required=False, help="Skip Windows installer/zip generation or macOS DMG.") - parser.add_argument('--32bit', action='store_true', required=False, - help="Skip Windows 64 bit build.", dest='only_32bit') - parser.add_argument('--64bit', action='store_true', required=False, - help="Skip Windows 32 bit build.", dest='only_64bit') parser.add_argument('--debug', action='store_true', required=False, help="Build a debug build.") parser.add_argument('--qt5', action='store_true', required=False, @@ -754,8 +720,6 @@ def main() -> None: artifacts = build_windows( gh_token=gh_token, skip_packaging=args.skip_packaging, - only_32bit=args.only_32bit, - only_64bit=args.only_64bit, qt5=args.qt5, debug=args.debug, ) @@ -181,7 +181,7 @@ commands = {envpython} scripts/dev/check_doc_changes.py {posargs} {envpython} scripts/asciidoc2html.py {posargs} -[testenv:pyinstaller-{64bit,32bit}{,-qt5}] +[testenv:pyinstaller{,-qt5}] basepython = {env:PYTHON:python3} passenv = APPDATA |