Use newer StrEnum and IntEnum over Enum (#4521)

* Use newer StrEnum and IntEnum over Enum

* Fix validation issue and remove unnecessary .value calls

---------

Co-authored-by: Pascal Vizeli <pvizeli@syshack.ch>
This commit is contained in:
Mike Degatano 2023-09-06 12:21:04 -04:00 committed by GitHub
parent 38572a5a86
commit 1b649fe5cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 163 additions and 165 deletions

View File

@ -1000,7 +1000,7 @@ class Addon(AddonModel):
_LOGGER.warning(
"Watchdog found addon %s is %s, restarting...",
self.name,
state.value,
state,
)
try:
if state == ContainerState.FAILED:

View File

@ -1,11 +1,11 @@
"""Add-on static data."""
from datetime import timedelta
from enum import Enum
from enum import StrEnum
from ..jobs.const import JobCondition
class AddonBackupMode(str, Enum):
class AddonBackupMode(StrEnum):
"""Backup mode of an Add-on."""
HOT = "hot"

View File

@ -212,9 +212,9 @@ def _migrate_addon_config(protocol=False):
name,
)
if value == "before":
config[ATTR_STARTUP] = AddonStartup.SERVICES.value
config[ATTR_STARTUP] = AddonStartup.SERVICES
elif value == "after":
config[ATTR_STARTUP] = AddonStartup.APPLICATION.value
config[ATTR_STARTUP] = AddonStartup.APPLICATION
# UART 2021-01-20
if "auto_uart" in config:

View File

@ -195,7 +195,7 @@ class SecurityMiddleware(CoreSysAttributes):
CoreState.FREEZE,
):
return api_return_error(
message=f"System is not ready with state: {self.sys_core.state.value}"
message=f"System is not ready with state: {self.sys_core.state}"
)
return await handler(request)

View File

@ -153,7 +153,7 @@ class CoreConfig(FileConfiguration):
def modify_log_level(self) -> None:
"""Change log level."""
lvl = getattr(logging, str(self.logging.value).upper())
lvl = getattr(logging, self.logging.value.upper())
logging.getLogger("supervisor").setLevel(lvl)
@property

View File

@ -1,6 +1,6 @@
"""Constants file for Supervisor."""
from dataclasses import dataclass
from enum import Enum
from enum import StrEnum
from ipaddress import ip_network
from pathlib import Path
from sys import version_info as systemversion
@ -374,14 +374,14 @@ ROLE_ADMIN = "admin"
ROLE_ALL = [ROLE_DEFAULT, ROLE_HOMEASSISTANT, ROLE_BACKUP, ROLE_MANAGER, ROLE_ADMIN]
class AddonBoot(str, Enum):
class AddonBoot(StrEnum):
"""Boot mode for the add-on."""
AUTO = "auto"
MANUAL = "manual"
class AddonStartup(str, Enum):
class AddonStartup(StrEnum):
"""Startup types of Add-on."""
INITIALIZE = "initialize"
@ -391,7 +391,7 @@ class AddonStartup(str, Enum):
ONCE = "once"
class AddonStage(str, Enum):
class AddonStage(StrEnum):
"""Stage types of add-on."""
STABLE = "stable"
@ -399,7 +399,7 @@ class AddonStage(str, Enum):
DEPRECATED = "deprecated"
class AddonState(str, Enum):
class AddonState(StrEnum):
"""State of add-on."""
STARTUP = "startup"
@ -409,7 +409,7 @@ class AddonState(str, Enum):
ERROR = "error"
class UpdateChannel(str, Enum):
class UpdateChannel(StrEnum):
"""Core supported update channels."""
STABLE = "stable"
@ -417,7 +417,7 @@ class UpdateChannel(str, Enum):
DEV = "dev"
class CoreState(str, Enum):
class CoreState(StrEnum):
"""Represent current loading state."""
INITIALIZE = "initialize"
@ -430,7 +430,7 @@ class CoreState(str, Enum):
CLOSE = "close"
class LogLevel(str, Enum):
class LogLevel(StrEnum):
"""Logging level of system."""
DEBUG = "debug"
@ -440,7 +440,7 @@ class LogLevel(str, Enum):
CRITICAL = "critical"
class HostFeature(str, Enum):
class HostFeature(StrEnum):
"""Host feature."""
HASSOS = "hassos"
@ -452,7 +452,7 @@ class HostFeature(str, Enum):
TIMEDATE = "timedate"
class BusEvent(str, Enum):
class BusEvent(StrEnum):
"""Bus event type."""
HARDWARE_NEW_DEVICE = "hardware_new_device"
@ -461,7 +461,7 @@ class BusEvent(str, Enum):
SUPERVISOR_STATE_CHANGE = "supervisor_state_change"
class CpuArch(str, Enum):
class CpuArch(StrEnum):
"""Supported CPU architectures."""
ARMV7 = "armv7"

View File

@ -63,7 +63,7 @@ class Core(CoreSysAttributes):
if self._state == new_state:
return
try:
RUN_SUPERVISOR_STATE.write_text(new_state.value, encoding="utf-8")
RUN_SUPERVISOR_STATE.write_text(new_state, encoding="utf-8")
except OSError as err:
_LOGGER.warning(
"Can't update the Supervisor state to %s: %s", new_state, err

View File

@ -1,5 +1,5 @@
"""Constants for DBUS."""
from enum import Enum, IntEnum
from enum import IntEnum, StrEnum
from socket import AF_INET, AF_INET6
DBUS_NAME_HAOS = "io.hass.os"
@ -181,7 +181,7 @@ DBUS_ATTR_WWN = "WWN"
DBUS_ERR_SYSTEMD_NO_SUCH_UNIT = "org.freedesktop.systemd1.NoSuchUnit"
class RaucState(str, Enum):
class RaucState(StrEnum):
"""Rauc slot states."""
GOOD = "good"
@ -189,7 +189,7 @@ class RaucState(str, Enum):
ACTIVE = "active"
class InterfaceMethod(str, Enum):
class InterfaceMethod(StrEnum):
"""Interface method simple."""
AUTO = "auto"
@ -198,14 +198,14 @@ class InterfaceMethod(str, Enum):
LINK_LOCAL = "link-local"
class ConnectionType(str, Enum):
class ConnectionType(StrEnum):
"""Connection type."""
ETHERNET = "802-3-ethernet"
WIRELESS = "802-11-wireless"
class ConnectionStateType(int, Enum):
class ConnectionStateType(IntEnum):
"""Connection states.
https://developer.gnome.org/NetworkManager/stable/nm-dbus-types.html#NMActiveConnectionState
@ -218,7 +218,7 @@ class ConnectionStateType(int, Enum):
DEACTIVATED = 4
class ConnectionStateFlags(int, Enum):
class ConnectionStateFlags(IntEnum):
"""Connection state flags.
https://developer-old.gnome.org/NetworkManager/stable/nm-dbus-types.html#NMActivationStateFlags
@ -235,7 +235,7 @@ class ConnectionStateFlags(int, Enum):
EXTERNAL = 0x80
class ConnectivityState(int, Enum):
class ConnectivityState(IntEnum):
"""Network connectvity.
https://developer.gnome.org/NetworkManager/unstable/nm-dbus-types.html#NMConnectivityState
@ -248,7 +248,7 @@ class ConnectivityState(int, Enum):
CONNECTIVITY_FULL = 4
class DeviceType(int, Enum):
class DeviceType(IntEnum):
"""Device types.
https://developer.gnome.org/NetworkManager/stable/nm-dbus-types.html#NMDeviceType
@ -263,7 +263,7 @@ class DeviceType(int, Enum):
VETH = 20
class WirelessMethodType(int, Enum):
class WirelessMethodType(IntEnum):
"""Device Type."""
UNKNOWN = 0
@ -280,7 +280,7 @@ class DNSAddressFamily(IntEnum):
INET6 = AF_INET6
class MulticastProtocolEnabled(str, Enum):
class MulticastProtocolEnabled(StrEnum):
"""Multicast protocol enabled or resolve."""
YES = "yes"
@ -288,7 +288,7 @@ class MulticastProtocolEnabled(str, Enum):
RESOLVE = "resolve"
class DNSOverTLSEnabled(str, Enum):
class DNSOverTLSEnabled(StrEnum):
"""DNS over TLS enabled."""
YES = "yes"
@ -296,7 +296,7 @@ class DNSOverTLSEnabled(str, Enum):
OPPORTUNISTIC = "opportunistic"
class DNSSECValidation(str, Enum):
class DNSSECValidation(StrEnum):
"""DNSSEC validation enforced."""
YES = "yes"
@ -304,7 +304,7 @@ class DNSSECValidation(str, Enum):
ALLOW_DOWNGRADE = "allow-downgrade"
class DNSStubListenerEnabled(str, Enum):
class DNSStubListenerEnabled(StrEnum):
"""DNS stub listener enabled."""
YES = "yes"
@ -313,7 +313,7 @@ class DNSStubListenerEnabled(str, Enum):
UDP_ONLY = "udp"
class ResolvConfMode(str, Enum):
class ResolvConfMode(StrEnum):
"""Resolv.conf management mode."""
FOREIGN = "foreign"
@ -323,7 +323,7 @@ class ResolvConfMode(str, Enum):
UPLINK = "uplink"
class StopUnitMode(str, Enum):
class StopUnitMode(StrEnum):
"""Mode for stopping the unit."""
REPLACE = "replace"
@ -332,7 +332,7 @@ class StopUnitMode(str, Enum):
IGNORE_REQUIREMENTS = "ignore-requirements"
class StartUnitMode(str, Enum):
class StartUnitMode(StrEnum):
"""Mode for starting the unit."""
REPLACE = "replace"
@ -342,7 +342,7 @@ class StartUnitMode(str, Enum):
ISOLATE = "isolate"
class UnitActiveState(str, Enum):
class UnitActiveState(StrEnum):
"""Active state of a systemd unit."""
ACTIVE = "active"

View File

@ -121,7 +121,7 @@ class NetworkConnection(DBusInterfaceProxy):
self._state_flags = {
flag
for flag in ConnectionStateFlags
if flag.value & self.properties[DBUS_ATTR_STATE_FLAGS]
if flag & self.properties[DBUS_ATTR_STATE_FLAGS]
} or {ConnectionStateFlags.NONE}
# IPv4

View File

@ -41,7 +41,7 @@ def get_connection_from_interface(
elif interface.type == InterfaceType.WIRELESS:
iftype = "802-11-wireless"
else:
iftype = interface.type.value
iftype = interface.type
# Generate UUID
if not uuid:

View File

@ -95,7 +95,7 @@ class Rauc(DBusInterfaceProxy):
@dbus_connected
async def mark(self, state: RaucState, slot_identifier: str) -> tuple[str, str]:
"""Get slot status."""
return await self.dbus.Installer.call_mark(state.value, slot_identifier)
return await self.dbus.Installer.call_mark(state, slot_identifier)
@dbus_connected
async def update(self, changed: dict[str, Any] | None = None) -> None:

View File

@ -122,25 +122,25 @@ class Systemd(DBusInterfaceProxy):
@systemd_errors
async def start_unit(self, unit: str, mode: StartUnitMode) -> str:
"""Start a systemd service unit. Returns object path of job."""
return await self.dbus.Manager.call_start_unit(unit, mode.value)
return await self.dbus.Manager.call_start_unit(unit, mode)
@dbus_connected
@systemd_errors
async def stop_unit(self, unit: str, mode: StopUnitMode) -> str:
"""Stop a systemd service unit. Returns object path of job."""
return await self.dbus.Manager.call_stop_unit(unit, mode.value)
return await self.dbus.Manager.call_stop_unit(unit, mode)
@dbus_connected
@systemd_errors
async def reload_unit(self, unit: str, mode: StartUnitMode) -> str:
"""Reload a systemd service unit. Returns object path of job."""
return await self.dbus.Manager.call_reload_or_restart_unit(unit, mode.value)
return await self.dbus.Manager.call_reload_or_restart_unit(unit, mode)
@dbus_connected
@systemd_errors
async def restart_unit(self, unit: str, mode: StartUnitMode) -> str:
"""Restart a systemd service unit. Returns object path of job."""
return await self.dbus.Manager.call_restart_unit(unit, mode.value)
return await self.dbus.Manager.call_restart_unit(unit, mode)
@dbus_connected
async def list_units(
@ -155,7 +155,7 @@ class Systemd(DBusInterfaceProxy):
) -> str:
"""Start a transient unit which is released when stopped or on reboot. Returns object path of job."""
return await self.dbus.Manager.call_start_transient_unit(
unit, mode.value, properties, []
unit, mode, properties, []
)
@dbus_connected

View File

@ -263,6 +263,4 @@ class UDisks2Block(DBusInterfaceProxy):
) -> None:
"""Format block device."""
options = options.to_dict() if options else {}
await self.dbus.Block.call_format(
type_.value, options | UDISKS2_DEFAULT_OPTIONS
)
await self.dbus.Block.call_format(type_, options | UDISKS2_DEFAULT_OPTIONS)

View File

@ -1,20 +1,20 @@
"""Constants for UDisks2."""
from enum import Enum
from enum import StrEnum
from dbus_fast import Variant
UDISKS2_DEFAULT_OPTIONS = {"auth.no_user_interaction": Variant("b", True)}
class EncryptType(str, Enum):
class EncryptType(StrEnum):
"""Encryption type."""
LUKS1 = "luks1"
LUKS2 = "luks2"
class EraseMode(str, Enum):
class EraseMode(StrEnum):
"""Erase mode."""
ZERO = "zero"
@ -22,7 +22,7 @@ class EraseMode(str, Enum):
ATA_SECURE_ERASE_ENHANCED = "ata-secure-erase-enhanced"
class FormatType(str, Enum):
class FormatType(StrEnum):
"""Format type."""
EMPTY = "empty"
@ -31,7 +31,7 @@ class FormatType(str, Enum):
GPT = "gpt"
class PartitionTableType(str, Enum):
class PartitionTableType(StrEnum):
"""Partition Table type."""
DOS = "dos"

View File

@ -167,10 +167,10 @@ class FormatOptions(UDisks2StandardOptions):
)
if self.encrypt_passpharase
else None,
"encrypt.type": Variant("s", self.encrypt_type.value)
"encrypt.type": Variant("s", self.encrypt_type)
if self.encrypt_type
else None,
"erase": Variant("s", self.erase.value) if self.erase else None,
"erase": Variant("s", self.erase) if self.erase else None,
"update-partition-type": _optional_variant("b", self.update_partition_type),
"no-block": _optional_variant("b", self.no_block),
"dry-run-first": _optional_variant("b", self.dry_run_first),

View File

@ -278,7 +278,7 @@ class DockerAddon(DockerInterface):
return None
@property
def capabilities(self) -> list[str] | None:
def capabilities(self) -> list[Capabilities] | None:
"""Generate needed capabilities."""
capabilities: set[Capabilities] = set(self.addon.privileged)
@ -292,7 +292,7 @@ class DockerAddon(DockerInterface):
# Return None if no capabilities is present
if capabilities:
return [cap.value for cap in capabilities]
return list(capabilities)
return None
@property
@ -332,7 +332,7 @@ class DockerAddon(DockerInterface):
mounts = [
MOUNT_DEV,
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.addon.path_extern_data.as_posix(),
target="/data",
read_only=False,
@ -343,7 +343,7 @@ class DockerAddon(DockerInterface):
if MAP_CONFIG in addon_mapping:
mounts.append(
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_homeassistant.as_posix(),
target="/config",
read_only=addon_mapping[MAP_CONFIG],
@ -353,7 +353,7 @@ class DockerAddon(DockerInterface):
if MAP_SSL in addon_mapping:
mounts.append(
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_ssl.as_posix(),
target="/ssl",
read_only=addon_mapping[MAP_SSL],
@ -363,7 +363,7 @@ class DockerAddon(DockerInterface):
if MAP_ADDONS in addon_mapping:
mounts.append(
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_addons_local.as_posix(),
target="/addons",
read_only=addon_mapping[MAP_ADDONS],
@ -373,7 +373,7 @@ class DockerAddon(DockerInterface):
if MAP_BACKUP in addon_mapping:
mounts.append(
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_backup.as_posix(),
target="/backup",
read_only=addon_mapping[MAP_BACKUP],
@ -383,22 +383,22 @@ class DockerAddon(DockerInterface):
if MAP_SHARE in addon_mapping:
mounts.append(
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_share.as_posix(),
target="/share",
read_only=addon_mapping[MAP_SHARE],
propagation=PropagationMode.RSLAVE.value,
propagation=PropagationMode.RSLAVE,
)
)
if MAP_MEDIA in addon_mapping:
mounts.append(
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_media.as_posix(),
target="/media",
read_only=addon_mapping[MAP_MEDIA],
propagation=PropagationMode.RSLAVE.value,
propagation=PropagationMode.RSLAVE,
)
)
@ -411,7 +411,7 @@ class DockerAddon(DockerInterface):
continue
mounts.append(
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=gpio_path,
target=gpio_path,
read_only=False,
@ -422,7 +422,7 @@ class DockerAddon(DockerInterface):
if self.addon.with_devicetree:
mounts.append(
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source="/sys/firmware/devicetree/base",
target="/device-tree",
read_only=True,
@ -437,7 +437,7 @@ class DockerAddon(DockerInterface):
if self.addon.with_kernel_modules:
mounts.append(
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source="/lib/modules",
target="/lib/modules",
read_only=True,
@ -456,19 +456,19 @@ class DockerAddon(DockerInterface):
if self.addon.with_audio:
mounts += [
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.addon.path_extern_pulse.as_posix(),
target="/etc/pulse/client.conf",
read_only=True,
),
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_plugins.audio.path_extern_pulse.as_posix(),
target="/run/audio",
read_only=True,
),
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_plugins.audio.path_extern_asound.as_posix(),
target="/etc/asound.conf",
read_only=True,
@ -479,13 +479,13 @@ class DockerAddon(DockerInterface):
if self.addon.with_journald:
mounts += [
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=SYSTEMD_JOURNAL_PERSISTENT.as_posix(),
target=SYSTEMD_JOURNAL_PERSISTENT.as_posix(),
read_only=True,
),
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=SYSTEMD_JOURNAL_VOLATILE.as_posix(),
target=SYSTEMD_JOURNAL_VOLATILE.as_posix(),
read_only=True,

View File

@ -45,7 +45,7 @@ class DockerAudio(DockerInterface, CoreSysAttributes):
mounts = [
MOUNT_DEV,
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_audio.as_posix(),
target="/data",
read_only=False,
@ -68,9 +68,9 @@ class DockerAudio(DockerInterface, CoreSysAttributes):
) + self.sys_hardware.policy.get_cgroups_rules(PolicyGroup.BLUETOOTH)
@property
def capabilities(self) -> list[str]:
def capabilities(self) -> list[Capabilities]:
"""Generate needed capabilities."""
return [cap.value for cap in (Capabilities.SYS_NICE, Capabilities.SYS_RESOURCE)]
return [Capabilities.SYS_NICE, Capabilities.SYS_RESOURCE]
@property
def ulimits(self) -> list[docker.types.Ulimit]:

View File

@ -1,12 +1,12 @@
"""Docker constants."""
from enum import Enum
from enum import StrEnum
from docker.types import Mount
from ..const import MACHINE_ID
class Capabilities(str, Enum):
class Capabilities(StrEnum):
"""Linux Capabilities."""
BPF = "BPF"
@ -24,7 +24,7 @@ class Capabilities(str, Enum):
SYS_TIME = "SYS_TIME"
class ContainerState(str, Enum):
class ContainerState(StrEnum):
"""State of supervisor managed docker container."""
FAILED = "failed"
@ -35,7 +35,7 @@ class ContainerState(str, Enum):
UNKNOWN = "unknown"
class RestartPolicy(str, Enum):
class RestartPolicy(StrEnum):
"""Restart policy of container."""
NO = "no"
@ -44,7 +44,7 @@ class RestartPolicy(str, Enum):
ALWAYS = "always"
class MountType(str, Enum):
class MountType(StrEnum):
"""Mount type."""
BIND = "bind"
@ -53,7 +53,7 @@ class MountType(str, Enum):
NPIPE = "npipe"
class PropagationMode(str, Enum):
class PropagationMode(StrEnum):
"""Propagataion mode, only for bind type mounts."""
PRIVATE = "private"
@ -71,23 +71,21 @@ ENV_TOKEN_OLD = "HASSIO_TOKEN"
LABEL_MANAGED = "supervisor_managed"
MOUNT_DBUS = Mount(
type=MountType.BIND.value, source="/run/dbus", target="/run/dbus", read_only=True
)
MOUNT_DEV = Mount(
type=MountType.BIND.value, source="/dev", target="/dev", read_only=True
type=MountType.BIND, source="/run/dbus", target="/run/dbus", read_only=True
)
MOUNT_DEV = Mount(type=MountType.BIND, source="/dev", target="/dev", read_only=True)
MOUNT_DOCKER = Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source="/run/docker.sock",
target="/run/docker.sock",
read_only=True,
)
MOUNT_MACHINE_ID = Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=MACHINE_ID.as_posix(),
target=MACHINE_ID.as_posix(),
read_only=True,
)
MOUNT_UDEV = Mount(
type=MountType.BIND.value, source="/run/udev", target="/run/udev", read_only=True
type=MountType.BIND, source="/run/udev", target="/run/udev", read_only=True
)

View File

@ -56,7 +56,7 @@ class DockerDNS(DockerInterface, CoreSysAttributes):
environment={ENV_TIME: self.sys_timezone},
mounts=[
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_dns.as_posix(),
target="/config",
read_only=False,

View File

@ -85,7 +85,7 @@ class DockerHomeAssistant(DockerInterface):
MOUNT_UDEV,
# HA config folder
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_homeassistant.as_posix(),
target="/config",
read_only=False,
@ -98,20 +98,20 @@ class DockerHomeAssistant(DockerInterface):
[
# All other folders
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_ssl.as_posix(),
target="/ssl",
read_only=True,
),
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_share.as_posix(),
target="/share",
read_only=False,
propagation=PropagationMode.RSLAVE.value,
),
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_media.as_posix(),
target="/media",
read_only=False,
@ -119,19 +119,19 @@ class DockerHomeAssistant(DockerInterface):
),
# Configuration audio
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_homeassistant.path_extern_pulse.as_posix(),
target="/etc/pulse/client.conf",
read_only=True,
),
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_plugins.audio.path_extern_pulse.as_posix(),
target="/run/audio",
read_only=True,
),
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_plugins.audio.path_extern_asound.as_posix(),
target="/etc/asound.conf",
read_only=True,
@ -212,19 +212,19 @@ class DockerHomeAssistant(DockerInterface):
stderr=True,
mounts=[
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_homeassistant.as_posix(),
target="/config",
read_only=False,
),
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_ssl.as_posix(),
target="/ssl",
read_only=True,
),
Mount(
type=MountType.BIND.value,
type=MountType.BIND,
source=self.sys_config.path_extern_share.as_posix(),
target="/share",
read_only=False,

View File

@ -27,9 +27,9 @@ class DockerMulticast(DockerInterface, CoreSysAttributes):
return MULTICAST_DOCKER_NAME
@property
def capabilities(self) -> list[str]:
def capabilities(self) -> list[Capabilities]:
"""Generate needed capabilities."""
return [Capabilities.NET_ADMIN.value]
return [Capabilities.NET_ADMIN]
@Job(
name="docker_multicast_run",

View File

@ -52,7 +52,7 @@ class DockerObserver(DockerInterface, CoreSysAttributes):
hostname=self.name.replace("_", "-"),
detach=True,
security_opt=self.security_opt,
restart_policy={"Name": RestartPolicy.ALWAYS.value},
restart_policy={"Name": RestartPolicy.ALWAYS},
extra_hosts={"supervisor": self.sys_docker.network.supervisor},
environment={
ENV_TIME: self.sys_timezone,

View File

@ -39,7 +39,7 @@ class DockerSupervisor(DockerInterface):
def host_mounts_available(self) -> bool:
"""Return True if container can see mounts on host within its data directory."""
return self._meta and any(
mount.get("Propagation") == PropagationMode.SLAVE.value
mount.get("Propagation") == PropagationMode.SLAVE
for mount in self.meta_mounts
if mount.get("Destination") == "/data"
)

View File

@ -1,8 +1,8 @@
"""Constants for hardware."""
from enum import Enum
from enum import StrEnum
class UdevSubsystem(str, Enum):
class UdevSubsystem(StrEnum):
"""Udev subsystem class."""
SERIAL = "tty"
@ -24,7 +24,7 @@ class UdevSubsystem(str, Enum):
RPI_H264MEM = "rpivid-h264mem"
class PolicyGroup(str, Enum):
class PolicyGroup(StrEnum):
"""Policy groups backend."""
UART = "uart"
@ -35,14 +35,14 @@ class PolicyGroup(str, Enum):
BLUETOOTH = "bluetooth"
class HardwareAction(str, Enum):
class HardwareAction(StrEnum):
"""Hardware device action."""
ADD = "add"
REMOVE = "remove"
class UdevKernelAction(str, Enum):
class UdevKernelAction(StrEnum):
"""Udev kernel device action."""
ADD = "add"

View File

@ -94,7 +94,7 @@ class HardwareManager(CoreSysAttributes):
udev_device: pyudev.Device = pyudev.Devices.from_sys_path(
self._udev, str(device.sysfs)
)
return udev_device.find_parent(subsystem.value) is not None
return udev_device.find_parent(subsystem) is not None
def _import_devices(self) -> None:
"""Import fresh from udev database."""

View File

@ -1,6 +1,6 @@
"""Constants for homeassistant."""
from datetime import timedelta
from enum import Enum
from enum import StrEnum
from awesomeversion import AwesomeVersion
@ -19,7 +19,7 @@ CLOSING_STATES = [
]
class WSType(str, Enum):
class WSType(StrEnum):
"""Websocket types."""
AUTH = "auth"
@ -28,7 +28,7 @@ class WSType(str, Enum):
BACKUP_END = "backup/end"
class WSEvent(str, Enum):
class WSEvent(StrEnum):
"""Websocket events."""
ADDON = "addon"

View File

@ -492,7 +492,7 @@ class HomeAssistantCore(JobGroup):
# Don't interrupt a task in progress or if rollback is handling it
if not (self.in_progress or self.error_state):
_LOGGER.warning(
"Watchdog found Home Assistant %s, restarting...", state.value
"Watchdog found Home Assistant %s, restarting...", state
)
if state == ContainerState.FAILED and attempts == 0:
try:

View File

@ -1,12 +1,12 @@
"""Const for host."""
from enum import Enum
from enum import StrEnum
PARAM_BOOT_ID = "_BOOT_ID"
PARAM_FOLLOW = "follow"
PARAM_SYSLOG_IDENTIFIER = "SYSLOG_IDENTIFIER"
class InterfaceMethod(str, Enum):
class InterfaceMethod(StrEnum):
"""Configuration of an interface."""
DISABLED = "disabled"
@ -14,7 +14,7 @@ class InterfaceMethod(str, Enum):
AUTO = "auto"
class InterfaceType(str, Enum):
class InterfaceType(StrEnum):
"""Configuration of an interface."""
ETHERNET = "ethernet"
@ -22,7 +22,7 @@ class InterfaceType(str, Enum):
VLAN = "vlan"
class AuthMethod(str, Enum):
class AuthMethod(StrEnum):
"""Authentication method."""
OPEN = "open"
@ -30,7 +30,7 @@ class AuthMethod(str, Enum):
WPA_PSK = "wpa-psk"
class WifiMode(str, Enum):
class WifiMode(StrEnum):
"""Wifi mode."""
INFRASTRUCTURE = "infrastructure"
@ -39,7 +39,7 @@ class WifiMode(str, Enum):
AP = "ap"
class HostFeature(str, Enum):
class HostFeature(StrEnum):
"""Host feature."""
DISK = "disk"
@ -56,7 +56,7 @@ class HostFeature(str, Enum):
TIMEDATE = "timedate"
class LogFormat(str, Enum):
class LogFormat(StrEnum):
"""Log format."""
JOURNAL = "application/vnd.fdo.journal"

View File

@ -142,7 +142,7 @@ class LogsControl(CoreSysAttributes):
async with ClientSession(
connector=UnixConnector(path="/run/systemd-journal-gatewayd.sock")
) as session:
headers = {ACCEPT: accept.value}
headers = {ACCEPT: accept}
if range_header:
headers[RANGE] = range_header
async with session.get(

View File

@ -1,5 +1,5 @@
"""Jobs constants."""
from enum import Enum
from enum import StrEnum
from pathlib import Path
from ..const import SUPERVISOR_DATA
@ -13,7 +13,7 @@ JOB_GROUP_DOCKER_INTERFACE = "container_{name}"
JOB_GROUP_HOME_ASSISTANT_CORE = "home_assistant_core"
class JobCondition(str, Enum):
class JobCondition(StrEnum):
"""Job condition enum."""
AUTO_UPDATE = "auto_update"
@ -30,7 +30,7 @@ class JobCondition(str, Enum):
SUPERVISOR_UPDATED = "supervisor_updated"
class JobExecutionLimit(str, Enum):
class JobExecutionLimit(StrEnum):
"""Job Execution limits."""
ONCE = "once"

View File

@ -72,7 +72,7 @@ class Job(CoreSysAttributes):
and self._throttle_period is None
):
raise RuntimeError(
f"Job {name} is using execution limit {limit.value} without a throttle period!"
f"Job {name} is using execution limit {limit} without a throttle period!"
)
if self.limit in (
@ -81,7 +81,7 @@ class Job(CoreSysAttributes):
):
if self.throttle_max_calls is None:
raise RuntimeError(
f"Job {name} is using execution limit {limit.value} without throttle max calls!"
f"Job {name} is using execution limit {limit} without throttle max calls!"
)
self._rate_limited_calls = {}

View File

@ -1,6 +1,6 @@
"""Constants for mount manager."""
from enum import Enum
from enum import StrEnum
from pathlib import PurePath
FILE_CONFIG_MOUNTS = PurePath("mounts.json")
@ -13,7 +13,7 @@ ATTR_SHARE = "share"
ATTR_USAGE = "usage"
class MountType(str, Enum):
class MountType(StrEnum):
"""Mount type."""
BIND = "bind"
@ -21,7 +21,7 @@ class MountType(str, Enum):
NFS = "nfs"
class MountUsage(str, Enum):
class MountUsage(StrEnum):
"""Mount usage."""
BACKUP = "backup"
@ -29,7 +29,7 @@ class MountUsage(str, Enum):
SHARE = "share"
class MountCifsVersion(str, Enum):
class MountCifsVersion(StrEnum):
"""Mount CIFS version."""
LEGACY_1_0 = "1.0"

View File

@ -81,7 +81,7 @@ class Mount(CoreSysAttributes, ABC):
def to_dict(self, *, skip_secrets: bool = True) -> MountData:
"""Return dictionary representation."""
return MountData(name=self.name, type=self.type.value, usage=self.usage.value)
return MountData(name=self.name, type=self.type, usage=self.usage)
@property
def name(self) -> str:
@ -120,7 +120,7 @@ class Mount(CoreSysAttributes, ABC):
@property
def description(self) -> str:
"""Description of mount."""
return f"Supervisor {self.type.value} mount: {self.name}"
return f"Supervisor {self.type} mount: {self.name}"
@property
def unit_name(self) -> str:
@ -240,7 +240,7 @@ class Mount(CoreSysAttributes, ABC):
else []
)
if self.type != MountType.BIND:
options += [(DBUS_ATTR_TYPE, Variant("s", self.type.value))]
options += [(DBUS_ATTR_TYPE, Variant("s", self.type))]
await self.sys_dbus.systemd.start_transient_unit(
self.unit_name,
@ -467,9 +467,9 @@ class BindMount(Mount):
coresys,
MountData(
name=name,
type=MountType.BIND.value,
type=MountType.BIND,
path=path.as_posix(),
usage=usage and usage.value,
usage=usage and usage,
),
where=where,
)

View File

@ -38,8 +38,10 @@ VALIDATE_SHARE = vol.Match(RE_PATH_PART)
_SCHEMA_BASE_MOUNT_CONFIG = vol.Schema(
{
vol.Required(ATTR_NAME): VALIDATE_NAME,
vol.Required(ATTR_TYPE): vol.In([MountType.CIFS.value, MountType.NFS.value]),
vol.Required(ATTR_USAGE): vol.In([u.value for u in MountUsage]),
vol.Required(ATTR_TYPE): vol.All(
vol.In([MountType.CIFS.value, MountType.NFS.value]), vol.Coerce(MountType)
),
vol.Required(ATTR_USAGE): vol.Coerce(MountUsage),
},
extra=vol.REMOVE_EXTRA,
)
@ -53,7 +55,7 @@ _SCHEMA_MOUNT_NETWORK = _SCHEMA_BASE_MOUNT_CONFIG.extend(
SCHEMA_MOUNT_CIFS = _SCHEMA_MOUNT_NETWORK.extend(
{
vol.Required(ATTR_TYPE): MountType.CIFS.value,
vol.Required(ATTR_TYPE): vol.All(MountType.CIFS.value, vol.Coerce(MountType)),
vol.Required(ATTR_SHARE): VALIDATE_SHARE,
vol.Inclusive(ATTR_USERNAME, "basic_auth"): str,
vol.Inclusive(ATTR_PASSWORD, "basic_auth"): str,
@ -65,7 +67,7 @@ SCHEMA_MOUNT_CIFS = _SCHEMA_MOUNT_NETWORK.extend(
SCHEMA_MOUNT_NFS = _SCHEMA_MOUNT_NETWORK.extend(
{
vol.Required(ATTR_TYPE): MountType.NFS.value,
vol.Required(ATTR_TYPE): vol.All(MountType.NFS.value, vol.Coerce(MountType)),
vol.Required(ATTR_PATH): str,
}
)

View File

@ -120,7 +120,7 @@ class PluginBase(ABC, FileConfiguration, CoreSysAttributes):
_LOGGER.warning(
"Watchdog found %s plugin %s, restarting...",
self.slug,
state.value,
state,
)
try:
if state == ContainerState.STOPPED and attempts == 0:

View File

@ -1,5 +1,5 @@
"""Helpers to check core security."""
from enum import Enum
from enum import StrEnum
from pathlib import Path
from awesomeversion import AwesomeVersion, AwesomeVersionException
@ -15,7 +15,7 @@ def setup(coresys: CoreSys) -> CheckBase:
return CheckCoreSecurity(coresys)
class SecurityReference(str, Enum):
class SecurityReference(StrEnum):
"""Version references."""
CUSTOM_COMPONENTS_BELOW_2021_1_5 = "custom_components_below_2021_1_5"

View File

@ -12,7 +12,7 @@ from .base import CheckBase
def _check_container(container: DockerInterface) -> bool:
"""Return true if container has a config issue."""
return any(
mount.get("Propagation") != PropagationMode.RSLAVE.value
mount.get("Propagation") != PropagationMode.RSLAVE
for mount in container.meta_mounts
if mount.get("Destination") in ["/media", "/share"]
)

View File

@ -1,5 +1,5 @@
"""Constants for the resoulution manager."""
from enum import Enum
from enum import StrEnum
from pathlib import Path
from ..const import SUPERVISOR_DATA
@ -15,7 +15,7 @@ DNS_CHECK_HOST = "_checkdns.home-assistant.io"
DNS_ERROR_NO_DATA = 1
class ContextType(str, Enum):
class ContextType(StrEnum):
"""Place where somethings was happening."""
ADDON = "addon"
@ -29,7 +29,7 @@ class ContextType(str, Enum):
SYSTEM = "system"
class UnsupportedReason(str, Enum):
class UnsupportedReason(StrEnum):
"""Reasons for unsupported status."""
APPARMOR = "apparmor"
@ -55,7 +55,7 @@ class UnsupportedReason(str, Enum):
SYSTEMD_RESOLVED = "systemd_resolved"
class UnhealthyReason(str, Enum):
class UnhealthyReason(StrEnum):
"""Reasons for unsupported status."""
DOCKER = "docker"
@ -65,7 +65,7 @@ class UnhealthyReason(str, Enum):
UNTRUSTED = "untrusted"
class IssueType(str, Enum):
class IssueType(StrEnum):
"""Issue type."""
CORRUPT_DOCKER = "corrupt_docker"
@ -91,7 +91,7 @@ class IssueType(str, Enum):
UPDATE_ROLLBACK = "update_rollback"
class SuggestionType(str, Enum):
class SuggestionType(StrEnum):
"""Sugestion type."""
CLEAR_FULL_BACKUP = "clear_full_backup"

View File

@ -26,7 +26,7 @@ class EvaluateBase(ABC, CoreSysAttributes):
_LOGGER.warning(
"%s (more-info: https://www.home-assistant.io/more-info/unsupported/%s)",
self.on_failure,
self.reason.value,
self.reason,
)
else:
if self.reason in self.sys_resolution.unsupported:

View File

@ -1,10 +1,10 @@
"""Security constants."""
from enum import Enum
from enum import StrEnum
import attr
class ContentTrustResult(str, Enum):
class ContentTrustResult(StrEnum):
"""Content trust result enum."""
PASS = "pass"

View File

@ -1,5 +1,5 @@
"""Constants for the add-on store."""
from enum import Enum
from enum import StrEnum
from pathlib import Path
from ..const import SUPERVISOR_DATA
@ -7,7 +7,7 @@ from ..const import SUPERVISOR_DATA
FILE_HASSIO_STORE = Path(SUPERVISOR_DATA, "store.json")
class StoreType(str, Enum):
class StoreType(StrEnum):
"""Store Types."""
CORE = "core"

View File

@ -9,8 +9,8 @@ from .const import StoreType
URL_COMMUNITY_ADDONS = "https://github.com/hassio-addons/repository"
URL_ESPHOME = "https://github.com/esphome/home-assistant-addon"
BUILTIN_REPOSITORIES = {
StoreType.CORE.value,
StoreType.LOCAL.value,
StoreType.CORE,
StoreType.LOCAL,
URL_COMMUNITY_ADDONS,
URL_ESPHOME,
}
@ -28,7 +28,7 @@ SCHEMA_REPOSITORY_CONFIG = vol.Schema(
def validate_repository(repository: str) -> str:
"""Validate a valid repository."""
if repository in [StoreType.CORE.value, StoreType.LOCAL.value]:
if repository in [StoreType.CORE, StoreType.LOCAL]:
return repository
data = RE_REPOSITORY.match(repository)

View File

@ -115,7 +115,7 @@ class Supervisor(CoreSysAttributes):
async def update_apparmor(self) -> None:
"""Fetch last version and update profile."""
url = URL_HASSIO_APPARMOR.format(channel=self.sys_updater.channel.value)
url = URL_HASSIO_APPARMOR.format(channel=self.sys_updater.channel)
# Fetch
try:

View File

@ -192,7 +192,7 @@ class Updater(FileConfiguration, CoreSysAttributes):
Is a coroutine.
"""
url = URL_HASSIO_VERSION.format(channel=self.channel.value)
url = URL_HASSIO_VERSION.format(channel=self.channel)
machine = self.sys_machine or "default"
# Get data

View File

@ -41,13 +41,13 @@ def test_migration_startup():
valid_config = vd.SCHEMA_ADDON_CONFIG(config)
assert valid_config["startup"].value == "services"
assert valid_config["startup"] == "services"
config["startup"] = "after"
valid_config = vd.SCHEMA_ADDON_CONFIG(config)
assert valid_config["startup"].value == "application"
assert valid_config["startup"] == "application"
def test_migration_auto_uart():

View File

@ -9,8 +9,8 @@ def test_write_state(run_dir, coresys: CoreSys):
coresys.core.state = CoreState.RUNNING
assert run_dir.read_text() == CoreState.RUNNING.value
assert run_dir.read_text() == CoreState.RUNNING
coresys.core.state = CoreState.SHUTDOWN
assert run_dir.read_text() == CoreState.SHUTDOWN.value
assert run_dir.read_text() == CoreState.SHUTDOWN

View File

@ -104,7 +104,7 @@ async def test_update_apparmor(
await coresys.supervisor.update_apparmor()
get.assert_called_once_with(
f"https://version.home-assistant.io/apparmor_{channel.value}.txt",
f"https://version.home-assistant.io/apparmor_{channel}.txt",
timeout=ClientTimeout(total=10),
)
load_profile.assert_called_once()