Repository navigation
const: bring the 16 bespoke registries onto EnumRegistry, after fixing the base's str-key dispatch #860
Description
Is your feature request related to a problem? Please describe.
Filed per @JarryShaw's ruling on #842: "Take (1) then and file tracking for the remaining work and keep on working."
#842 is closed as done at 111 of 127 const enum classes inheriting EnumRegistry. This tracks the remaining 16.
They divide into two groups, measured on main:
4 StrEnum classes ftp/command.FEATCode, http/method.Method, pcapng/option_type.OptionType,
reg/apptype.AppType
12 others ftp/command.CommandType (IntFlag), ftp/return_code.{ResponseKind,GroupingInformation},
http/status_code.StatusCode (all IntEnum), reg/apptype.TransportProtocol,
and the four transport subclasses dccp.DCCP / sctp.SCTP / tcp.TCP / udp.UDP
Each defines its own __new__ and its own hand-written get, so none shares pcapkit/vendor/default.py's template —
which is why #858 could not sweep them up.
The blocker is real, not merely bookkeeping. The base get dispatches on isinstance(key, str) and its str
branch never falls back to the value path. So on a StrEnum registry a valid value that is not a name would
start raising KeyError where the bespoke get resolved it. That was measured during #858's review on a real
EnumRegistry + StrEnum fixture, not hypothesised.
Describe the solution you'd like
Two steps, in order:
- Fix the base's
str-key dispatch so aStrEnumregistry can resolve a key that is a valid value but not a
name — try the name path, then fall through to the value path rather than raising.tests/consthas no
StrEnum-valued registry on the base today, so this needs a fixture as well as a fix. - Then convert the 16, or decide per class that its bespoke
__new__earns an exemption.ftp/return_codeand
http/status_codeareIntEnumand unaffected by (1), so they could go first.
Describe alternatives you've considered
Converting them without (1), which #858's review showed regresses StrEnum value lookups. Rejected.
Leaving all 16 permanently bespoke. Defensible — they genuinely differ — but it leaves get/get_all/register/
register_alias unavailable on four public StrEnum registries including AppType, which is the one most likely to
be reached for.
Additional context
A second, independent item for the same 16, from #859's review: ftp/return_code.py:284,299 and
http/status_code.py:250,265 still carry their own -1-as-no-default convention (if default == -1: raise). After
#859 the 111 treat -1 as an ordinary value, so the repo will hold two meanings for a literal -1 default (plus
a third, value-to-mint, at pcapng/option_type.py:201 and six sites in protocols/). Harmonising that belongs here
too.
Related: #842 (closed, the 111), #858 (the template move), #859 (the NO_DEFAULT sentinel), #775 (the minting tier).
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsDone
Activity
JarryShaw commentedon Sep 27, 2026
Checkable blocker. Step 1 of this issue — fixing the base
get'sstr-key dispatch so it falls through to thevalue path — edits
pcapkit/corekit/enum.py, which open PR #859 is currently rewriting (NO_DEFAULT→ adedicated sentinel type, per the owner's ruling). Starting here now would collide in that one file.
gh pr view 859 -R JarryShaw/PyPCAPKit --json state -q .state # must be MERGED (or CLOSED)Until then there is nothing to start. Once #859 lands, step 1 is a small, self-contained change to
EnumRegistry.getplus aStrEnumfixture —tests/consthas noStrEnum-valued registry exercising the basetoday, which is why the gap went unnoticed until #858's review probed for it.
Step 2 (converting the 16, or exempting them case by case) depends on step 1 and on nothing else.
JarryShaw commentedon Sep 27, 2026
Scope correction — this issue is larger than filed, and it gates 78% of #775's conversion work.
I filed this as "bring the 16 bespoke registries onto
EnumRegistry", framed as method availability. Thatundersold it. Verified by AST walk over every
_missing_onmain:AppTypealone holds 766 of them.Why that matters here rather than on #775: #775's ruling converts placeholder-minting branches to
_unregistered_member. These 9 classes do not inheritEnumRegistry, so they have no_unregistered_membertoconvert to. #775's classification confirms almost all 781 are placeholder mints that should convert —
AppType's766 are 754
unassigned_%dplus 4reserved_%dplus 8 genuinely-named IANA services — but none of it can be doneuntil these classes have the base.
So this issue is the gate for that work, and the ordering is: #859 → this → #775's remaining 781 branches. The
step-1
str-key dispatch fix matters more than I first wrote, too: four of the nine areStrEnum(
AppType,FEATCode,Command,Method,OptionType), so they are exactly the population the baseget'smissing value-path fallback would break.
The blocker above is unchanged —
gh pr view 859 --json statemust read MERGED, since step 1 editspcapkit/corekit/enum.pywhich #859 is rewriting.JarryShaw commentedon Sep 27, 2026
Unblocked — #859 merged at 21:04:58Z and it was the gate. The condition on the blocker above now reads clear:
So
pcapkit/corekit/enum.pyis no longer being rewritten by an open PR, and step 1 is a self-contained change to onebranch of one method.
A reminder of what step 1 actually is, since it is easy to under-scope.
EnumRegistry.get'sstrpath atenum.py:291doescls._member_map_[key]and, onKeyError, either raises or falls back todefault— it nevertries the value path. On a
StrEnumregistry that means a key which is a valid value but not a name raisesKeyErrorwhere the bespokegetresolved it. Four of the sixteen areStrEnum—ftp/command.FEATCode,http/method.Method,pcapng/option_type.OptionType,reg/apptype.AppType— so they are exactly the population thegap would break.
tests/consthas noStrEnum-valued registry exercising the base today, which is why the gap went unnoticed until#858's review probed for it with a synthetic fixture. So step 1 needs a real fixture as well as the fix.
And the scope correction from earlier still stands: these 16 classes hold 781 of the 1007 minting
_missing_branches —
AppTypealone 766 — so this issue also gates that part of #775. #861 is converting the other 226 now.blockedremoved,wipapplied.refactor(const,vendor): apply the mint/unmint criterion ruling to 82 …
refactor(const,vendor): apply the mint/unmint criterion ruling to 82 …
fix(corekit): fall EnumRegistry.get() back to a str key's value (#860)
fix(corekit): fall EnumRegistry.get() back to a str key's value (#860)
fix(corekit): fall EnumRegistry.get() back to a str key's value (#860)
55 remaining items
docs(tests): re-point six ruling citations at their actual threads, per
docs(tests): paraphrase four fabricated or altered owner quotations (#…
test(corekit,const): narrow the blanket paraphrase, restoring quotati…
test(corekit,const): convert restored quotations to statements with c…
test(corekit,const): state the remaining owner rulings in our own wor…
docs(pcapkit,ci): cite the issue a defect belongs to, not the pull re…
docs(const,vendor): state the generated files' rulings instead of quo…
docs(const,vendor): state the generated files' rulings instead of quo…
docs(corekit,tests): state what the enum tiers actually declare and d…
docs(tests): second pass over tests outside tests/protocols (#1103)
docs(tests): second pass over tests outside tests/protocols (#1103) (#…
docs(corekit): second pass over corekit, const and vendor (#1103) (#1786