|
1 | | -from enum import IntEnum |
| 1 | +import sys |
| 2 | +from enum import EnumMeta, IntEnum |
2 | 3 |
|
3 | 4 | from typing_extensions import Self |
4 | 5 |
|
5 | 6 |
|
6 | | -class Enum(IntEnum): |
| 7 | +class _EnumMeta(EnumMeta): |
| 8 | + def __new__(metacls, cls, bases, classdict): |
| 9 | + # Find the proto names if defined |
| 10 | + if sys.version_info >= (3, 11): |
| 11 | + proto_names = classdict.pop("betterproto_proto_names", {}) |
| 12 | + classdict._member_names.pop("betterproto_proto_names", None) |
| 13 | + else: |
| 14 | + proto_names = {} |
| 15 | + if "betterproto_proto_names" in classdict: |
| 16 | + proto_names = classdict.pop("betterproto_proto_names") |
| 17 | + classdict._member_names.remove("betterproto_proto_names") |
| 18 | + |
| 19 | + enum_class = super().__new__(metacls, cls, bases, classdict) |
| 20 | + |
| 21 | + # Attach extra info to each enum member |
| 22 | + for member in enum_class: |
| 23 | + value = member.value # type: ignore[reportAttributeAccessIssue] |
| 24 | + extra = proto_names.get(value) |
| 25 | + member._proto_name = extra # type: ignore[reportAttributeAccessIssue] |
| 26 | + |
| 27 | + return enum_class |
| 28 | + |
| 29 | + |
| 30 | +class Enum(IntEnum, metaclass=_EnumMeta): |
| 31 | + @property |
| 32 | + def proto_name(self) -> str | None: |
| 33 | + return self._proto_name # type: ignore[reportAttributeAccessIssue] |
| 34 | + |
7 | 35 | @classmethod |
8 | 36 | def _missing_(cls, value): |
9 | 37 | # If the given value is not an integer, let the standard enum implementation raise an error |
10 | 38 | if not isinstance(value, int): |
11 | | - return None |
| 39 | + return |
12 | 40 |
|
13 | 41 | # Create a new "unknown" instance with the given value. |
14 | 42 | obj = int.__new__(cls, value) |
|
0 commit comments