Skip to content

const: bring the 16 bespoke registries onto EnumRegistry, after fixing the base's str-key dispatch #860

Closed

Description

@JarryShaw

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:

  1. Fix the base's str-key dispatch so a StrEnum registry 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/const has no
    StrEnum-valued registry on the base today, so this needs a fixture as well as a fix.
  2. Then convert the 16, or decide per class that its bespoke __new__ earns an exemption. ftp/return_code and
    http/status_code are IntEnum and 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).

Activity

  1. added
    enhancementIssues requesting a new capability (set by the feature request template)
    designA design or decision issue: a pattern being decided rather than a defect or a request
    refactorRestructuring for its own sake — neither a fix nor a new capability (refactor: prefix)
    constRegenerated IANA or vendor constant tables; members keep their numeric values
    on Sep 27, 2026
  2. JarryShaw commented on Sep 27, 2026

    @JarryShaw
    OwnerAuthor

    Checkable blocker. Step 1 of this issue — fixing the base get's str-key dispatch so it falls through to the
    value path — edits pcapkit/corekit/enum.py, which open PR #859 is currently rewriting (NO_DEFAULT → a
    dedicated 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.get plus a StrEnum fixture — tests/const has no StrEnum-valued registry exercising the base
    today, 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.

  3. added
    blockedDeferred pending another issue or decision; see the last comment for what unblocks it
    on Sep 27, 2026
  4. JarryShaw commented on Sep 27, 2026

    @JarryShaw
    OwnerAuthor

    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. That
    undersold it. Verified by AST walk over every _missing_ on main:

    minting extend_enum branches, whole tree : 1007
    of which on these 16 classes             :  781  (78%) across 6 files / 9 classes
      reg/apptype/apptype.py  AppType      766
      http/status_code.py     StatusCode     8
      ftp/return_code.py      ResponseKind / GroupingInformation / ReturnCode   3
      ftp/command.py          FEATCode / Command                                2
      http/method.py          Method         1
      pcapng/option_type.py   OptionType     1
    

    AppType alone 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 inherit EnumRegistry, so they have no _unregistered_member to
    convert to
    . #775's classification confirms almost all 781 are placeholder mints that should convert — AppType's
    766 are 754 unassigned_%d plus 4 reserved_%d plus 8 genuinely-named IANA services — but none of it can be done
    until 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 are StrEnum
    (AppType, FEATCode, Command, Method, OptionType), so they are exactly the population the base get's
    missing value-path fallback would break.

    The blocker above is unchanged — gh pr view 859 --json state must read MERGED, since step 1 edits
    pcapkit/corekit/enum.py which #859 is rewriting.

  5. JarryShaw commented on Sep 27, 2026

    @JarryShaw
    OwnerAuthor

    Unblocked — #859 merged at 21:04:58Z and it was the gate. The condition on the blocker above now reads clear:

    gh pr view 859 --json state -> MERGED
    pcapkit/corekit/enum.py on main: class NoDefaultType at :58, NO_DEFAULT = NoDefaultType() at :219
                                     the str-key branch this issue must change is at :291
    

    So pcapkit/corekit/enum.py is no longer being rewritten by an open PR, and step 1 is a self-contained change to one
    branch of one method.

    A reminder of what step 1 actually is, since it is easy to under-scope. EnumRegistry.get's str path at
    enum.py:291 does cls._member_map_[key] and, on KeyError, either raises or falls back to default — it never
    tries the value path
    . On a StrEnum registry that means a key which is a valid value but not a name raises
    KeyError where the bespoke get resolved it. Four of the sixteen are StrEnum — ftp/command.FEATCode,
    http/method.Method, pcapng/option_type.OptionType, reg/apptype.AppType — so they are exactly the population the
    gap would break.

    tests/const has no StrEnum-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 — AppType alone 766 — so this issue also gates that part of #775. #861 is converting the other 226 now.

    blocked removed, wip applied.

  6. added
    wipWork in flight - a covering PR is open or an agent is actively on it
    and removed
    blockedDeferred pending another issue or decision; see the last comment for what unblocks it
    on Sep 27, 2026
  7. 55 remaining items

  8. added this to the 1.5 milestone on Oct 6, 2026
  9. moved this to Done in PyPCAPKiton Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    constRegenerated IANA or vendor constant tables; members keep their numeric valuesdesignA design or decision issue: a pattern being decided rather than a defect or a requestenhancementIssues requesting a new capability (set by the feature request template)refactorRestructuring for its own sake — neither a fix nor a new capability (refactor: prefix)

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions