File: enum.py

package info (click to toggle)
python-asusrouter 1.21.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,856 kB
  • sloc: python: 20,497; makefile: 3
file content (85 lines) | stat: -rw-r--r-- 2,551 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
"""Enum utilities."""

from __future__ import annotations

from typing import Any, Self, cast

from asusrouter.tools.converters import clean_string, safe_int


class FromIntMixin:
    """Mixin providing a `from_value` classmethod for int-based enums.

    Any enum inheriting from this mixin have to define an `UNKNOWN` member.
    """

    @classmethod
    def from_value(cls, value: Any) -> Self:
        """Resolve an enum member."""

        # If already an enum member, return it
        if isinstance(value, cls):
            return value

        # Try integer conversion first
        vint = safe_int(value)
        if vint is not None:
            try:
                return cls(vint)  # type: ignore[call-arg]
            except ValueError:
                pass

        # Try key names
        vstr = clean_string(value)
        if isinstance(vstr, str):
            member = getattr(cls, vstr.upper(), None)
            if member is not None:
                return cast(Self, member)

        # Fallback to UNKNOWN member if defined on the enum class
        unknown = getattr(cls, "UNKNOWN", None)
        if unknown is not None:
            return cast(Self, unknown)

        raise ValueError(
            f"{cls.__name__}.from_value: cannot resolve {value!r} "
            "and no `UNKNOWN` member is defined"
        )


class FromStrMixin:
    """Mixin providing a `from_value` classmethod for string-based enums.

    Any enum inheriting from this mixin have to define an `UNKNOWN` member.
    """

    @classmethod
    def from_value(cls, value: Any) -> Self:
        """Resolve an enum member from a string value."""

        # If already an enum member, return it
        if isinstance(value, cls):
            return value

        vstr = clean_string(value)
        if isinstance(vstr, str):
            # Check whether this is a value
            value_map = getattr(cls, "_value2member_map_", {})
            member = value_map.get(vstr)
            if member is not None:
                return cast(Self, member)

            # Check if a key exists
            member = getattr(cls, vstr.upper(), None)
            if member is not None:
                return cast(Self, member)

        # Fallback to UNKNOWN member if defined on the enum class
        unknown = getattr(cls, "UNKNOWN", None)
        if unknown is not None:
            return cast(Self, unknown)

        raise ValueError(
            f"{cls.__name__}.from_value: cannot resolve {value!r} "
            "and no `UNKNOWN` member is defined"
        )