Found during the post-wave-1 consistency sweep (docs/source/pep.rst). Three lookup defects in pcapkit/const/**, all reproduced by me on 5959a437c. They share a subsystem and a one-PR fix, so they are filed together, but their severities are genuinely different and are labelled honestly below rather than levelled up.
The sweep behind them: I instantiated every IntEnum under pcapkit.const with value 0 — 111 classes — and separately checked every _missing_ for the @classmethod decorator.
1. HIGH — RouterAlert(0) rejects RFC 2113's only defined value
pcapkit/const/ipv4/router_alert.py. RFC 2113 §2.1 defines the Router Alert value field as:
Value: A two octet code with the following values:
0 - Router shall examine packet
1-65535 - Reserved
Value 0 is the only thing RFC 2113 defines, and it is what IGMP, RSVP and MLD put on the wire. The enum does not have it. Members start at Aggregated_Reservation_Nesting_Level_0 = 1 (the RFC 3175 registry, correctly), and _missing_ at :236-251 covers only 66..65502 and 65503..65534. So 0 falls through to super()._missing_ and raises:
RouterAlert(0) -> ValueError: 0 is not a valid RouterAlert
RouterAlert(1) -> <RouterAlert.Aggregated_Reservation_Nesting_Level_0: 1>
RouterAlert(32) -> <RouterAlert.Aggregated_Reservation_Nesting_Level_31: 32>
RouterAlert(65535) -> <RouterAlert.Reserved_65535: 65535>
A standards-compliant packet therefore fails to parse. Built one — IPv4 carrying a Router Alert option (type 148, length 4, value 0) ahead of an IGMP payload:
wire: 4600001c00000000000200007f000001000000009404000011000000
parse -> ValueError: 0 is not a valid RouterAlert
Note the exception class: ValueError from aenum, not a pcapkit.utilities.exceptions error, so it escapes the library's own exception hierarchy.
The gap is in the vendor registry generation: IANA's IPv4 Router Alert Option Values registry lists 0 (RFC 2113) alongside 1-31 (RFC 3175), and only the latter came through.
2. MEDIUM — Socket(0) rejects a real wire value, and it is IPX's own default
pcapkit/const/ipx/socket.py. Every unregistered-value bucket in Socket._missing_ (:79-103) starts at 0x0001 or higher — 0x0001-0x0BB8, 0x0020-0x003F, 0x0BB9-0xFFFF, 0x4000-0x4FFF, 0x8000-0xFFFF — so 0x0000, an ordinary "unspecified socket", reaches aenum's default _missing_ and raises.
Socket(0x0000) -> ValueError: 0 is not a valid Socket
Socket(0x0001) -> <Socket.Routing_Information_Packet: 1>
Socket(0x0451) -> <Socket.NetWare_Core_Protocol: 1105>
0x0000 is also IPX's own class default for dst/src, so the class cannot construct itself with its own documented defaults:
bytes(IPX(payload=b'\xde\xad\xbe\xef'))
ValueError: 0 is not a valid Socket
at pcapkit/const/ipx/socket.py:74 in get
Rated MEDIUM rather than HIGH for one measured reason: through the full pipeline the beholder wrapper catches it and degrades the layer to Raw, so a capture containing such a frame comes back as Ethernet:Novell_Inc_0x8137 with 'error': '0 is not a valid Socket' instead of crashing. It silently loses the IPX parse rather than failing loudly. With a registered socket (0x0451) the identical packet parses fine, which isolates the cause to the missing bucket.
3. LOW, and latent rather than live — two _missing_ methods lack @classmethod
pcapkit/const/ftp/return_code.py:44 (ResponseKind) and :66 (GroupingInformation). aenum invokes cls._missing_(value); without the decorator the lone argument binds to the cls parameter and value goes unfilled:
ResponseKind(0) -> TypeError: ResponseKind._missing_() missing 1 required positional argument: 'value'
ResponseKind(7) -> TypeError: ... (same)
ResponseKind(99) -> TypeError: ... (same)
So every unknown value fails, not merely 0, and with a TypeError that the _missing_ body was written to avoid. The sweep makes the intent unambiguous:
_missing_ WITH @classmethod : 107
_missing_ WITHOUT @classmethod : 2 <- both in ftp/return_code.py
Why LOW, stated plainly: these two const classes are imported by no runtime code. grep across pcapkit/, tests/ and examples/ finds references only in pcapkit/const/ftp/return_code.py itself and in the separate codegen copy pcapkit/vendor/ftp/return_code.py, which carries the identical missing decorator at :73/:95 and does call them at :124-125:
obj.kind = ResponseKind(int(code[0]))
obj.group = GroupingInformation(int(code[1]))
That path is reachable only during vendor regeneration, and only for a reply code whose digits fall outside the defined members. Since codegen currently succeeds, no code in today's IANA registry triggers it. It is a one-line fix in two (really four) places and worth doing, but I am not claiming it breaks anything today.
The other six, checked and cleared
Six further enums also reject 0, and for all six that is correct — 0 is not a valid protocol value, so no change is wanted:
ftp.return_code.ReturnCode and http.status_code.StatusCode (both are 3-digit codes, 100-599), ftp.command.ConformanceRequirement, sctp.cause_code.CauseCode and sctp.parameter.Parameter (registries that begin at 1, with 0 reserved), and mh.mn_id_subtype.MNIDSubtype (subtypes begin at 1 with NAI — the enum behind #469/#481).
So of 111 enums swept: 102 accept 0, 6 rightly reject it, 2 are defects (1 and 2 above), and 1 is the broken-signature case.
Suggested shape
For 1 and 2 the fix is a registry-accuracy one — add the missing 0 member (RouterAlert gets RFC 2113's "Router shall examine packet"; Socket gets an unspecified-socket entry or a _missing_ bucket reaching down to 0x0000) in both pcapkit/const/ and the matching pcapkit/vendor/ generator, or the next regeneration reverts it. For 3, add @classmethod in both files.
A test sweeping every pcapkit.const IntEnum for "does Enum(0) behave as the registry says it should" would pin all of this permanently; the probe above is ~20 lines and already does the enumeration.
Found during the post-wave-1 consistency sweep (
docs/source/pep.rst). Three lookup defects inpcapkit/const/**, all reproduced by me on5959a437c. They share a subsystem and a one-PR fix, so they are filed together, but their severities are genuinely different and are labelled honestly below rather than levelled up.The sweep behind them: I instantiated every
IntEnumunderpcapkit.constwith value0— 111 classes — and separately checked every_missing_for the@classmethoddecorator.1. HIGH —
RouterAlert(0)rejects RFC 2113's only defined valuepcapkit/const/ipv4/router_alert.py. RFC 2113 §2.1 defines the Router Alert value field as:Value 0 is the only thing RFC 2113 defines, and it is what IGMP, RSVP and MLD put on the wire. The enum does not have it. Members start at
Aggregated_Reservation_Nesting_Level_0 = 1(the RFC 3175 registry, correctly), and_missing_at:236-251covers only66..65502and65503..65534. So 0 falls through tosuper()._missing_and raises:A standards-compliant packet therefore fails to parse. Built one — IPv4 carrying a Router Alert option (type 148, length 4, value 0) ahead of an IGMP payload:
Note the exception class:
ValueErrorfromaenum, not apcapkit.utilities.exceptionserror, so it escapes the library's own exception hierarchy.The gap is in the vendor registry generation: IANA's IPv4 Router Alert Option Values registry lists
0(RFC 2113) alongside1-31(RFC 3175), and only the latter came through.2. MEDIUM —
Socket(0)rejects a real wire value, and it is IPX's own defaultpcapkit/const/ipx/socket.py. Every unregistered-value bucket inSocket._missing_(:79-103) starts at0x0001or higher —0x0001-0x0BB8,0x0020-0x003F,0x0BB9-0xFFFF,0x4000-0x4FFF,0x8000-0xFFFF— so0x0000, an ordinary "unspecified socket", reaches aenum's default_missing_and raises.0x0000is alsoIPX's own class default fordst/src, so the class cannot construct itself with its own documented defaults:Rated MEDIUM rather than HIGH for one measured reason: through the full pipeline the
beholderwrapper catches it and degrades the layer toRaw, so a capture containing such a frame comes back asEthernet:Novell_Inc_0x8137with'error': '0 is not a valid Socket'instead of crashing. It silently loses the IPX parse rather than failing loudly. With a registered socket (0x0451) the identical packet parses fine, which isolates the cause to the missing bucket.3. LOW, and latent rather than live — two
_missing_methods lack@classmethodpcapkit/const/ftp/return_code.py:44(ResponseKind) and:66(GroupingInformation). aenum invokescls._missing_(value); without the decorator the lone argument binds to theclsparameter andvaluegoes unfilled:So every unknown value fails, not merely 0, and with a
TypeErrorthat the_missing_body was written to avoid. The sweep makes the intent unambiguous:Why LOW, stated plainly: these two
constclasses are imported by no runtime code.grepacrosspcapkit/,tests/andexamples/finds references only inpcapkit/const/ftp/return_code.pyitself and in the separate codegen copypcapkit/vendor/ftp/return_code.py, which carries the identical missing decorator at:73/:95and does call them at:124-125:That path is reachable only during vendor regeneration, and only for a reply code whose digits fall outside the defined members. Since codegen currently succeeds, no code in today's IANA registry triggers it. It is a one-line fix in two (really four) places and worth doing, but I am not claiming it breaks anything today.
The other six, checked and cleared
Six further enums also reject
0, and for all six that is correct —0is not a valid protocol value, so no change is wanted:ftp.return_code.ReturnCodeandhttp.status_code.StatusCode(both are 3-digit codes, 100-599),ftp.command.ConformanceRequirement,sctp.cause_code.CauseCodeandsctp.parameter.Parameter(registries that begin at 1, with 0 reserved), andmh.mn_id_subtype.MNIDSubtype(subtypes begin at 1 with NAI — the enum behind #469/#481).So of 111 enums swept: 102 accept 0, 6 rightly reject it, 2 are defects (1 and 2 above), and 1 is the broken-signature case.
Suggested shape
For 1 and 2 the fix is a registry-accuracy one — add the missing
0member (RouterAlertgets RFC 2113's "Router shall examine packet";Socketgets an unspecified-socket entry or a_missing_bucket reaching down to0x0000) in bothpcapkit/const/and the matchingpcapkit/vendor/generator, or the next regeneration reverts it. For 3, add@classmethodin both files.A test sweeping every
pcapkit.constIntEnumfor "doesEnum(0)behave as the registry says it should" would pin all of this permanently; the probe above is ~20 lines and already does the enumeration.