Target: 2.1.0 (Tier 3 — make typing the product)
_enums.py defines EtherType, IPProtocol, ARPOperation and
ARPHardwareType, but no decoded field is annotated with any of
them. reveal_type(Ethernet.decode(b"...").ethertype) is int. The
enums are used only as dict keys during dispatch and inside the
*_name display properties.
1.3.0 already established the right pattern for this with addresses:
IPv4.src stays a str and IPv4.src_address returns an
ipaddress.IPv4Address. Do the same for the enum registries.
What to do
Add ethertype_enum -> EtherType | None, protocol_enum -> IPProtocol | None, next_header_enum, oper_enum, and an htype_name /
htype_enum for ARP — ARPHardwareType is currently exported but
referenced nowhere outside its own definition.
Why accessors and not retyped fields
Annotating the wire field itself (ethertype: EtherType) is the
obvious move and it is the wrong one. An IntEnum field cannot hold a
value outside the enum, so any EtherType we do not enumerate would
either raise or need a pseudo-member — and round-trip fidelity for
unknown protocol numbers is worth more than the annotation. The corpus
already contains values we do not name.
Keeping the wire field int and offering a typed accessor preserves
bytes(decode(x)) == x for arbitrary input while giving typed code the
enum. It also costs nothing at decode time, since the accessor is lazy.
Acceptance criteria
Target: 2.1.0 (Tier 3 — make typing the product)
_enums.pydefinesEtherType,IPProtocol,ARPOperationandARPHardwareType, but no decoded field is annotated with any ofthem.
reveal_type(Ethernet.decode(b"...").ethertype)isint. Theenums are used only as dict keys during dispatch and inside the
*_namedisplay properties.1.3.0 already established the right pattern for this with addresses:
IPv4.srcstays astrandIPv4.src_addressreturns anipaddress.IPv4Address. Do the same for the enum registries.What to do
Add
ethertype_enum -> EtherType | None,protocol_enum -> IPProtocol | None,next_header_enum,oper_enum, and anhtype_name/htype_enumforARP—ARPHardwareTypeis currently exported butreferenced nowhere outside its own definition.
Why accessors and not retyped fields
Annotating the wire field itself (
ethertype: EtherType) is theobvious move and it is the wrong one. An
IntEnumfield cannot hold avalue outside the enum, so any EtherType we do not enumerate would
either raise or need a pseudo-member — and round-trip fidelity for
unknown protocol numbers is worth more than the annotation. The corpus
already contains values we do not name.
Keeping the wire field
intand offering a typed accessor preservesbytes(decode(x)) == xfor arbitrary input while giving typed code theenum. It also costs nothing at decode time, since the accessor is lazy.
Acceptance criteria
Nonerather than raising.