You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
refactor(corekit)!: Info.to_dict() returns an OrderedMultiDict; add MultiInfo and OrderedMultiInfo to infoclass #1484
Is your feature request related to a problem? Please describe. Info.to_dict() returns InfoDict (pcapkit/corekit/multidict.py:643, added by #1466). Measured on 00d232890 with an IPv6 packet carrying two Destination Options headers:
It is mutable: setting a key, add() and del all succeed, whereas Info refuses assignment with UnsupportedCall.
No attribute access: d.limit and d['opts'].next raise AttributeError, while info.limit works.
Dumps drop the repeated key: the JSON, tree and plist dumps each hold opts once, losing the second header. dumpkit/common.py:451,462 excludes InfoDict from the code that writes every value.
Wrong home: multidict.py copies Werkzeug's source, so an Info-specific class does not belong there.
Describe the solution you'd like
Per the owner, a MultiInfo class in pcapkit/corekit/infoclass.py replaces InfoDict:
to_dict() returns it;
it is immutable, with keys readable as attributes, like Info;
it keeps every value of a repeated key;
it builds on the multidict classes without editing that module;
the dumpers write every value of a repeated key.
from_dict(to_dict()) == info and the byte-exact rebuild must keep passing.
Open question: which base class. Werkzeug's MultiDict groups values by key and so loses the order of different keys. For an IPv6 chain of Opts, Route, Opts it yields opts, opts, route, and IPv6.from_data() then raises AttributeError: 'IPv6_Route' object has no attribute 'type'. OrderedMultiDict keeps the order on the wire and rebuilds byte-exactly. So MultiInfo needs OrderedMultiDict's ordering, whether by subclassing it or by reproducing that ordering on top of MultiDict.
Describe alternatives you've considered
Keeping InfoDict and fixing only the dumpers. Its mutability and missing attribute access would remain.
Additional context InfoDict came from #1453/#1466. Whether to rename infoclass to info is tracked in #1485.
I recall Info.to_dict was supposed to return a dict-like object directly. So returning an Info-like object here seems off the track.
We definitely would need MultiInfo and OrderedMultiInfo for other use cases for sure. But Info.to_dict should still return dict or MultiDict or OrderedMultiDict in my opinion.
Recorded: the owner wants Info.to_dict() to return a plain dict type, a dict, MultiDict or OrderedMultiDict, not something Info-like. MultiInfo and OrderedMultiInfo are still wanted, for other uses. The revised scope:
to_dict() returns OrderedMultiDict. The order matters: for an IPv6 chain Opts, Route, Opts, a MultiDict groups it as opts, opts, route and IPv6.from_data() raises, while OrderedMultiDict rebuilds byte-exactly.
Remove InfoDict. That puts pcapkit/corekit/multidict.py back to the Werkzeug-derived classes only. The dumpers already write every value of an OrderedMultiDict (dumpkit/common.py:451), so the repeated header returns to the JSON, tree and plist output.
Add MultiInfo and OrderedMultiInfo to pcapkit/corekit/infoclass.py. They are immutable, attribute-accessible and keep repeated keys, building on the multidict classes without editing them.
from_dict(to_dict()) == info and the byte-exact rebuild must still pass. This is still breaking, because to_dict()'s return type and its dict-interface semantics change.
Labelled pending. I'll start it once the #1202 corekit slice reports, because that slice is measuring Info ↔ dict on the current InfoDict.
changed the title [-]refactor(corekit)!: replace InfoDict with an immutable, attribute-accessible MultiInfo in infoclass[/-][+]refactor(corekit)!: Info.to_dict() returns an OrderedMultiDict; add MultiInfo and OrderedMultiInfo to infoclass[/+]on Oct 9, 2026
and one additional note, I think those parsed option lists where I suppose we used MultiDict or OrderedMultiDict to hold the wip data, we should convert them to MultiInfo and OrderedMultiInfo respectively when finalising as Info.
Recorded, as a fourth scope item. Option lists are built as MultiDict or OrderedMultiDict while a packet is parsed. When the Info is finalised, they should become MultiInfo or OrderedMultiInfo respectively, so a finalised Info holds no mutable mapping.
Measured on 00d232890:
Construction sites: 26 OrderedMultiDict( and 4 MultiDict( in pcapkit/protocols. The OrderedMultiDict( ones span 12 files: HTTP/1, HIP, HOPOPT, IPv4, IPv6, IPv6-Opts, MH, PCAP-NG, SCTP, TCP, and the IPv4 and PCAP-NG schemas.
Annotations: 106 OrderedMultiDict[...] annotations in pcapkit/protocols/data/, all to be retyped.
Round trip:to_dict() must turn a MultiInfo or OrderedMultiInfo field back into a plain MultiDict or OrderedMultiDict, and from_dict() must restore the *Info type, so the round trip stays byte-exact.
It stays pending, starting after the #1202 corekit slice.
Blocked until #1492 merges and the #1490 fix has landed. All three touch pcapkit/corekit/infoclass.py, and #1490 changes how Info subclasses are finalised, which MultiInfo and OrderedMultiInfo build on.
Both open questions are answered on #1523. MultiInfo and OrderedMultiInfo become real Info subclasses (option 1). For __ne__, multidict.py stays verbatim and to_dict() returns a thin subclass that adds __ne__ (option 3). The worker is implementing the second on #1523.
Activity
JarryShaw commentedon Oct 9, 2026
I recall Info.to_dict was supposed to return a dict-like object directly. So returning an Info-like object here seems off the track.
We definitely would need MultiInfo and OrderedMultiInfo for other use cases for sure. But Info.to_dict should still return dict or MultiDict or OrderedMultiDict in my opinion.
JarryShaw commentedon Oct 9, 2026
Recorded: the owner wants
Info.to_dict()to return a plain dict type, adict,MultiDictorOrderedMultiDict, not somethingInfo-like.MultiInfoandOrderedMultiInfoare still wanted, for other uses. The revised scope:to_dict()returnsOrderedMultiDict. The order matters: for an IPv6 chain Opts, Route, Opts, aMultiDictgroups it asopts, opts, routeandIPv6.from_data()raises, whileOrderedMultiDictrebuilds byte-exactly.InfoDict. That putspcapkit/corekit/multidict.pyback to the Werkzeug-derived classes only. The dumpers already write every value of anOrderedMultiDict(dumpkit/common.py:451), so the repeated header returns to the JSON, tree and plist output.MultiInfoandOrderedMultiInfotopcapkit/corekit/infoclass.py. They are immutable, attribute-accessible and keep repeated keys, building on themultidictclasses without editing them.from_dict(to_dict()) == infoand the byte-exact rebuild must still pass. This is still breaking, becauseto_dict()'s return type and itsdict-interface semantics change.Labelled
pending. I'll start it once the #1202 corekit slice reports, because that slice is measuringInfo↔ dict on the currentInfoDict.[-]refactor(corekit)!: replace InfoDict with an immutable, attribute-accessible MultiInfo in infoclass[/-][+]refactor(corekit)!: Info.to_dict() returns an OrderedMultiDict; add MultiInfo and OrderedMultiInfo to infoclass[/+]JarryShaw commentedon Oct 9, 2026
and one additional note, I think those parsed option lists where I suppose we used MultiDict or OrderedMultiDict to hold the wip data, we should convert them to MultiInfo and OrderedMultiInfo respectively when finalising as Info.
JarryShaw commentedon Oct 9, 2026
Recorded, as a fourth scope item. Option lists are built as
MultiDictorOrderedMultiDictwhile a packet is parsed. When theInfois finalised, they should becomeMultiInfoorOrderedMultiInforespectively, so a finalisedInfoholds no mutable mapping.Measured on
00d232890:OrderedMultiDict(and 4MultiDict(inpcapkit/protocols. TheOrderedMultiDict(ones span 12 files: HTTP/1, HIP, HOPOPT, IPv4, IPv6, IPv6-Opts, MH, PCAP-NG, SCTP, TCP, and the IPv4 and PCAP-NG schemas.OrderedMultiDict[...]annotations inpcapkit/protocols/data/, all to be retyped.to_dict()must turn aMultiInfoorOrderedMultiInfofield back into a plainMultiDictorOrderedMultiDict, andfrom_dict()must restore the*Infotype, so the round trip stays byte-exact.It stays
pending, starting after the #1202 corekit slice.JarryShaw commentedon Oct 9, 2026
Blocked until #1492 merges and the #1490 fix has landed. All three touch
pcapkit/corekit/infoclass.py, and #1490 changes howInfosubclasses are finalised, whichMultiInfoandOrderedMultiInfobuild on.2 remaining items
refactor(corekit)!: Info.to_dict() returns an OrderedMultiDict; add M…
refactor(corekit)!: Info.to_dict() returns an OrderedMultiDict; add M…
refactor(corekit)!: Info.to_dict() returns an OrderedMultiDict; add M…
JarryShaw commentedon Oct 10, 2026
Both open questions are answered on #1523.
MultiInfoandOrderedMultiInfobecome realInfosubclasses (option 1). For__ne__,multidict.pystays verbatim andto_dict()returns a thin subclass that adds__ne__(option 3). The worker is implementing the second on #1523.refactor(corekit)!: Info.to_dict() returns an OrderedMultiDict; add M…
refactor(corekit)!: Info.to_dict() returns an OrderedMultiDict; add M…
refactor(corekit)!: Info.to_dict() returns an OrderedMultiDict; add M…
refactor(corekit)!: Info.to_dict() returns an OrderedMultiDict; add M…