Skip to content

prefer-str-enum

Prefer StrEnum for application-owned string domains with explicit closed-set evidence.

Why

A named closed domain lets type checking and review catch invalid values and incomplete handling.

Fix

Define a StrEnum, or a named Literal alias when enum runtime behavior is unnecessary.

Examples

Before — flagged Dispatch rejects every unlisted string
app/render.py
def render(kind: str) -> str:
match kind:
case "text":
return "Text"
case "image":
return "Image"
case _:
raise ValueError("unsupported kind")
After — preferred Dispatch forwards unlisted strings
app/render.py
def render(kind: str) -> str:
if kind == "text":
return "Text"
if kind == "image":
return "Image"
return render_plugin(kind)
Before — flagged String field backed by a closed choice collection
app/order.py
class Order:
statuses = ("pending", "shipped")
status: str = "pending"
After — preferred Closed domain represented by a string enum
app/order.py
from enum import StrEnum
class Status(StrEnum):
PENDING = "pending"
SHIPPED = "shipped"
class Order:
status: Status = Status.PENDING