Last active
May 3, 2023 22:40
-
-
Save malcolmgreaves/a59462e15e6ed9b4270c8ecd69db4125 to your computer and use it in GitHub Desktop.
Function to create a function that can parse `str -> Enum instance` and one from `Enum instance -> str`.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from enum import Enum | |
from typing import Callable, Optional, Type, TypeVar | |
class EnumStr(str, Enum): | |
pass | |
E = TypeVar('E', bound=EnumStr) | |
EnumParser = Callable[[Optional[str]], Optional[E]] | |
EnumWriter = Callable[[Optional[E]], Optional[str]] | |
def create_enum_parser(enum_cls: Type[E]) -> EnumParser[E]: | |
if not issubclass(enum_cls, EnumStr): | |
raise TypeError(f"Expecting {enum_cls} to be an Enum type!") | |
def parse(maybe_value: Optional[str]) -> Optional[E]: | |
if maybe_value is None: | |
return None | |
try: | |
return enum_cls(maybe_value) | |
except ValueError as e: | |
raise ValueError(f"{str(e)}: use one of {list(enum_cls.__members__.values())}") | |
return parse | |
def create_enum_writer(enum_cls: Type[E]) -> EnumWriter[E]: | |
if not issubclass(enum_cls, EnumStr): | |
raise TypeError(f"Expecting {enum_cls} to be an Enum type!") | |
def write(maybe_enum: Optional[E]) -> Optional[str]: | |
if maybe_enum is None: | |
return None | |
return maybe_enum.value | |
return write | |
# | |
# use | |
# | |
class Example(EnumStr): | |
name1 = "value1" | |
name2 = "value2" | |
example_parser: EnumParser[Example] = create_enum_parser(Example) | |
example_writer: EnumWriter[Example] = create_enum_writer(Example) | |
print(f'{example_parser("value1")=}') | |
print(f'{example_writer(Example.name2)=}') | |
# produces: | |
# example_parser("value1")=<Example.name1: 'value1'> | |
# example_writer(Example.name2)='value2' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment