]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Update typing to use generics for standard container classes
authorJoerg Behrmann <behrmann@physik.fu-berlin.de>
Fri, 13 Jan 2023 09:20:45 +0000 (10:20 +0100)
committerJoerg Behrmann <behrmann@physik.fu-berlin.de>
Fri, 13 Jan 2023 14:19:03 +0000 (15:19 +0100)
Also use the non-deprecated typing imports

18 files changed:
mkosi/__init__.py
mkosi/__main__.py
mkosi/backend.py
mkosi/distributions/__init__.py
mkosi/distributions/alma.py
mkosi/distributions/arch.py
mkosi/distributions/centos.py
mkosi/distributions/debian.py
mkosi/distributions/fedora.py
mkosi/distributions/gentoo.py
mkosi/distributions/mageia.py
mkosi/distributions/openmandriva.py
mkosi/distributions/opensuse.py
mkosi/distributions/rocky.py
mkosi/distributions/ubuntu.py
mkosi/install.py
mkosi/manifest.py
mkosi/mounts.py

index 512a777aeedcdbd1fe7d7a5eb824fa4c38a4f906..db7b12b6c4583deadeb813e4e48fb4d3aa237602 100644 (file)
@@ -29,6 +29,7 @@ import sys
 import tempfile
 import time
 import uuid
+from collections.abc import Iterable, Iterator, Sequence
 from pathlib import Path
 from textwrap import dedent, wrap
 from typing import (
@@ -36,16 +37,9 @@ from typing import (
     Any,
     BinaryIO,
     Callable,
-    Dict,
-    Iterable,
-    Iterator,
-    List,
     NoReturn,
     Optional,
-    Sequence,
-    Set,
     TextIO,
-    Tuple,
     TypeVar,
     Union,
     cast,
@@ -375,7 +369,7 @@ def prepare_tree(state: MkosiState, cached: bool) -> None:
         state.root.joinpath("etc/kernel/install.conf").write_text("layout=bls\n")
 
 
-def flatten(lists: Iterable[Iterable[T]]) -> List[T]:
+def flatten(lists: Iterable[Iterable[T]]) -> list[T]:
     """Flatten a sequence of sequences into a single list."""
     return list(itertools.chain.from_iterable(lists))
 
@@ -601,7 +595,7 @@ def configure_root_password(state: MkosiState, cached: bool) -> None:
             patch_file(state.root / "etc/shadow", set_root_pw)
 
 
-def pam_add_autologin(root: Path, ttys: List[str]) -> None:
+def pam_add_autologin(root: Path, ttys: list[str]) -> None:
     login = root / "etc/pam.d/login"
     original = login.read_text() if login.exists() else ""
 
@@ -666,7 +660,7 @@ def nspawn_id_map_supported() -> bool:
     return ret.returncode == 0
 
 
-def nspawn_params_for_build_sources(config: MkosiConfig, sft: SourceFileTransfer) -> List[str]:
+def nspawn_params_for_build_sources(config: MkosiConfig, sft: SourceFileTransfer) -> list[str]:
     params = ["--setenv=SRCDIR=/root/src",
               "--chdir=/root/src"]
     if sft == SourceFileTransfer.mount:
@@ -772,7 +766,7 @@ def copy_git_files(src: Path, dest: Path, *, source_file_transfer: SourceFileTra
     uid = int(os.getenv("SUDO_UID", 0))
 
     c = run(["git", "-C", src, "ls-files", "-z", *what_files], stdout=subprocess.PIPE, text=False, user=uid)
-    files: Set[str] = {x.decode("utf-8") for x in c.stdout.rstrip(b"\0").split(b"\0")}
+    files = {x.decode("utf-8") for x in c.stdout.rstrip(b"\0").split(b"\0")}
 
     # Add the .git/ directory in as well.
     if source_file_transfer == SourceFileTransfer.copy_git_more:
@@ -885,7 +879,7 @@ def xz_binary() -> str:
     return "pxz" if shutil.which("pxz") else "xz"
 
 
-def compressor_command(option: Union[str, bool], src: Path) -> List[PathString]:
+def compressor_command(option: Union[str, bool], src: Path) -> list[PathString]:
     """Returns a command suitable for compressing archives."""
 
     if option == "xz":
@@ -915,7 +909,7 @@ def make_tar(state: MkosiState) -> None:
     if state.for_cache:
         return
 
-    cmd: List[PathString] = [tar_binary(), "-C", state.root, "-c", "--xattrs", "--xattrs-include=*"]
+    cmd: list[PathString] = [tar_binary(), "-C", state.root, "-c", "--xattrs", "--xattrs-include=*"]
     if state.config.tar_strip_selinux_context:
         cmd += ["--xattrs-exclude=security.selinux"]
 
@@ -941,7 +935,7 @@ def make_cpio(state: MkosiState) -> None:
 
     with complete_step("Creating archive…"), open(state.staging / state.config.output.name, "wb") as f:
         files = find_files(state.root)
-        cmd: List[PathString] = [
+        cmd: list[PathString] = [
             "cpio", "-o", "--reproducible", "--null", "-H", "newc", "--quiet", "-D", state.root
         ]
 
@@ -963,7 +957,7 @@ def make_directory(state: MkosiState) -> None:
     os.rename(state.root, state.staging / state.config.output.name)
 
 
-def gen_kernel_images(state: MkosiState) -> Iterator[Tuple[str, Path]]:
+def gen_kernel_images(state: MkosiState) -> Iterator[tuple[str, Path]]:
     # Apparently openmandriva hasn't yet completed its usrmerge so we use lib here instead of usr/lib.
     if not state.root.joinpath("lib/modules").exists():
         return
@@ -1051,7 +1045,7 @@ def install_unified_kernel(state: MkosiState, label: Optional[str], root_hash: O
                 option = "mount.usr" if usr_only else "root"
                 boot_options = f"{boot_options} {option}=LABEL={label}"
 
-            cmd: List[PathString] = [
+            cmd: list[PathString] = [
                 "ukify",
                 "--cmdline", boot_options,
                 "--os-release", f"@{state.root / 'usr/lib/os-release'}",
@@ -1184,7 +1178,7 @@ def calculate_signature(state: MkosiState) -> None:
         return None
 
     with complete_step("Signing SHA256SUMS…"):
-        cmdline: List[PathString] = [
+        cmdline: list[PathString] = [
             "gpg",
             "--detach-sign",
             "-o", state.staging / state.config.output_signature.name,
@@ -1205,7 +1199,7 @@ def calculate_bmap(state: MkosiState) -> None:
         return
 
     with complete_step("Creating BMAP file…"):
-        cmdline: List[PathString] = [
+        cmdline: list[PathString] = [
             "bmaptool",
             "create",
             "--output", state.staging / state.config.output_bmap.name,
@@ -1277,7 +1271,7 @@ def setup_package_cache(config: MkosiConfig, workspace: Path) -> Path:
     return cache
 
 
-def remove_duplicates(items: List[T]) -> List[T]:
+def remove_duplicates(items: list[T]) -> list[T]:
     "Return list with any repetitions removed"
     # We use a dictionary to simulate an ordered set
     return list({x: None for x in items})
@@ -1470,7 +1464,7 @@ class CustomHelpFormatter(argparse.HelpFormatter):
         args_string = self._format_args(action, default)
         return ", ".join(action.option_strings) + " " + args_string
 
-    def _split_lines(self, text: str, width: int) -> List[str]:
+    def _split_lines(self, text: str, width: int) -> list[str]:
         """Wraps text to width, each line separately.
         If the first line of text ends in a colon, we assume that
         this is a list of option descriptions, and subindent them.
@@ -1539,7 +1533,7 @@ class ArgumentParserMkosi(argparse.ArgumentParser):
     def _ini_key_to_cli_arg(cls, key: str) -> str:
         return cls.SPECIAL_MKOSI_DEFAULT_PARAMS.get(key) or ("--" + cls._camel_to_arg(key))
 
-    def _read_args_from_files(self, arg_strings: List[str]) -> List[str]:
+    def _read_args_from_files(self, arg_strings: list[str]) -> list[str]:
         """Convert @-prefixed command line arguments with corresponding file content
 
         Regular arguments are just returned. Arguments prefixed with @ are considered
@@ -1622,7 +1616,7 @@ def parse_base_packages(value: str) -> Union[str, bool]:
     return parse_boolean(value)
 
 
-def parse_remove_files(value: str) -> List[str]:
+def parse_remove_files(value: str) -> list[str]:
     """Normalize paths as relative to / to ensure we don't go outside of our root."""
 
     # os.path.normpath() leaves leading '//' untouched, even though it normalizes '///'.
@@ -2353,7 +2347,7 @@ def load_distribution(args: argparse.Namespace) -> argparse.Namespace:
     return args
 
 
-def parse_args(argv: Optional[Sequence[str]] = None) -> Dict[str, argparse.Namespace]:
+def parse_args(argv: Optional[Sequence[str]] = None) -> dict[str, argparse.Namespace]:
     """Load config values from files and parse command line arguments
 
     Do all about config files and command line arguments parsing. If --all argument is passed
@@ -2440,7 +2434,7 @@ def parse_args(argv: Optional[Sequence[str]] = None) -> Dict[str, argparse.Names
     return args_all
 
 
-def parse_args_file(argv: List[str], config_path: Path) -> argparse.Namespace:
+def parse_args_file(argv: list[str], config_path: Path) -> argparse.Namespace:
     """Parse just one mkosi.* file (--all mode)."""
 
     # Parse all parameters handled by mkosi.
@@ -2451,7 +2445,7 @@ def parse_args_file(argv: List[str], config_path: Path) -> argparse.Namespace:
 
 
 def parse_args_file_group(
-    argv: List[str], config_path: Path, distribution: Optional[Distribution] = None
+    argv: list[str], config_path: Path, distribution: Optional[Distribution] = None
 ) -> argparse.Namespace:
     """Parse a set of mkosi config files"""
     # Add the @ prefixed filenames to current argument list in inverse priority order.
@@ -2510,7 +2504,7 @@ def parse_bytes(num_bytes: Optional[str], *, sector_size: int = 512) -> int:
 
 def remove_glob(*patterns: PathString) -> None:
     pathgen = (glob.glob(str(pattern)) for pattern in patterns)
-    paths: Set[str] = set(sum(pathgen, []))  # uniquify
+    paths: set[str] = set(sum(pathgen, []))  # uniquify
     for path in paths:
         unlink_try_hard(Path(path))
 
@@ -3449,11 +3443,11 @@ def invoke_repart(
     state: MkosiState,
     skip: Sequence[str] = [],
     split: bool = False,
-) -> Tuple[Optional[str], Optional[str], bool]:
+) -> tuple[Optional[str], Optional[str], bool]:
     if not state.config.output_format == OutputFormat.disk or state.for_cache or state.do_run_build_script:
         return (None, None, False)
 
-    cmdline: List[PathString] = [
+    cmdline: list[PathString] = [
         "systemd-repart",
         "--empty=allow",
         "--size=auto",
@@ -3885,7 +3879,7 @@ def find_qemu_binary(config: MkosiConfig) -> str:
     die("Couldn't find QEMU/KVM binary")
 
 
-def find_qemu_firmware(config: MkosiConfig) -> Tuple[Path, bool]:
+def find_qemu_firmware(config: MkosiConfig) -> tuple[Path, bool]:
     FIRMWARE_LOCATIONS = {
         "x86_64": ["/usr/share/ovmf/x64/OVMF_CODE.secboot.fd"],
         "i386": [
@@ -4023,7 +4017,7 @@ def run_qemu(config: MkosiConfig) -> None:
     else:
         machine = f"type=q35,accel={accel},smm={smm}"
 
-    cmdline: List[PathString] = [
+    cmdline: list[PathString] = [
         find_qemu_binary(config),
         "-machine",
         machine,
@@ -4126,7 +4120,7 @@ def interface_exists(dev: str) -> bool:
     return rc == 0
 
 
-def find_address(config: MkosiConfig) -> Tuple[str, str]:
+def find_address(config: MkosiConfig) -> tuple[str, str]:
     if not ensure_networkd(config) and config.ssh_port != 22:
         return "", "127.0.0.1"
 
@@ -4250,7 +4244,7 @@ def generate_secure_boot_key(config: MkosiConfig) -> None:
         )
     )
 
-    cmd: List[PathString] = [
+    cmd: list[PathString] = [
         "openssl",
         "req",
         "-new",
@@ -4293,7 +4287,7 @@ def bump_image_version(config: MkosiConfig) -> None:
     Path("mkosi.version").write_text(new_version + "\n")
 
 
-def expand_paths(paths: Sequence[str]) -> List[Path]:
+def expand_paths(paths: Sequence[str]) -> list[Path]:
     if not paths:
         return []
 
index d67f9f67e63348081cfc47ee782ecb78bbe43482..fd5d7482cd19a1416daaf79876b168dcc78f74d3 100644 (file)
@@ -4,8 +4,8 @@
 import contextlib
 import os
 import sys
+from collections.abc import Iterator
 from subprocess import CalledProcessError
-from typing import Iterator
 
 from mkosi import complete_step, parse_args, run_verb
 from mkosi.backend import MkosiException, die
index 3f0847ecbe306c8fb13e5236beb94955695d7a54..53f24e4dfdff6e4919f7e7f337d31fea423b0d00 100644 (file)
@@ -20,6 +20,7 @@ import subprocess
 import sys
 import tarfile
 import uuid
+from collections.abc import Iterable, Iterator, Mapping, Sequence
 from pathlib import Path
 from types import FrameType
 from typing import (
@@ -28,17 +29,8 @@ from typing import (
     Any,
     Callable,
     Deque,
-    Dict,
-    Iterable,
-    Iterator,
-    List,
-    Mapping,
     NoReturn,
     Optional,
-    Sequence,
-    Set,
-    Tuple,
-    Type,
     TypeVar,
     Union,
     cast,
@@ -95,7 +87,7 @@ class MkosiNotSupportedException(MkosiException):
 
 
 # This global should be initialized after parsing arguments
-ARG_DEBUG: Set[str] = set()
+ARG_DEBUG: set[str] = set()
 
 
 class Parseable:
@@ -114,7 +106,7 @@ class Parseable:
             raise argparse.ArgumentTypeError(f"unknown Format: {name!r}")
 
     @classmethod
-    def parse_list(cls: Any, string: str) -> List[Any]:
+    def parse_list(cls: Any, string: str) -> list[Any]:
         return [cls.from_string(p) for p in string.split(",") if p]
 
 
@@ -174,15 +166,15 @@ class Distribution(enum.Enum):
         return self.name
 
 
-def dictify(f: Callable[..., Iterator[Tuple[T, V]]]) -> Callable[..., Dict[T, V]]:
-    def wrapper(*args: Any, **kwargs: Any) -> Dict[T, V]:
+def dictify(f: Callable[..., Iterator[tuple[T, V]]]) -> Callable[..., dict[T, V]]:
+    def wrapper(*args: Any, **kwargs: Any) -> dict[T, V]:
         return dict(f(*args, **kwargs))
 
     return functools.update_wrapper(wrapper, f)
 
 
 @dictify
-def read_os_release() -> Iterator[Tuple[str, str]]:
+def read_os_release() -> Iterator[tuple[str, str]]:
     try:
         filename = "/etc/os-release"
         f = open(filename)
@@ -204,7 +196,7 @@ def read_os_release() -> Iterator[Tuple[str, str]]:
                 print(f"{filename}:{line_number}: bad line {line!r}", file=sys.stderr)
 
 
-def detect_distribution() -> Tuple[Optional[Distribution], Optional[str]]:
+def detect_distribution() -> tuple[Optional[Distribution], Optional[str]]:
     try:
         os_release = read_os_release()
     except FileNotFoundError:
@@ -280,7 +272,7 @@ class SourceFileTransfer(enum.Enum):
         return self.value
 
     @classmethod
-    def doc(cls) -> Dict["SourceFileTransfer", str]:
+    def doc(cls) -> dict["SourceFileTransfer", str]:
         return {
             cls.copy_all: "normal file copy",
             cls.copy_git_cached: "use git ls-files --cached, ignoring any file that git itself ignores",
@@ -333,7 +325,7 @@ class MkosiConfig:
     """
 
     verb: Verb
-    cmdline: List[str]
+    cmdline: list[str]
     force: int
 
     distribution: Distribution
@@ -341,17 +333,17 @@ class MkosiConfig:
     mirror: Optional[str]
     local_mirror: Optional[str]
     repository_key_check: bool
-    repositories: List[str]
+    repositories: list[str]
     use_host_repositories: bool
     repos_dir: Optional[str]
     repart_dir: Optional[str]
     architecture: str
     output_format: OutputFormat
-    manifest_format: List[ManifestFormat]
+    manifest_format: list[ManifestFormat]
     output: Path
     output_dir: Optional[Path]
     bootable: bool
-    kernel_command_line: List[str]
+    kernel_command_line: list[str]
     secure_boot: bool
     secure_boot_key: Path
     secure_boot_certificate: Path
@@ -369,21 +361,21 @@ class MkosiConfig:
     incremental: bool
     cache_initrd: bool
     base_packages: Union[str, bool]
-    packages: List[str]
-    remove_packages: List[str]
+    packages: list[str]
+    remove_packages: list[str]
     with_docs: bool
     with_tests: bool
     cache_path: Path
-    extra_trees: List[Path]
-    skeleton_trees: List[Path]
+    extra_trees: list[Path]
+    skeleton_trees: list[Path]
     clean_package_metadata: Union[bool, str]
-    remove_files: List[Path]
-    environment: Dict[str, str]
+    remove_files: list[Path]
+    environment: dict[str, str]
     build_sources: Path
     build_dir: Optional[Path]
     include_dir: Optional[Path]
     install_dir: Optional[Path]
-    build_packages: List[str]
+    build_packages: list[str]
     skip_final_phase: bool
     build_script: Optional[Path]
     prepare_script: Optional[Path]
@@ -404,7 +396,7 @@ class MkosiConfig:
     password: Optional[str]
     password_is_hashed: bool
     autologin: bool
-    extra_search_paths: List[Path]
+    extra_search_paths: list[Path]
     netdev: bool
     ephemeral: bool
     ssh: bool
@@ -412,12 +404,12 @@ class MkosiConfig:
     ssh_agent: Optional[Path]
     ssh_timeout: int
     ssh_port: int
-    credentials: Dict[str, str]
+    credentials: dict[str, str]
     directory: Optional[Path]
     config_path: Optional[Path]
     all: bool
     all_directory: Optional[Path]
-    debug: List[str]
+    debug: list[str]
     auto_bump: bool
     workspace_dir: Optional[Path]
     machine_id: Optional[str]
@@ -469,7 +461,7 @@ class MkosiConfig:
     def output_changelog(self) -> Path:
         return build_auxiliary_output_path(self, ".changelog")
 
-    def output_paths(self) -> Tuple[Path, ...]:
+    def output_paths(self) -> tuple[Path, ...]:
         return (
             self.output,
             self.output_split_kernel,
@@ -498,7 +490,7 @@ class MkosiState:
     do_run_build_script: bool
     machine_id: str
     for_cache: bool
-    environment: Dict[str, str] = dataclasses.field(init=False)
+    environment: dict[str, str] = dataclasses.field(init=False)
     installer: DistributionInstaller = dataclasses.field(init=False)
 
     def __post_init__(self) -> None:
@@ -584,7 +576,7 @@ def run_workspace_command(
     cmd: Sequence[PathString],
     network: bool = False,
     env: Optional[Mapping[str, str]] = None,
-    nspawn_params: Optional[List[str]] = None,
+    nspawn_params: Optional[list[str]] = None,
     capture_stdout: bool = False,
     check: bool = True,
 ) -> CompletedProcess:
@@ -745,7 +737,7 @@ def path_relative_to_cwd(path: PathString) -> Path:
         return path
 
 
-def die(message: str, exception: Type[MkosiException] = MkosiException) -> NoReturn:
+def die(message: str, exception: type[MkosiException] = MkosiException) -> NoReturn:
     MkosiPrinter.warn(f"Error: {message}")
     raise exception(message)
 
@@ -796,12 +788,12 @@ class MkosiPrinter:
 
     @classmethod
     @contextlib.contextmanager
-    def complete_step(cls, text: str, text2: Optional[str] = None) -> Iterator[List[Any]]:
+    def complete_step(cls, text: str, text2: Optional[str] = None) -> Iterator[list[Any]]:
         cls.print_step(text)
 
         cls.level += 1
         try:
-            args: List[Any] = []
+            args: list[Any] = []
             yield args
         finally:
             cls.level -= 1
@@ -880,7 +872,7 @@ def disable_pam_securetty(root: Path) -> None:
 
 
 def add_packages(
-    config: MkosiConfig, packages: Set[str], *names: str, conditional: Optional[str] = None
+    config: MkosiConfig, packages: set[str], *names: str, conditional: Optional[str] = None
 ) -> None:
 
     """Add packages in @names to @packages, if enabled by --base-packages.
@@ -896,7 +888,7 @@ def add_packages(
             packages.add(f"({name} if {conditional})" if conditional else name)
 
 
-def sort_packages(packages: Iterable[str]) -> List[str]:
+def sort_packages(packages: Iterable[str]) -> list[str]:
     """Sorts packages: normal first, paths second, conditional third"""
 
     m = {"(": 2, "/": 1}
index ea1c6316cbad2200f9201bc3d168c5d3a481e7f6..aa87b7185a90c1b9ae1e3319eb51d5b372752c72 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
 from pathlib import Path
-from typing import TYPE_CHECKING, List
+from typing import TYPE_CHECKING
 
 if TYPE_CHECKING:
     from mkosi.backend import MkosiState
@@ -19,9 +19,9 @@ class DistributionInstaller:
         return Path("lib/modules") / name / "vmlinuz"
 
     @classmethod
-    def cache_path(cls) -> List[str]:
+    def cache_path(cls) -> list[str]:
         raise NotImplementedError
 
     @classmethod
-    def remove_packages(cls, state: "MkosiState", remove: List[str]) -> None:
+    def remove_packages(cls, state: "MkosiState", remove: list[str]) -> None:
         raise NotImplementedError
index 143a5aad9d6c7513e08c0da806132fbd076d85a9..59c39af1d721d6ef73e3d7f61a9a0b04bd45e007 100644 (file)
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
 from pathlib import Path
-from typing import Tuple
 
 from mkosi.backend import MkosiConfig
 from mkosi.distributions.centos import CentosInstaller
@@ -9,7 +8,7 @@ from mkosi.distributions.centos import CentosInstaller
 
 class AlmaInstaller(CentosInstaller):
     @staticmethod
-    def _gpg_locations(epel_release: int) -> Tuple[Path, str]:
+    def _gpg_locations(epel_release: int) -> tuple[Path, str]:
         return (
             Path(f"/etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux-{epel_release}"),
             f"https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux-{epel_release}",
index 881712b7457987498de2eed5ba8765af6c45c98e..fa474204d96869b32667c3a8feaf2498b53a20cb 100644 (file)
@@ -2,7 +2,6 @@
 
 import os
 from textwrap import dedent
-from typing import List, Set
 
 from mkosi.backend import (
     MkosiPrinter,
@@ -19,7 +18,7 @@ from mkosi.mounts import mount_api_vfs
 
 class ArchInstaller(DistributionInstaller):
     @classmethod
-    def cache_path(cls) -> List[str]:
+    def cache_path(cls) -> list[str]:
         return ["var/cache/pacman/pkg"]
 
     @classmethod
@@ -135,7 +134,7 @@ def install_arch(state: MkosiState) -> None:
                     )
                 )
 
-    packages: Set[str] = set()
+    packages: set[str] = set()
     add_packages(state.config, packages, "base")
 
     if not state.do_run_build_script and state.config.bootable:
index d5b59fe984204af2ece53eeb7e5bd21e31010483..7c45a8a4970adaae52ac28dcc97bfea740ee5cee 100644 (file)
@@ -2,7 +2,6 @@
 
 import shutil
 from pathlib import Path
-from typing import List, Tuple
 
 from mkosi.backend import (
     Distribution,
@@ -35,7 +34,7 @@ def move_rpm_db(root: Path) -> None:
 
 class CentosInstaller(DistributionInstaller):
     @classmethod
-    def cache_path(cls) -> List[str]:
+    def cache_path(cls) -> list[str]:
         return ["var/cache/yum", "var/cache/dnf"]
 
     @classmethod
@@ -89,7 +88,7 @@ class CentosInstaller(DistributionInstaller):
             run_workspace_command(state, cmdline)
 
     @classmethod
-    def remove_packages(cls, state: MkosiState, remove: List[str]) -> None:
+    def remove_packages(cls, state: MkosiState, remove: list[str]) -> None:
         invoke_dnf(state, 'remove', remove)
 
     @classmethod
@@ -104,14 +103,14 @@ class CentosInstaller(DistributionInstaller):
         return int(fields[0].removesuffix("-stream"))
 
     @staticmethod
-    def _gpg_locations(epel_release: int) -> Tuple[Path, str]:
+    def _gpg_locations(epel_release: int) -> tuple[Path, str]:
         return (
             Path("/etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial"),
             "https://www.centos.org/keys/RPM-GPG-KEY-CentOS-Official"
         )
 
     @staticmethod
-    def _epel_gpg_locations(epel_release: int) -> Tuple[Path, str]:
+    def _epel_gpg_locations(epel_release: int) -> tuple[Path, str]:
         return (
             Path(f"/etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-{epel_release}"),
             f"https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-{epel_release}",
@@ -126,7 +125,7 @@ class CentosInstaller(DistributionInstaller):
         return f"http://mirrorlist.centos.org/?release={config.release}&arch=$basearch&repo={repo}"
 
     @classmethod
-    def _variant_repos(cls, config: MkosiConfig, epel_release: int) -> List[Repo]:
+    def _variant_repos(cls, config: MkosiConfig, epel_release: int) -> list[Repo]:
         # Repos for CentOS Linux 8, CentOS Stream 8 and CentOS variants
 
         directory = cls._mirror_directory()
@@ -174,7 +173,7 @@ class CentosInstaller(DistributionInstaller):
         return repos
 
     @classmethod
-    def _stream_repos(cls, config: MkosiConfig, epel_release: int) -> List[Repo]:
+    def _stream_repos(cls, config: MkosiConfig, epel_release: int) -> list[Repo]:
         # Repos for CentOS Stream 9 and later
 
         gpgpath, gpgurl = cls._gpg_locations(epel_release)
index 649784ab068f366db0d167f1195375ebf7451191..f813f9326b2f0debdd3922d117c3c764c023aa90 100644 (file)
@@ -3,9 +3,10 @@
 import contextlib
 import os
 import subprocess
+from collections.abc import Iterable, Iterator
 from pathlib import Path
 from textwrap import dedent
-from typing import TYPE_CHECKING, Any, Iterable, Iterator, List, Set
+from typing import TYPE_CHECKING, Any
 
 from mkosi.backend import (
     MkosiState,
@@ -28,17 +29,17 @@ else:
 
 class DebianInstaller(DistributionInstaller):
     needs_skeletons_after_bootstrap = True
-    repositories_for_boot: Set[str] = set()
+    repositories_for_boot: set[str] = set()
 
     @classmethod
-    def _add_default_kernel_package(cls, state: MkosiState, extra_packages: Set[str]) -> None:
+    def _add_default_kernel_package(cls, state: MkosiState, extra_packages: set[str]) -> None:
         # Don't pull in a kernel if users specify one, but otherwise try to pick a default
         # one - try to infer from the architecture.
         if not any(package.startswith("linux-image") for package in extra_packages):
             add_packages(state.config, extra_packages, f"linux-image-{DEBIAN_KERNEL_ARCHITECTURES[state.config.architecture]}")
 
     @classmethod
-    def _fixup_resolved(cls, state: MkosiState, extra_packages: Set[str]) -> None:
+    def _fixup_resolved(cls, state: MkosiState, extra_packages: set[str]) -> None:
         if "systemd" in extra_packages and "systemd-resolved" not in extra_packages:
             # The default resolv.conf points to 127.0.0.1, and resolved is disabled, fix it in
             # the base image.
@@ -47,7 +48,7 @@ class DebianInstaller(DistributionInstaller):
             run(["systemctl", "--root", state.root, "enable", "systemd-resolved"])
 
     @classmethod
-    def cache_path(cls) -> List[str]:
+    def cache_path(cls) -> list[str]:
         return ["var/cache/apt/archives"]
 
     @staticmethod
@@ -69,7 +70,7 @@ class DebianInstaller(DistributionInstaller):
 
         # debootstrap fails if a base image is used with an already populated root, so skip it.
         if state.config.base_image is None:
-            cmdline: List[PathString] = [
+            cmdline: list[PathString] = [
                 "debootstrap",
                 "--variant=minbase",
                 "--include=ca-certificates",
@@ -95,7 +96,7 @@ class DebianInstaller(DistributionInstaller):
         # Install extra packages via the secondary APT run, because it is smarter and can deal better with any
         # conflicts. dbus and libpam-systemd are optional dependencies for systemd in debian so we include them
         # explicitly.
-        extra_packages: Set[str] = set()
+        extra_packages: set[str] = set()
         add_packages(state.config, extra_packages, "systemd", "systemd-sysv", "dbus", "libpam-systemd")
         extra_packages.update(state.config.packages)
 
@@ -190,7 +191,7 @@ class DebianInstaller(DistributionInstaller):
         state.root.joinpath("etc/default/locale").symlink_to("../locale.conf")
 
     @classmethod
-    def _add_apt_auxiliary_repos(cls, state: MkosiState, repos: Set[str]) -> None:
+    def _add_apt_auxiliary_repos(cls, state: MkosiState, repos: set[str]) -> None:
         if state.config.release in ("unstable", "sid"):
             return
 
@@ -206,7 +207,7 @@ class DebianInstaller(DistributionInstaller):
         state.root.joinpath(f"etc/apt/sources.list.d/{state.config.release}-security.list").write_text(f"{security}\n")
 
     @classmethod
-    def remove_packages(cls, state: MkosiState, remove: List[str]) -> None:
+    def remove_packages(cls, state: MkosiState, remove: list[str]) -> None:
         invoke_apt(state, "get", "purge", ["--assume-yes", "--auto-remove", *remove])
 
 
@@ -308,6 +309,6 @@ def invoke_apt(
         return run(cmdline, env=env, text=True, **kwargs)
 
 
-def add_apt_package_if_exists(state: MkosiState, extra_packages: Set[str], package: str) -> None:
+def add_apt_package_if_exists(state: MkosiState, extra_packages: set[str], package: str) -> None:
     if invoke_apt(state, "cache", "search", ["--names-only", f"^{package}$"], stdout=subprocess.PIPE).stdout.strip():
         add_packages(state.config, extra_packages, package)
index db880959b51ed0a0f44016026af88dbe566dfc33..7adc1d9b56697f481e43378e4c2b4a0cc384bb3e 100644 (file)
@@ -3,9 +3,10 @@
 import shutil
 import urllib.parse
 import urllib.request
+from collections.abc import Iterable, Sequence
 from pathlib import Path
 from textwrap import dedent
-from typing import Iterable, List, NamedTuple, Optional, Sequence, Set, Tuple
+from typing import NamedTuple, Optional
 
 from mkosi.backend import (
     Distribution,
@@ -32,7 +33,7 @@ FEDORA_KEYS_MAP = {
 
 class FedoraInstaller(DistributionInstaller):
     @classmethod
-    def cache_path(cls) -> List[str]:
+    def cache_path(cls) -> list[str]:
         return ["var/cache/dnf"]
 
     @classmethod
@@ -40,11 +41,11 @@ class FedoraInstaller(DistributionInstaller):
         return install_fedora(state)
 
     @classmethod
-    def remove_packages(cls, state: MkosiState, remove: List[str]) -> None:
+    def remove_packages(cls, state: MkosiState, remove: list[str]) -> None:
         invoke_dnf(state, 'remove', remove)
 
 
-def parse_fedora_release(release: str) -> Tuple[str, str]:
+def parse_fedora_release(release: str) -> tuple[str, str]:
     if release.startswith("rawhide-"):
         release, releasever = release.split("-")
         MkosiPrinter.info(f"Fedora rawhide — release version: {releasever}")
@@ -120,7 +121,7 @@ def url_exists(url: str) -> bool:
     return False
 
 
-def make_rpm_list(state: MkosiState, packages: Set[str]) -> Set[str]:
+def make_rpm_list(state: MkosiState, packages: set[str]) -> set[str]:
     packages = packages.copy()
 
     if not state.do_run_build_script and state.config.ssh:
@@ -129,7 +130,7 @@ def make_rpm_list(state: MkosiState, packages: Set[str]) -> Set[str]:
     return packages
 
 
-def install_packages_dnf(state: MkosiState, packages: Set[str],) -> None:
+def install_packages_dnf(state: MkosiState, packages: set[str],) -> None:
     packages = make_rpm_list(state, packages)
     invoke_dnf(state, 'install', packages)
 
index 5d6eb874260c391fcea018eafc4084010550b9aa..7ced46edbe1a2966c09772be68b8d865651cce3c 100644 (file)
@@ -7,9 +7,9 @@ import re
 import tarfile
 import urllib.parse
 import urllib.request
+from collections.abc import Generator, Sequence
 from pathlib import Path
 from textwrap import dedent
-from typing import Dict, Generator, List, Sequence
 
 from mkosi.backend import (
     ARG_DEBUG,
@@ -45,14 +45,14 @@ class Gentoo:
     arch_profile: Path
     arch: str
     custom_profile_path: Path
-    DEFAULT_NSPAWN_PARAMS: List[str]
+    DEFAULT_NSPAWN_PARAMS: list[str]
     ebuild_sh_env_dir: Path
-    emerge_default_opts: List[str]
-    emerge_vars: Dict[str, str]
+    emerge_default_opts: list[str]
+    emerge_vars: dict[str, str]
     portage_cfg_dir: Path
     profile_path: Path
     root: Path
-    pkgs: Dict[str, List[str]] = {}
+    pkgs: dict[str, list[str]] = {}
     dracut_atom = "sys-kernel/dracut"
 
     EMERGE_UPDATE_OPTS = [
@@ -90,7 +90,7 @@ class Gentoo:
     ]
 
     @staticmethod
-    def try_import_portage() -> Dict[str, str]:
+    def try_import_portage() -> dict[str, str]:
         NEED_PORTAGE_MSG = "You need portage(5) for Gentoo"
         PORTAGE_INSTALL_INSTRUCTIONS = """\
         # Following is known to work on most systemd-based systems:
@@ -363,7 +363,7 @@ class Gentoo:
         if not inside_stage3:
             from _emerge.main import emerge_main  # type: ignore
 
-            PREFIX_OPTS: List[str] = []
+            PREFIX_OPTS: list[str] = []
             if "--sync" not in actions:
                 PREFIX_OPTS = [
                     f"--config-root={self.root.resolve()}",
@@ -393,7 +393,7 @@ class Gentoo:
 
 class GentooInstaller(DistributionInstaller):
     @classmethod
-    def cache_path(cls) -> List[str]:
+    def cache_path(cls) -> list[str]:
         return ["var/cache/binpkgs", "var/cache/distfiles"]
 
     @staticmethod
index 0e61c242a49b1ee05f5d81633b71dffbd43a90b3..0a3dd383e6855afe90ae21fccc8e26ad67961916 100644 (file)
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
 from pathlib import Path
-from typing import List
 
 from mkosi.backend import MkosiState, add_packages, complete_step, disable_pam_securetty
 from mkosi.distributions import DistributionInstaller
@@ -10,7 +9,7 @@ from mkosi.distributions.fedora import Repo, install_packages_dnf, invoke_dnf, s
 
 class MageiaInstaller(DistributionInstaller):
     @classmethod
-    def cache_path(cls) -> List[str]:
+    def cache_path(cls) -> list[str]:
         return ["var/cache/dnf"]
 
     @classmethod
@@ -18,7 +17,7 @@ class MageiaInstaller(DistributionInstaller):
         return install_mageia(state)
 
     @classmethod
-    def remove_packages(cls, state: MkosiState, remove: List[str]) -> None:
+    def remove_packages(cls, state: MkosiState, remove: list[str]) -> None:
         invoke_dnf(state, 'remove', remove)
 
 
index 74de4eb1528483529dc3060c0025ea488f2e4226..8e0dfe0c49d96f0476250fddba914fe7a265543b 100644 (file)
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
 from pathlib import Path
-from typing import List
 
 from mkosi.backend import MkosiState, add_packages, complete_step
 from mkosi.distributions import DistributionInstaller
@@ -10,7 +9,7 @@ from mkosi.distributions.fedora import Repo, install_packages_dnf, invoke_dnf, s
 
 class OpenmandrivaInstaller(DistributionInstaller):
     @classmethod
-    def cache_path(cls) -> List[str]:
+    def cache_path(cls) -> list[str]:
         return ["var/cache/dnf"]
 
     @classmethod
@@ -18,7 +17,7 @@ class OpenmandrivaInstaller(DistributionInstaller):
         return install_openmandriva(state)
 
     @classmethod
-    def remove_packages(cls, state: MkosiState, remove: List[str]) -> None:
+    def remove_packages(cls, state: MkosiState, remove: list[str]) -> None:
         invoke_dnf(state, 'remove', remove)
 
 
index ab923975783dcbc70e03f2d43c0cc073faf6dc62..3642550a7363578473d9837a8c53f678cff8d920 100644 (file)
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
 import shutil
-from typing import List
 
 from mkosi.backend import (
     MkosiState,
@@ -18,7 +17,7 @@ from mkosi.mounts import mount_api_vfs
 
 class OpensuseInstaller(DistributionInstaller):
     @classmethod
-    def cache_path(cls) -> List[str]:
+    def cache_path(cls) -> list[str]:
         return ["var/cache/zypp/packages"]
 
     @classmethod
@@ -81,7 +80,7 @@ def install_opensuse(state: MkosiState) -> None:
     if not state.do_run_build_script and state.config.ssh:
         add_packages(state.config, packages, "openssh-server")
 
-    cmdline: List[PathString] = ["zypper"]
+    cmdline: list[PathString] = ["zypper"]
     # --reposd-dir needs to be before the verb
     if state.config.local_mirror:
         cmdline += ["--reposd-dir", state.workspace / "zypper-repos.d"]
index 30d3385b877eb2fda1f4fde11d4cb7675f764284..b62b672b25112c5dbca7f0a27dc28539f4b2d772 100644 (file)
@@ -1,7 +1,6 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
 from pathlib import Path
-from typing import Tuple
 
 from mkosi.backend import MkosiConfig
 from mkosi.distributions.centos import CentosInstaller
@@ -9,7 +8,7 @@ from mkosi.distributions.centos import CentosInstaller
 
 class RockyInstaller(CentosInstaller):
     @staticmethod
-    def _gpg_locations(epel_release: int) -> Tuple[Path, str]:
+    def _gpg_locations(epel_release: int) -> tuple[Path, str]:
         keyname = f"Rocky-{epel_release}" if epel_release >= 9 else "rockyofficial"
         return (
              Path(f"/etc/pki/rpm-gpg/RPM-GPG-KEY-{keyname}"),
index 26080d0bcee90a2295a7d1bfcf6d552f0315806c..8bd59c8a338776e6e20d4807080881140b3354fb 100644 (file)
@@ -1,7 +1,5 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
-from typing import Set
-
 from mkosi.backend import MkosiState, add_packages
 from mkosi.distributions.debian import DebianInstaller
 
@@ -10,14 +8,14 @@ class UbuntuInstaller(DebianInstaller):
     repositories_for_boot = {"universe"}
 
     @classmethod
-    def _add_default_kernel_package(cls, state: MkosiState, extra_packages: Set[str]) -> None:
+    def _add_default_kernel_package(cls, state: MkosiState, extra_packages: set[str]) -> None:
         # use the global metapckage linux-generic if the user didn't pick one
         if ("linux-generic" not in extra_packages and
             not any(package.startswith("linux-image") for package in extra_packages)):
             add_packages(state.config, extra_packages, "linux-generic")
 
     @classmethod
-    def _add_apt_auxiliary_repos(cls, state: MkosiState, repos: Set[str]) -> None:
+    def _add_apt_auxiliary_repos(cls, state: MkosiState, repos: set[str]) -> None:
         if state.config.release in ("unstable", "sid"):
             return
 
@@ -30,5 +28,5 @@ class UbuntuInstaller(DebianInstaller):
         state.root.joinpath(f"etc/apt/sources.list.d/{state.config.release}-security.list").write_text(f"{security}\n")
 
     @classmethod
-    def _fixup_resolved(cls, state: MkosiState, extra_packages: Set[str]) -> None:
+    def _fixup_resolved(cls, state: MkosiState, extra_packages: set[str]) -> None:
         pass
index df0597508ef31cc43d6111b1a27bd85a069e665b..6a25f7326da27f0cbc340e0caaec76c0e7ddd205 100644 (file)
@@ -7,9 +7,10 @@ import importlib.resources
 import os
 import shutil
 import stat
+from collections.abc import Iterator
 from pathlib import Path
 from textwrap import dedent
-from typing import Any, BinaryIO, Iterator, Optional, cast
+from typing import Any, BinaryIO, Optional, cast
 
 from mkosi.backend import MkosiState, PathString, complete_step
 
index d12a986905858750b8ccf216b33efd6c5490795d..ff867d3d6da245c8ec7a0b8fe5ee90c8e622fc17 100644 (file)
@@ -6,7 +6,7 @@ from datetime import datetime
 from pathlib import Path
 from subprocess import DEVNULL, PIPE
 from textwrap import dedent
-from typing import IO, Any, Dict, List, Optional, Tuple
+from typing import IO, Any, Optional
 
 from mkosi.backend import Distribution, ManifestFormat, MkosiConfig, PackageType, run
 
@@ -25,7 +25,7 @@ class PackageManifest:
     architecture: str
     size: int
 
-    def as_dict(self) -> Dict[str, str]:
+    def as_dict(self) -> dict[str, str]:
         return {
             "type": self.type,
             "name": self.name,
@@ -38,7 +38,7 @@ class PackageManifest:
 class SourcePackageManifest:
     name: str
     changelog: Optional[str]
-    packages: List[PackageManifest] = dataclasses.field(default_factory=list)
+    packages: list[PackageManifest] = dataclasses.field(default_factory=list)
 
     def add(self, package: PackageManifest) -> None:
         self.packages.append(package)
@@ -58,7 +58,7 @@ class SourcePackageManifest:
         return t
 
 
-def parse_pkg_desc(f: Path) -> Tuple[str, str, str, str]:
+def parse_pkg_desc(f: Path) -> tuple[str, str, str, str]:
     name = version = base = arch = ""
     with f.open() as desc:
         for line in desc:
@@ -78,8 +78,8 @@ def parse_pkg_desc(f: Path) -> Tuple[str, str, str, str]:
 @dataclasses.dataclass
 class Manifest:
     config: MkosiConfig
-    packages: List[PackageManifest] = dataclasses.field(default_factory=list)
-    source_packages: Dict[str, SourcePackageManifest] = dataclasses.field(default_factory=dict)
+    packages: list[PackageManifest] = dataclasses.field(default_factory=list)
+    source_packages: dict[str, SourcePackageManifest] = dataclasses.field(default_factory=dict)
 
     _init_timestamp: datetime = dataclasses.field(init=False, default_factory=datetime.now)
 
@@ -242,7 +242,7 @@ class Manifest:
         # We might add more data in the future
         return len(self.packages) > 0
 
-    def as_dict(self) -> Dict[str, Any]:
+    def as_dict(self) -> dict[str, Any]:
         config = {
             "name": self.config.image_id or "image",
             "distribution": self.config.distribution.name,
index 571c9228c5bff648e899bd2338002bad1591231c..a2d5cc309e8d287153855b5ae33f75c10bad7ba8 100644 (file)
@@ -3,8 +3,9 @@
 import contextlib
 import os
 import stat
+from collections.abc import Iterator, Sequence
 from pathlib import Path
-from typing import ContextManager, Iterator, List, Optional, Sequence, Union, cast
+from typing import ContextManager, Optional, Union, cast
 
 from mkosi.backend import complete_step, run, scandir_recursive
 
@@ -42,7 +43,7 @@ def mount(
     if read_only:
         options = ["ro", *options]
 
-    cmd: List[PathString] = ["mount", "--no-mtab"]
+    cmd: list[PathString] = ["mount", "--no-mtab"]
 
     if operation:
         cmd += [operation]