From: Daan De Meyer Date: Wed, 2 Aug 2023 08:32:58 +0000 (+0200) Subject: Introduce StrEnum and Use enum.auto() everywhere X-Git-Tag: v15~47^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=317bc367ec3e250c5eb7c0f5c8124edab0c11ad0;p=thirdparty%2Fmkosi.git Introduce StrEnum and Use enum.auto() everywhere --- diff --git a/mkosi/architecture.py b/mkosi/architecture.py index d8edbabf9..1e845d791 100644 --- a/mkosi/architecture.py +++ b/mkosi/architecture.py @@ -4,9 +4,10 @@ import enum import platform from mkosi.log import die +from mkosi.util import StrEnum -class Architecture(enum.Enum): +class Architecture(StrEnum): alpha = enum.auto() arc = enum.auto() arm = enum.auto() @@ -27,9 +28,6 @@ class Architecture(enum.Enum): x86 = enum.auto() x86_64 = enum.auto() - def __str__(self) -> str: - return self.name.replace("_", "-") - @staticmethod def from_uname(s: str) -> "Architecture": a = { diff --git a/mkosi/config.py b/mkosi/config.py index 7f6dfe5cb..3e3ef4a5c 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -30,6 +30,7 @@ from mkosi.pager import page from mkosi.run import run from mkosi.util import ( InvokingUser, + StrEnum, chdir, flatten, qemu_check_kvm_support, @@ -43,22 +44,18 @@ ConfigMatchCallback = Callable[[str, str, argparse.Namespace], bool] ConfigDefaultCallback = Callable[[argparse.Namespace], Any] -class Verb(enum.Enum): - build = "build" - clean = "clean" - summary = "summary" - shell = "shell" - boot = "boot" - qemu = "qemu" - ssh = "ssh" - serve = "serve" - bump = "bump" - help = "help" - genkey = "genkey" - - # Defining __str__ is required to get "print_help()" output to include the human readable (values) of Verb. - def __str__(self) -> str: - return self.value +class Verb(StrEnum): + build = enum.auto() + clean = enum.auto() + summary = enum.auto() + shell = enum.auto() + boot = enum.auto() + qemu = enum.auto() + ssh = enum.auto() + serve = enum.auto() + bump = enum.auto() + help = enum.auto() + genkey = enum.auto() def supports_cmdline(self) -> bool: return self in (Verb.shell, Verb.boot, Verb.qemu, Verb.ssh) @@ -70,51 +67,42 @@ class Verb(enum.Enum): return self in (Verb.shell, Verb.boot) -class ConfigFeature(enum.Enum): - auto = "auto" - enabled = "enabled" - disabled = "disabled" - - def __str__(self) -> str: - return str(self.value).lower() - - -class SecureBootSignTool(enum.Enum): - auto = "auto" - sbsign = "sbsign" - pesign = "pesign" +class ConfigFeature(StrEnum): + auto = enum.auto() + enabled = enum.auto() + disabled = enum.auto() - def __str__(self) -> str: - return str(self.value).lower() +class SecureBootSignTool(StrEnum): + auto = enum.auto() + sbsign = enum.auto() + pesign = enum.auto() -class OutputFormat(str, enum.Enum): - directory = "directory" - tar = "tar" - cpio = "cpio" - disk = "disk" - none = "none" +class OutputFormat(StrEnum): + directory = enum.auto() + tar = enum.auto() + cpio = enum.auto() + disk = enum.auto() + none = enum.auto() -class ManifestFormat(str, enum.Enum): - json = "json" # the standard manifest in json format - changelog = "changelog" # human-readable text file with package changelogs +class ManifestFormat(StrEnum): + json = enum.auto() # the standard manifest in json format + changelog = enum.auto() # human-readable text file with package changelogs -class Compression(enum.Enum): - none = None - zst = "zst" - xz = "xz" - bz2 = "bz2" - gz = "gz" - lz4 = "lz4" - lzma = "lzma" - def __str__(self) -> str: - return str(self.value).lower() +class Compression(StrEnum): + none = enum.auto() + zst = enum.auto() + xz = enum.auto() + bz2 = enum.auto() + gz = enum.auto() + lz4 = enum.auto() + lzma = enum.auto() def __bool__(self) -> bool: - return bool(self.value) + return self != Compression.none def parse_boolean(s: str) -> bool: @@ -223,7 +211,7 @@ def config_match_boolean(dest: str, value: str, namespace: argparse.Namespace) - def parse_feature(value: Optional[str]) -> ConfigFeature: - if not value or value == ConfigFeature.auto.value: + if not value or value == ConfigFeature.auto.name: return ConfigFeature.auto return ConfigFeature.enabled if parse_boolean(value) else ConfigFeature.disabled @@ -319,8 +307,8 @@ def config_default_package_manager_tree(namespace: argparse.Namespace) -> list[t def make_enum_parser(type: Type[enum.Enum]) -> Callable[[str], enum.Enum]: def parse_enum(value: str) -> enum.Enum: try: - return type[value.replace("-", "_")] - except KeyError: + return type(value) + except ValueError: die(f"'{value}' is not a valid {type.__name__}") return parse_enum @@ -809,7 +797,7 @@ class MkosiConfigParser: parse=config_make_enum_parser(Distribution), match=config_make_enum_matcher(Distribution), default=detect_distribution()[0], - choices=Distribution.__members__, + choices=Distribution.values(), help="Distribution to install", ), MkosiConfigSetting( @@ -826,6 +814,7 @@ class MkosiConfigParser: section="Distribution", parse=config_make_enum_parser(Architecture), default=Architecture.native(), + choices=Architecture.values(), help="Override the architecture of installation", ), MkosiConfigSetting( @@ -866,7 +855,7 @@ class MkosiConfigParser: section="Output", parse=config_make_enum_parser(OutputFormat), default=OutputFormat.disk, - choices=OutputFormat.__members__, + choices=OutputFormat.values(), help="Output Format", ), MkosiConfigSetting( @@ -1303,6 +1292,7 @@ class MkosiConfigParser: section="Validation", parse=config_make_enum_parser(SecureBootSignTool), default=SecureBootSignTool.auto, + choices=SecureBootSignTool.values(), help="Tool to use for signing PE binaries for secure boot", ), MkosiConfigSetting( diff --git a/mkosi/distributions/__init__.py b/mkosi/distributions/__init__.py index 44cd19879..932aa8812 100644 --- a/mkosi/distributions/__init__.py +++ b/mkosi/distributions/__init__.py @@ -8,21 +8,18 @@ from typing import TYPE_CHECKING, Optional, Type, cast from mkosi.architecture import Architecture from mkosi.log import die -from mkosi.util import read_os_release +from mkosi.util import StrEnum, read_os_release if TYPE_CHECKING: from mkosi.state import MkosiState -class PackageType(enum.Enum): +class PackageType(StrEnum): rpm = enum.auto() deb = enum.auto() pkg = enum.auto() ebuild = enum.auto() - def __str__(self) -> str: - return self.name - class DistributionInstaller: @classmethod @@ -50,7 +47,7 @@ class DistributionInstaller: raise NotImplementedError() -class Distribution(enum.Enum): +class Distribution(StrEnum): fedora = enum.auto() debian = enum.auto() ubuntu = enum.auto() @@ -63,9 +60,6 @@ class Distribution(enum.Enum): alma = enum.auto() gentoo = enum.auto() - def __str__(self) -> str: - return self.name - def is_centos_variant(self) -> bool: return self in (Distribution.centos, Distribution.alma, Distribution.rocky) diff --git a/mkosi/util.py b/mkosi/util.py index a2490c178..17843b3bb 100644 --- a/mkosi/util.py +++ b/mkosi/util.py @@ -3,6 +3,7 @@ import ast import contextlib import copy +import enum import errno import fcntl import functools @@ -16,7 +17,7 @@ import resource import stat import sys import tempfile -from collections.abc import Iterable, Iterator, Mapping +from collections.abc import Iterable, Iterator, Mapping, Sequence from pathlib import Path from typing import Any, Callable, Optional, TypeVar @@ -197,3 +198,18 @@ def scopedenv(env: Mapping[str, Any]) -> Iterator[None]: finally: os.environ = old tempfile.tempdir = None + + +class StrEnum(enum.Enum): + def __str__(self) -> str: + assert isinstance(self.value, str) + return self.value + + # Used by enum.auto() to get the next value. + @staticmethod + def _generate_next_value_(name: str, start: int, count: int, last_values: Sequence[str]) -> str: + return name.replace("_", "-") + + @classmethod + def values(cls) -> list[str]: + return list(map(str, cls)) diff --git a/tests/test_config.py b/tests/test_config.py index dd1b2f70f..441f052c1 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -8,7 +8,7 @@ from mkosi.config import Compression, GenericVersion def test_compression_enum_creation() -> None: - assert Compression(None) == Compression.none + assert Compression("none") == Compression.none assert Compression("zst") == Compression.zst assert Compression("xz") == Compression.xz assert Compression("bz2") == Compression.bz2