| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- # enum.py/Open GoPro, Version 2.0 (C) Copyright 2021 GoPro, Inc. (http://gopro.com/OpenGoPro).
- # This copyright was auto-generated on Mon Jul 31 17:04:07 UTC 2023
- """Custom enum definition"""
- from __future__ import annotations
- from enum import Enum, EnumMeta, IntEnum
- from typing import Any, Iterator, Protocol, TypeVar, no_type_check
- T = TypeVar("T")
- class ProtobufDescriptor(Protocol):
- """Protocol definition for Protobuf enum descriptor used to generate GoPro enums from protobufs"""
- @property
- def name(self) -> str:
- """Human readable name of protobuf enum
- Returns:
- str: enum name
- """
- @property
- def values_by_name(self) -> dict:
- """Get the enum values by name
- Returns:
- dict: Dict of enum values mapped by name
- """
- @property
- def values_by_number(self) -> dict:
- """Get the enum values by number
- Returns:
- dict: dict of enum numbers mapped by number
- """
- class GoProEnumMeta(EnumMeta):
- """Modify enum metaclass to build GoPro specific enums"""
- _is_proto = False
- _iter_skip_names = ("NOT_APPLICABLE", "DESCRIPTOR")
- @no_type_check
- def __new__(mcs, name, bases, classdict, **kwargs) -> GoProEnumMeta: # noqa
- is_proto = "__is_proto__" in classdict
- classdict["_ignore_"] = "__is_proto__"
- classdict["__doc__"] = "" # Don't use useless "An enumeration" docstring
- e = super().__new__(mcs, name, bases, classdict, **kwargs)
- setattr(e, "_is_proto", is_proto)
- return e
- @no_type_check
- def __contains__(cls: type[Any], obj: object) -> bool:
- if isinstance(obj, Enum):
- return super().__contains__(obj)
- if isinstance(obj, int):
- return obj in [x.value for x in cls._member_map_.values()]
- if isinstance(obj, str):
- return obj.lower() in [x.name.lower() for x in cls._member_map_.values()]
- raise TypeError(
- f"unsupported operand type(s) for 'in': {type(obj).__qualname__} and {cls.__class__.__qualname__}"
- )
- def __iter__(cls: type[T]) -> Iterator[T]:
- """Do not return enum values whose name is in the _iter_skip_names list
- Returns:
- Iterator[T]: enum iterator
- """
- return iter([x[1] for x in cls._member_map_.items() if x[0] not in GoProEnumMeta._iter_skip_names]) # type: ignore
- class GoProIntEnum(IntEnum, metaclass=GoProEnumMeta):
- """GoPro specific integer enum to be used for all settings, statuses, and parameters
- The names NOT_APPLICABLE and DESCRIPTOR are special as they will not be returned as part of the enum iterator
- """
- def __eq__(self, other: object) -> bool:
- if type(self)._is_proto:
- if isinstance(other, int):
- return self.value == other
- if isinstance(other, str):
- return self.name == other
- if isinstance(other, Enum):
- return self.value == other.value
- raise TypeError(f"Unexpected case: proto enum can only be str or int, not {type(other)}")
- return super(IntEnum, self).__eq__(other)
- def __hash__(self) -> Any:
- return hash(self.name + str(self.value))
- def __str__(self) -> str:
- return super(IntEnum, self).__str__()
- class GoProEnum(Enum, metaclass=GoProEnumMeta):
- """GoPro specific enum to be used for all settings, statuses, and parameters
- The names NOT_APPLICABLE and DESCRIPTOR are special as they will not be returned as part of the enum iterator
- """
- def __eq__(self, other: object) -> bool:
- if type(self)._is_proto:
- if isinstance(other, int):
- return self.value == other
- if isinstance(other, str):
- return self.name == other
- if isinstance(other, Enum):
- return self.value == other.value
- raise TypeError(f"Unexpected case: proto enum can only be str or int, not {type(other)}")
- return super().__eq__(other)
- def __hash__(self) -> Any:
- return hash(self.name + str(self.value))
- def enum_factory(proto_enum: ProtobufDescriptor) -> type[GoProIntEnum]:
- """Dynamically build a GoProEnum from a protobuf enum
- Args:
- proto_enum (ProtobufDescriptor): input protobuf enum descriptor
- Returns:
- type[GoProIntEnum]: generated GoProEnum
- """
- keys = proto_enum.values_by_name.keys()
- values = list(proto_enum.values_by_number.keys())
- # This has somehow changed between protobuf versions
- if isinstance(proto_enum.values_by_number, dict):
- values.reverse()
- return GoProIntEnum( # type: ignore # pylint: disable=too-many-function-args
- proto_enum.name, # type: ignore
- {
- **dict(zip(keys, values)),
- "__is_proto__": True,
- },
- )
|