Add typed *_enum accessors alongside every enum-backed field - #134
Merged
Conversation
_enums.py has defined EtherType, IPProtocol, ARPOperation and ARPHardwareType since early on, but no decoded field ever exposed them as a typed value -- only the *_name display strings, with the enums themselves used solely for internal dispatch. mypy could type-check ip.protocol as int and nothing caught a typo like ip.proto, but nobody writing match/case or comparing against IPProtocol.TCP got a real enum back without doing the try/except themselves. Mirrors the src/src_address precedent 1.3.0 established for IP addresses: the raw int field stays canonical (bytes(decode(x)) == x is unaffected either way), and a new *_enum property returns the typed value or None -- never raises -- for a wire value this library does not enumerate. Covers every field with a fixed wire vocabulary, not just the six issue #95 named explicitly: also VLAN.ethertype_enum and GRE.protocol_enum (same EtherType as Ethernet.ethertype), the three IPv6 extension headers that share IPv6.next_header's IPProtocol registry, and DHCP.htype_name/htype_enum (same ARPHardwareType ARP already used) -- all four use the identical enum a named field on this tier already gets, so leaving them out would just move the same documented gap sideways. Closes#95. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CP7X7H4k3pBWoiAkBdxATM
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Sep 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_enums.pydefinesEtherType,IPProtocol,ARPOperationandARPHardwareType, but until now no decoded field exposed them as a typed value — only the*_namedisplay strings, with the enums themselves used only for internal dispatch.reveal_type(Ethernet.decode(b"...").ethertype)wasint.1.3.0 established the right pattern for this with addresses:
IPv4.srcstays astrandIPv4.src_addressreturns anipaddress.IPv4Address. This does the same for the enum registries: the wire field stays a plainint(sobytes(decode(x)) == xholds for values this library does not enumerate), and a new*_enumproperty returns the typed enum member orNone— never raises — for a value it doesn't recognize.What's included
Ethernet.ethertype_enum,VLAN.ethertype_enum,GRE.protocol_enum→EtherType | NoneIPv4.protocol_enum,IPv6.next_header_enum(and the three IPv6 extension headers that share the field:IPv6HopByHopOptions,IPv6DestinationOptions,IPv6Routing,IPv6Fragment) →IPProtocol | NoneARP.oper_enum→ARPOperation | None,ARP.ptype_enum→EtherType | NoneARP.htype_name/ARP.htype_enumandDHCP.htype_name/DHCP.htype_enum→ARPHardwareType | None(new —ARPHardwareTypewas exported but referenced nowhere insrc/before this):param: ... (see :class:...)) added wherever a field gained an enum accessor but didn't already point at its enum classNone-degrades) case of every new accessorCHANGELOG.mdentry under a new## [Unreleased]section (this repo's changelog had none yet since 2.0.0 shipped)Scope note: issue #95's text names six accessors explicitly (
ethertype_enum,protocol_enum,next_header_enum,oper_enum,htype_name/htype_enumonARP). This PR also addsVLAN.ethertype_enum,GRE.protocol_enum, the three extra IPv6 extension-headernext_header_enums,ARP.ptype_enum, andDHCP.htype_name/htype_enum— every other field in the codebase that maps onto the exact same four enum registries the issue targets, for consistency rather than leaving an identical gap one field over.Verification
uv run --frozen ruff check .anduv run --frozen ruff format --check .are cleanuv run --frozen mypyis clean (strict,src/only — 30 source files)uv run --frozen pytestpasses locally (582 tests)uv run --frozen python scripts/benchmark.py --check --threshold 15— 126,825 f/s, +12.9% vs. baseline, within thresholdCHANGELOG.mdhas an entry under## [Unreleased]New protocol or dispatch change — also:
Not applicable — no new protocol, no dispatch change. Deleted this block's checklist since it doesn't apply.
Notes
No breaking change: every new accessor is additive (a new property alongside existing fields), consistent with 2.1.0 being a minor version per the roadmap (#105, part of #107).
Closes#95.
🤖 Generated with Claude Code
https://claude.ai/code/session_01CP7X7H4k3pBWoiAkBdxATM
Generated by Claude Code