Spaces:
Paused
Paused
| # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license | |
| # Copyright (C) 2003-2017 Nominum, Inc. | |
| # | |
| # Permission to use, copy, modify, and distribute this software and its | |
| # documentation for any purpose with or without fee is hereby granted, | |
| # provided that the above copyright notice and this permission notice | |
| # appear in all copies. | |
| # | |
| # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES | |
| # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
| # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR | |
| # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
| # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
| # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | |
| # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| import enum | |
| from typing import Type, TypeVar, Union | |
| TIntEnum = TypeVar("TIntEnum", bound="IntEnum") | |
| class IntEnum(enum.IntEnum): | |
| def _missing_(cls, value): | |
| cls._check_value(value) | |
| val = int.__new__(cls, value) | |
| val._name_ = cls._extra_to_text(value, None) or f"{cls._prefix()}{value}" | |
| val._value_ = value | |
| return val | |
| def _check_value(cls, value): | |
| max = cls._maximum() | |
| if not isinstance(value, int): | |
| raise TypeError | |
| if value < 0 or value > max: | |
| name = cls._short_name() | |
| raise ValueError(f"{name} must be an int between >= 0 and <= {max}") | |
| def from_text(cls: Type[TIntEnum], text: str) -> TIntEnum: | |
| text = text.upper() | |
| try: | |
| return cls[text] | |
| except KeyError: | |
| pass | |
| value = cls._extra_from_text(text) | |
| if value: | |
| return value | |
| prefix = cls._prefix() | |
| if text.startswith(prefix) and text[len(prefix) :].isdigit(): | |
| value = int(text[len(prefix) :]) | |
| cls._check_value(value) | |
| try: | |
| return cls(value) | |
| except ValueError: | |
| return value | |
| raise cls._unknown_exception_class() | |
| def to_text(cls: Type[TIntEnum], value: int) -> str: | |
| cls._check_value(value) | |
| try: | |
| text = cls(value).name | |
| except ValueError: | |
| text = None | |
| text = cls._extra_to_text(value, text) | |
| if text is None: | |
| text = f"{cls._prefix()}{value}" | |
| return text | |
| def make(cls: Type[TIntEnum], value: Union[int, str]) -> TIntEnum: | |
| """Convert text or a value into an enumerated type, if possible. | |
| *value*, the ``int`` or ``str`` to convert. | |
| Raises a class-specific exception if a ``str`` is provided that | |
| cannot be converted. | |
| Raises ``ValueError`` if the value is out of range. | |
| Returns an enumeration from the calling class corresponding to the | |
| value, if one is defined, or an ``int`` otherwise. | |
| """ | |
| if isinstance(value, str): | |
| return cls.from_text(value) | |
| cls._check_value(value) | |
| return cls(value) | |
| def _maximum(cls): | |
| raise NotImplementedError # pragma: no cover | |
| def _short_name(cls): | |
| return cls.__name__.lower() | |
| def _prefix(cls): | |
| return "" | |
| def _extra_from_text(cls, text): # pylint: disable=W0613 | |
| return None | |
| def _extra_to_text(cls, value, current_text): # pylint: disable=W0613 | |
| return current_text | |
| def _unknown_exception_class(cls): | |
| return ValueError | |