Skip to content

Enhance Enum's default ValueError to list valid member values #150220

@drain99

Description

@drain99

Feature or enhancement

Proposal:

Problem

>>> from enum import Enum
>>> class Currency(Enum):
...     USD = "USD"; EUR = "EUR"; JPY = "JPY"
>>> Currency("USO")
ValueError: 'USO' is not a valid Currency

The user has to inspect cls.__members__ to discover the legal set.
Pydantic and similar validators already include the list ("Input should be 'USD', 'EUR' or 'JPY'"); plain stdlib Enum does not.

Proposal

Append Valid values: ... to the default ValueError:

>>> Currency("USO")
ValueError: 'USO' is not a valid Currency. Valid values: 'USD', 'EUR', 'JPY'

only when _missing_ has not been overridden. This naturally exempts:

  • Flag / IntFlag (override _missing_ for bitwise composition);
  • user subclasses doing case-insensitive matching, aliases, etc., where
    the enumerated values would not describe the actual accepted set.

If a subclass overrides _missing_, it owns its error message.

Truncation

For enums with many members, printing all of them may be counter-productive,
e.g. http.HTTPStatus, signal.Signals in the standard library.

Options for handling this (in order of decreasing preference):

  1. Truncate after N members/N characters (e.g. 5) — Valid values: 100, 101, ..., 511 (62 total). Capped output, still informative.
  2. Skip listing if too long — fall back to bare default beyond a
    threshold.
  3. No truncation — simple; users can override _missing_
    if they specifically dislike the message. Accepts noise on a few
    stdlib classes.

Possibility for opting out

User opt-out without overriding __missing__ may be supported as well.
E.g., class C(Enum, verbose_errors=False)

Backward compatibility

Strictly additive: same ValueError type, same prefix (<value> is not a valid <ClassName>),
only a Valid values: ... suffix added.

CPython's test_enum.py suite passes unchanged with the patch on 3.11/main.
Third-party tests asserting on the exact message will need an update.

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

No response

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement
    No fields configured for issues without a type.

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions