Skip to content

Add us.states.enumeration() returning a dynamic Enum#99

Merged
jcarbaugh merged 1 commit into
mainfrom
APR-32-add-states-enumeration
May 20, 2026
Merged

Add us.states.enumeration() returning a dynamic Enum#99
jcarbaugh merged 1 commit into
mainfrom
APR-32-add-states-enumeration

Conversation

@jcarbaugh
Copy link
Copy Markdown
Member

@jcarbaugh jcarbaugh commented May 20, 2026

Summary

Adds a new us.states.enumeration() helper that dynamically constructs an Enum of states keyed by state abbreviation. It mirrors the call shape of us.states.mapping(): an optional states iterable selects which State objects to include (defaulting to STATES_AND_TERRITORIES), and a value_field argument picks which State attribute supplies each member's value.

The enum member name is always the state's abbrabbr is guaranteed to be a valid Python identifier, so users can't accidentally produce invalid member names by picking a value_field like "name" ("New York") or "fips" ("01").

Closes #28

Example

>>> States = us.states.enumeration()
>>> States.VA
<States.VA: 'Virginia'>

>>> States = us.states.enumeration("fips")
>>> States.CA.value
'06'

>>> States = us.states.enumeration("fips", states=[us.states.DC, us.states.MD])
>>> list(States)
[<States.DC: '11'>, <States.MD: '24'>]

Approach

enumeration() lives next to mapping() in us/states.py and delegates to the stdlib functional API: Enum("States", {s.abbr: getattr(s, value_field) for s in states}). No changes to mapping() or to State.

Test plan

  • uv run pytest us/tests/test_us.py passes
  • Default value_field ("name") returns expected member values
  • Explicit states= iterable produces an enum of exactly that subset
  • Non-name value_field ("fips") values pass through unchanged

Adds a sibling to `mapping()` that builds an `Enum` keyed by `State.abbr`
with member values pulled from a caller-chosen `State` attribute. Default
state list matches `mapping()` (`STATES_AND_TERRITORIES`); `value_field`
defaults to `name`.

Closes APR-32.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jcarbaugh
Copy link
Copy Markdown
Member Author

Review notes:

  • us/states.py:207-210 — new enumeration() function. The key design choice is hard-coding the member name as state.abbr (always a valid Python identifier) and only letting the caller pick the value via value_field. Worth a sanity check that this is the right ergonomic tradeoff vs. exposing a name_field too.
  • Return type is Type[Enum] — the function returns a dynamically constructed Enum subclass, not an instance.
  • Edge case to consider: passing states=us.STATES_AND_TERRITORIES + us.OBSOLETE with value_field="fips" would produce multiple None values, which Enum would alias. Default state set excludes obsolete states so this only bites callers who opt in.
  • No new exports. Same access pattern as mapping() — reached via us.states.enumeration.
  • README has a new "Enumerations" section; CHANGELOG has a single bullet under the unreleased entry.

@jcarbaugh jcarbaugh merged commit 43aed4f into main May 20, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

make it available as an enum?

1 participant