Batu Lab NotesPractical developer guides

Parse a string into an enum member deliberately

By Batu ยท English technical notes

Also published in our Blogger archive.

An enum offers two different lookup intentions: member names and member values. This example receives configuration text that is explicitly a member name, such as READ_WRITE, so Mode[text] is the deliberate operation. It returns the Mode.READ_WRITE member, whose name and implementation value are then printed as READ_WRITE:rw.

The parser converts the KeyError raised by name lookup into a domain-level ValueError with a useful message. Passing rw fails because it is a value, not a name. That distinction prevents an input format from becoming accidental: if callers are meant to send values, use Mode(text) instead and document that contract. The code intentionally preserves case sensitivity; accepting case-insensitive names would require a stated normalization rule and consideration of ambiguities.

The assertions verify the selected member and the error message for one invalid input. They do not establish that every external configuration source is valid, nor do they validate untrusted input beyond the names present in this enum. Enum aliases can also affect name lookup, so avoid aliases if each accepted name must identify a distinct option. Enum has been part of Python's standard library since Python 3.4.

AI assistance disclosure: this article was drafted with AI assistance and should be reviewed in the context of its target Python version.

Python enum documentation documents lookup by member name with square brackets and lookup by value through enum construction.

from enum import Enum


class Mode(Enum):
    READ_ONLY = "r"
    READ_WRITE = "rw"


def parse_mode(text: str) -> Mode:
    try:
        return Mode[text]
    except KeyError as error:
        raise ValueError(f"unknown mode name: {text}") from error


mode = parse_mode("READ_WRITE")

try:
    parse_mode("rw")
except ValueError as error:
    failure = str(error)

assert mode is Mode.READ_WRITE
assert failure == "unknown mode name: rw"

print(f"{mode.name}:{mode.value}|{failure}")
READ_WRITE:rw|unknown mode name: rw