Skip to content

Commit 0c8f666

Browse files
committed
Add UnknownEnumMixin for consistent handling of unknown enum values
1 parent b3a8630 commit 0c8f666

3 files changed

Lines changed: 38 additions & 27 deletions

File tree

pyoverkiz/enums/base.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""Shared enum helpers for consistent parsing and logging."""
2+
3+
from __future__ import annotations
4+
5+
import logging
6+
from enum import Enum
7+
from typing import TypeVar, cast
8+
9+
_EnumT = TypeVar("_EnumT", bound=Enum)
10+
11+
12+
class UnknownEnumMixin:
13+
"""Mixin for enums that need an `UNKNOWN` fallback.
14+
15+
Define `UNKNOWN` on the enum and optionally override
16+
`__missing_message__` to customize the log message.
17+
"""
18+
19+
__missing_message__ = "Unsupported value %s has been returned for %s"
20+
21+
@classmethod
22+
def _missing_(cls, value): # type: ignore[override]
23+
"""Return `UNKNOWN` and log unrecognized values."""
24+
message = getattr(cls, "__missing_message__", cls.__missing_message__)
25+
logging.getLogger(cls.__module__).warning(message, value, cls)
26+
return cls.UNKNOWN
27+
28+
@classmethod
29+
def from_value(cls: type[_EnumT], value: object) -> _EnumT:
30+
"""Return enum for `value`, falling back to `UNKNOWN`."""
31+
return cast(_EnumT, cls(value))

pyoverkiz/enums/execution.py

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
"""Execution related enums (types, states and subtypes)."""
22

3-
import logging
43
from enum import StrEnum, unique
54

6-
_LOGGER = logging.getLogger(__name__)
5+
from pyoverkiz.enums.base import UnknownEnumMixin
76

87

98
@unique
10-
class ExecutionType(StrEnum):
9+
class ExecutionType(UnknownEnumMixin, StrEnum):
1110
"""High-level execution categories returned by the API."""
1211

1312
UNKNOWN = "UNKNOWN"
@@ -18,14 +17,9 @@ class ExecutionType(StrEnum):
1817
RAW_TRIGGER_SERVER = "Raw trigger (Server)"
1918
RAW_TRIGGER_GATEWAY = "Raw trigger (Gateway)"
2019

21-
@classmethod
22-
def _missing_(cls, value): # type: ignore
23-
_LOGGER.warning(f"Unsupported value {value} has been returned for {cls}")
24-
return cls.UNKNOWN
25-
2620

2721
@unique
28-
class ExecutionState(StrEnum):
22+
class ExecutionState(UnknownEnumMixin, StrEnum):
2923
"""Execution lifecycle states."""
3024

3125
UNKNOWN = "UNKNOWN"
@@ -38,14 +32,9 @@ class ExecutionState(StrEnum):
3832
QUEUED_GATEWAY_SIDE = "QUEUED_GATEWAY_SIDE"
3933
QUEUED_SERVER_SIDE = "QUEUED_SERVER_SIDE"
4034

41-
@classmethod
42-
def _missing_(cls, value): # type: ignore
43-
_LOGGER.warning(f"Unsupported value {value} has been returned for {cls}")
44-
return cls.UNKNOWN
45-
4635

4736
@unique
48-
class ExecutionSubType(StrEnum):
37+
class ExecutionSubType(UnknownEnumMixin, StrEnum):
4938
"""Subtypes for execution reasons or sources."""
5039

5140
UNKNOWN = "UNKNOWN"
@@ -63,8 +52,3 @@ class ExecutionSubType(StrEnum):
6352
NO_ERROR = "NO_ERROR"
6453
P2P_COMMAND_REGULATION = "P2P_COMMAND_REGULATION"
6554
TIME_TRIGGER = "TIME_TRIGGER"
66-
67-
@classmethod
68-
def _missing_(cls, value): # type: ignore
69-
_LOGGER.warning(f"Unsupported value {value} has been returned for {cls}")
70-
return cls.UNKNOWN

pyoverkiz/enums/protocol.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
"""Protocol enums describe device URL schemes used by Overkiz."""
22

3-
import logging
43
from enum import StrEnum, unique
54

6-
_LOGGER = logging.getLogger(__name__)
5+
from pyoverkiz.enums.base import UnknownEnumMixin
76

87

98
@unique
10-
class Protocol(StrEnum):
9+
class Protocol(UnknownEnumMixin, StrEnum):
1110
"""Protocol used by Overkiz.
1211
1312
Values have been retrieved from /reference/protocolTypes
@@ -46,7 +45,4 @@ class Protocol(StrEnum):
4645
ZIGBEE = "zigbee"
4746
ZWAVE = "zwave"
4847

49-
@classmethod
50-
def _missing_(cls, value): # type: ignore
51-
_LOGGER.warning(f"Unsupported protocol {value} has been returned for {cls}")
52-
return cls.UNKNOWN
48+
__missing_message__ = "Unsupported protocol %s has been returned for %s"

0 commit comments

Comments
 (0)