]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Introduce StrEnum and Use enum.auto() everywhere
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 2 Aug 2023 08:32:58 +0000 (10:32 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 2 Aug 2023 11:04:51 +0000 (13:04 +0200)
mkosi/architecture.py
mkosi/config.py
mkosi/distributions/__init__.py
mkosi/util.py
tests/test_config.py

index d8edbabf99465d83416de17a289418e71d95bde4..1e845d791623df97e7e2b537cd94df04e192e734 100644 (file)
@@ -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 = {
index 7f6dfe5cb4880e0d02fbb03296905937c3f7454f..3e3ef4a5cfc833e292e04ed331f5c9af60829f6f 100644 (file)
@@ -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(
index 44cd198794a9b6375a25ab0d692de7b67d3ce8d2..932aa88122b99497a9a64573b5b8fdfa2909cef5 100644 (file)
@@ -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)
 
index a2490c1787d5312a6cb044c166db88db062a83fd..17843b3bb75de47dfb1e0c34856aa687dbbf6e82 100644 (file)
@@ -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))
index dd1b2f70ffde8587d3c506a3733f42c1715f8b1e..441f052c169aa320463ea83eb37b40c68c2a2b8d 100644 (file)
@@ -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