pmb: Add more type hints (MR 2489)

This commit is contained in:
Newbyte 2024-11-14 23:16:29 +01:00
parent 0e9a2e596f
commit 472726a9dc
No known key found for this signature in database
GPG key ID: 5AE7F5513E0885CB
9 changed files with 79 additions and 28 deletions

View file

@ -192,7 +192,7 @@ def _init(pkgname: str, arch: Arch | None) -> tuple[str, Arch, Any, Chroot, Env]
extract_and_patch_sources(pkgname, arch)
env = {
env: Env = {
"ARCH": arch.kernel(),
}

View file

@ -77,7 +77,7 @@ class BuildStatus(enum.Enum):
def __str__(self) -> str:
return self.value
def necessary(self):
def necessary(self) -> bool:
return self in [BuildStatus.OUTDATED, BuildStatus.NEW]
@ -132,7 +132,7 @@ def get_status(arch: Arch | None, apkbuild: dict[str, Any]) -> BuildStatus:
return BuildStatus.UNNECESSARY
def index_repo(arch=None):
def index_repo(arch: Arch | None = None) -> None:
"""Recreate the APKINDEX.tar.gz for a specific repo, and clear the parsing
cache for that file for the current pmbootstrap session (to prevent
rebuilding packages twice, in case the rebuild takes less than a second).

View file

@ -11,7 +11,7 @@ import pmb.parse
import pmb.chroot.apk
def is_registered(arch_qemu: Arch) -> bool:
def is_registered(arch_qemu: str | Arch) -> bool:
return os.path.exists(f"/proc/sys/fs/binfmt_misc/qemu-{arch_qemu}")

View file

@ -65,7 +65,7 @@ class Arch(enum.Enum):
global _cached_native_arch
return _cached_native_arch
def is_native(self):
def is_native(self) -> bool:
return self == Arch.native()
@staticmethod
@ -87,7 +87,7 @@ class Arch(enum.Enum):
]
)
def kernel(self):
def kernel(self) -> str:
mapping = {
Arch.x86: "x86",
Arch.x86_64: "x86_64",
@ -102,7 +102,7 @@ class Arch(enum.Enum):
}
return mapping.get(self, self.value)
def qemu(self):
def qemu(self) -> str:
mapping = {
Arch.x86: "i386",
Arch.armhf: "arm",
@ -110,7 +110,7 @@ class Arch(enum.Enum):
}
return mapping.get(self, self.value)
def alpine_triple(self):
def alpine_triple(self) -> str:
"""Get the cross compiler triple for this architecture on Alpine."""
mapping = {
Arch.aarch64: "aarch64-alpine-linux-musl",
@ -139,7 +139,7 @@ class Arch(enum.Enum):
raise ValueError(f"Can not map Alpine architecture '{self}'" " to the right hostspec value")
def cpu_emulation_required(self):
def cpu_emulation_required(self) -> bool:
# Obvious case: host arch is target arch
if self == Arch.native():
return False

View file

@ -14,12 +14,12 @@ from pmb.core.context import get_context
class ReadlineTabCompleter:
"""Store intermediate state for completer function."""
def __init__(self, options):
def __init__(self, options: list[str]) -> None:
""":param options: list of possible completions."""
self.options = sorted(options)
self.matches = []
self.matches: list[str] = []
def completer_func(self, input_text, iteration):
def completer_func(self, input_text: str, iteration: int) -> str | None:
"""
:param input_text: text that shall be autocompleted
:param iteration: how many times "tab" was hit
@ -104,7 +104,9 @@ def ask(
)
def confirm(question="Continue?", default=False, no_assumptions=False):
def confirm(
question: str = "Continue?", default: bool = False, no_assumptions: bool = False
) -> bool:
"""Convenience wrapper around ask for simple yes-no questions with validation.
:param no_assumptions: ask for confirmation, even if "pmbootstrap -y' is set
@ -118,7 +120,7 @@ def confirm(question="Continue?", default=False, no_assumptions=False):
return answer == "y"
def progress_print(progress):
def progress_print(progress: float) -> None:
"""Print a snapshot of a progress bar to STDOUT.
Call progress_flush to end printing progress and clear the line. No output is printed in
@ -141,7 +143,7 @@ def progress_print(progress):
sys.stdout.write("\u001b8\u001b[0K")
def progress_flush():
def progress_flush() -> None:
"""Finish printing a progress bar.
This will erase the line. Does nothing in non-interactive mode.

View file

@ -19,7 +19,7 @@ def find_path(codename: str, file: str = "") -> Path | None:
return g
def list_codenames(vendor=None, archived=True):
def list_codenames(vendor: str | None = None, archived: bool = True) -> list[str]:
"""Get all devices, for which aports are available.
:param vendor: vendor name to choose devices from, or None for all vendors

View file

@ -7,6 +7,7 @@ import os
from pathlib import Path
import shutil
import urllib.request
from typing import Literal, overload
import pmb.helpers.cli
from pmb.core.context import get_context
@ -18,9 +19,36 @@ def cache_file(prefix: str, url: str) -> Path:
return Path(f"{prefix}_{hashlib.sha256(url.encode('utf-8')).hexdigest()}")
@overload
def download(
url, prefix, cache=True, loglevel=logging.INFO, allow_404=False, flush_progress_bar_on_404=False
):
url: str,
prefix: str,
cache: bool = ...,
loglevel: int = ...,
allow_404: Literal[False] = ...,
flush_progress_bar_on_404: bool = ...,
) -> Path: ...
@overload
def download(
url: str,
prefix: str,
cache: bool = ...,
loglevel: int = ...,
allow_404: Literal[True] = ...,
flush_progress_bar_on_404: bool = ...,
) -> Path | None: ...
def download(
url: str,
prefix: str,
cache: bool = True,
loglevel: int = logging.INFO,
allow_404: bool = False,
flush_progress_bar_on_404: bool = False,
) -> Path | None:
"""Download a file to disk.
:param url: the http(s) address of to the file to download
@ -73,7 +101,21 @@ def download(
return path
def retrieve(url, headers=None, allow_404=False):
@overload
def retrieve(
url: str, headers: dict[str, str] | None = ..., allow_404: Literal[False] = ...
) -> str: ...
@overload
def retrieve(
url: str, headers: dict[str, str] | None = ..., allow_404: Literal[True] = ...
) -> str | None: ...
def retrieve(
url: str, headers: dict[str, str] | None = None, allow_404: bool = False
) -> str | None:
"""Fetch the content of a URL and returns it as string.
:param url: the http(s) address of to the resource to fetch

View file

@ -58,7 +58,7 @@ def get_subpartitions_size(chroot: Chroot) -> tuple[int, int]:
return (boot, round(root))
def get_nonfree_packages(device):
def get_nonfree_packages(device: str) -> list[str]:
"""
Get any legacy non-free subpackages in the APKBUILD.
Also see: https://postmarketos.org/edge/2024/02/15/default-nonfree-fw/

View file

@ -8,6 +8,7 @@ import os
from pathlib import Path
import re
from collections import OrderedDict
from typing import Any
import pmb.config
from pmb.meta import Cache
@ -33,7 +34,7 @@ revar5 = re.compile(r"([a-zA-Z_]+[a-zA-Z0-9_]*)=")
def replace_variable(apkbuild: Apkbuild, value: str) -> str:
def log_key_not_found(match):
def log_key_not_found(match: re.Match) -> None:
logging.verbose(
f"{apkbuild['pkgname']}: key '{match.group(1)}' for"
f" replacing '{match.group(0)}' not found, ignoring"
@ -135,7 +136,9 @@ def read_file(path: Path) -> list[str]:
return lines
def parse_next_attribute(lines, i, path):
def parse_next_attribute(
lines: list[str], i: int, path: Path
) -> tuple[str, str, int] | tuple[None, None, int]:
"""
Parse one attribute from the APKBUILD.
@ -196,7 +199,9 @@ def parse_next_attribute(lines, i, path):
)
def _parse_attributes(path, lines, apkbuild_attributes, ret):
def _parse_attributes(
path: Path, lines: list[str], apkbuild_attributes: dict[str, dict[str, bool]], ret: Apkbuild
) -> None:
"""
Parse attributes from a list of lines. Variables are replaced with values
from ret (if found) and split into the format configured in
@ -209,7 +214,7 @@ def _parse_attributes(path, lines, apkbuild_attributes, ret):
# Parse all variables first, and replace variables mentioned earlier
for i in range(len(lines)):
attribute, value, i = parse_next_attribute(lines, i, path)
if not attribute:
if not attribute or not value:
continue
ret[attribute] = replace_variable(ret, value)
@ -237,7 +242,9 @@ def _parse_attributes(path, lines, apkbuild_attributes, ret):
del ret[attribute]
def _parse_subpackage(path, lines, apkbuild, subpackages, subpkg):
def _parse_subpackage(
path: Path, lines: list[str], apkbuild: Apkbuild, subpackages: dict[str, Any], subpkg: str
) -> None:
"""
Attempt to parse attributes from a subpackage function.
This will attempt to locate the subpackage function in the APKBUILD and
@ -405,7 +412,7 @@ def kernels(device: str) -> dict[str, str] | None:
return None
def _parse_comment_tags(lines, tag):
def _parse_comment_tags(lines: list[str], tag: str) -> list[str]:
"""
Parse tags defined as comments in a APKBUILD file. This can be used to
parse e.g. the maintainers of a package (defined using # Maintainer:).
@ -422,7 +429,7 @@ def _parse_comment_tags(lines, tag):
return ret
def maintainers(path):
def maintainers(path: Path) -> list[str] | None:
"""
Parse maintainers of an APKBUILD file. They should be defined using
# Maintainer: (first maintainer) and # Co-Maintainer: (additional
@ -447,7 +454,7 @@ def maintainers(path):
return maintainers
def archived(path):
def archived(path: Path) -> str | None:
"""
Return if (and why) an APKBUILD might be archived. This should be
defined using a # Archived: <reason> tag in the APKBUILD.