Is this a bug or a feature request? A breaking design change, ruled on in #801.
Step 1 of #801's three. The maintainer's ruling, verbatim:
I feel like now that we're already using transport specific enums, we should avoid ambiguity from the enums in all sense. so... yes, go with your recommendation.
What changes
AppType.proto becomes the single transport of the registry the member lives in, not the whole IANA set. TCP['http'].proto goes tcp|udp|sctp → tcp.
register_apptype takes varargs instead of a proto kwarg, per the maintainer: "keeping everything singular and explicit".
def register_apptype(code: 'int | Enum_AppType', module: 'str | ModuleDescriptor[ProtocolBase] | Type[ProtocolBase]',
*transport: 'TransportProtocol', class_: 'str' = NULL) -> 'None':
class_ becomes keyword-only — that is deliberate and is the one divergence from the sibling register_* functions. Do NOT put *transport after class_: class_ is positional with a default, so a third positional argument binds to it and the transport is silently eaten. Measured:
(code, module, class_=NULL, *transport): f(member, Unit, TP.udp) -> class_='TP.udp', transport=()
(code, module, *transport, class_=NULL): f(member, Unit, TP.udp) -> transport=('TP.udp',)
Ruled sub-case: an Enum_AppType member with no explicit *transport uses the member's own proto — single-bit after this change, so it names exactly one registry. A bare int with no *transport stays an error.
Why the two are one issue: retyping removes the multi-bit value that protocols.py:833's proto = code.proto default relies on to fan out across {tcp, udp} at :846. Landing either alone leaves the other broken.
Expected behavior
Every member's proto names exactly its own registry; register_apptype requires transports to be named one at a time; no code path constructs or consumes a composite TransportProtocol.
Additional context
This is breaking for 10,625 of 12,391 members, because proto.name is folded into the member's underlying str value, not merely its display — pcapkit/vendor/reg/apptype/apptype.py:250 (temp = '%s [%d - %s]' % (name, value, proto.name), assigned to obj._value_), with __repr__ at :270 and __str__ at :273. So TCP['http'].value goes 'http [80 - tcp|udp|sctp]' → 'http [80 - tcp]'. _value_ is the live lookup key in _value2member_map_, so this must happen at generation time, never at runtime. Identity survives pickle, copy and deepcopy either way.
Verified migration surface, line numbers re-read against main (477ed00c4) — earlier citations in this thread were wrong, so trust these and re-derive rather than copying older comments:
pcapkit/vendor/reg/apptype/apptype.py:250 __new__, :270 __repr__, :273 __str__, :473 the docstring promising "the whole transport protocol set", :752 the emit condition if self.TRANSPORT not in record.protos.
- The same three format strings generated into
pcapkit/const/reg/apptype/apptype.py, plus the docstring duplicated into all four of const/reg/apptype/{tcp,udp,sctp,dccp}.py:21.
tests/const/test_const_apptype_split_unit.py:80 — assertEqual(TCP.http.proto, UDP.http.proto), which this change falsifies by design. That file is 415 lines with 15 test methods; ignore any citation above 415.
tests/foundation/registry/test_protocols.py:476, :484, :493, :499 — the only four register_apptype calls in the repo. :493 is the three-positional one.
Do not regenerate to verify. AppType.LINK fetches IANA's live CSV, so a regeneration is not reproducible. Hand-edit the generator and its output, then prove equivalence by rendering BASE(...) and diffing — 0 diff lines outside the intended region. BASE is a lambda returning an f-string, so braces in emitted code must be doubled.
Measurements that justify this, so they need not be redone: the multi-bit value is fully derivable — 7,054 (svc, port) groups, 0 disagreements, and 0 single-registry groups carrying a multi-bit proto. Per-registry: TCP 6147 / UDP 6143 / SCTP 91 / DCCP 10. register_apptype(TCP.http, Dummy) today displaces httpv1.HTTP from TCP and http.HTTP from UDP in one call.
Related: #801, #732, #759, #775, #804.
Is this a bug or a feature request? A breaking design change, ruled on in #801.
Step 1 of #801's three. The maintainer's ruling, verbatim:
What changes
AppType.protobecomes the single transport of the registry the member lives in, not the whole IANA set.TCP['http'].protogoestcp|udp|sctp→tcp.register_apptypetakes varargs instead of aprotokwarg, per the maintainer: "keeping everything singular and explicit".class_becomes keyword-only — that is deliberate and is the one divergence from the siblingregister_*functions. Do NOT put*transportafterclass_:class_is positional with a default, so a third positional argument binds to it and the transport is silently eaten. Measured:Ruled sub-case: an
Enum_AppTypemember with no explicit*transportuses the member's ownproto— single-bit after this change, so it names exactly one registry. A bareintwith no*transportstays an error.Why the two are one issue: retyping removes the multi-bit value that
protocols.py:833'sproto = code.protodefault relies on to fan out across{tcp, udp}at:846. Landing either alone leaves the other broken.Expected behavior
Every member's
protonames exactly its own registry;register_apptyperequires transports to be named one at a time; no code path constructs or consumes a compositeTransportProtocol.Additional context
This is
breakingfor 10,625 of 12,391 members, becauseproto.nameis folded into the member's underlyingstrvalue, not merely its display —pcapkit/vendor/reg/apptype/apptype.py:250(temp = '%s [%d - %s]' % (name, value, proto.name), assigned toobj._value_), with__repr__at:270and__str__at:273. SoTCP['http'].valuegoes'http [80 - tcp|udp|sctp]'→'http [80 - tcp]'._value_is the live lookup key in_value2member_map_, so this must happen at generation time, never at runtime. Identity survives pickle,copyanddeepcopyeither way.Verified migration surface, line numbers re-read against
main(477ed00c4) — earlier citations in this thread were wrong, so trust these and re-derive rather than copying older comments:pcapkit/vendor/reg/apptype/apptype.py:250__new__,:270__repr__,:273__str__,:473the docstring promising "the whole transport protocol set",:752the emit conditionif self.TRANSPORT not in record.protos.pcapkit/const/reg/apptype/apptype.py, plus the docstring duplicated into all four ofconst/reg/apptype/{tcp,udp,sctp,dccp}.py:21.tests/const/test_const_apptype_split_unit.py:80—assertEqual(TCP.http.proto, UDP.http.proto), which this change falsifies by design. That file is 415 lines with 15 test methods; ignore any citation above 415.tests/foundation/registry/test_protocols.py:476,:484,:493,:499— the only fourregister_apptypecalls in the repo.:493is the three-positional one.Do not regenerate to verify.
AppType.LINKfetches IANA's live CSV, so a regeneration is not reproducible. Hand-edit the generator and its output, then prove equivalence by renderingBASE(...)and diffing — 0 diff lines outside the intended region.BASEis a lambda returning an f-string, so braces in emitted code must be doubled.Measurements that justify this, so they need not be redone: the multi-bit value is fully derivable — 7,054
(svc, port)groups, 0 disagreements, and 0 single-registry groups carrying a multi-bitproto. Per-registry: TCP 6147 / UDP 6143 / SCTP 91 / DCCP 10.register_apptype(TCP.http, Dummy)today displaceshttpv1.HTTPfrom TCP andhttp.HTTPfrom UDP in one call.Related: #801, #732, #759, #775, #804.