Repository navigation
refactor(corekit)!: Info.to_dict() returns an OrderedMultiDict; add MultiInfo and OrderedMultiInfo (#1484) - #1523
Conversation
1f9d1e1 to
e2f35e7
Compare
|
Coverage: 89.66% (unit tier, Python 3.14,
Per-file detail: the |
|
Verdict: NEEDS CHANGES at Blocking:
Confirmed:
A question for the owner.
I recommend 2: it is a one-line correctness fix, and without it equality on exports is unreliable. |
e2f35e7 to
2cd7aee
Compare
|
Verdict: GOOD TO GO at
Still open for the owner: the |
|
Seems like we're not following Info subclass for the two next tho. |
|
You're right, they don't. I measured at
Which do you mean?
I recommend 2. It keeps your earlier ruling that they extend werkzeug's |
|
i prefer option 1 |
|
Recorded: the owner chose option 1 on the question above. One check: I've read "option 1" as answering the 00:17Z
Your #1516 ruling not to touch |
2cd7aee to
7b7f2c1
Compare
|
Verdict: GOOD TO GO at
The
I recommend 3: it fixes Not blocking: |
|
take option 3 |
|
Recorded: you chose option 3 for The worker is adding it to this branch. The change includes:
The same push fixes |
c75108e to
3c1f9b8
Compare
|
Verdict: NEEDS CHANGES at
Confirmed by the reviewer:
|
…ultiInfo and OrderedMultiInfo (#1484) - corekit/infoclass: add MultiInfo and OrderedMultiInfo, Info subclasses that also derive from MultiDict/OrderedMultiDict. They inherit from_dict and Info's finalisation, keep the multi-mapping protocol, refuse every mutation, read keys as attributes and keep every value of a repeated key. Info stores every MultiDict value as one of them, so a finalised Info holds no mutable multi-mapping. - Info.to_dict() returns an OrderedMultiDict at every level, and a MultiInfo/OrderedMultiInfo exports its plain multi-mapping; from_dict() restores them, including an annotated subclass (HTTP/2 Settings, now an OrderedMultiInfo). The OrderedMultiDict exports are a private subclass whose != negates ==, as OrderedMultiInfo's does, so two equal exports or option lists no longer compare unequal. - corekit/multidict: drop InfoDict; the module is Werkzeug's classes only. - dumpkit: write an Info's fields with every value of a repeated field, as a list; the PCAP and PCAP-NG engines hand the writers the Info itself. - protocols/data: retype the attribute annotations to OrderedMultiInfo and MultiInfo; PCAP-NG freezes the entries it holds in a tuple or dict. - tests: move the to_dict() assertions to the OrderedMultiDict contract. Every test directory and top-level test module passes, run one at a time.
3c1f9b8 to
94c3545
Compare
|
Verdict: GOOD TO GO at
Non-blocking nits:
|
Please follow the guide below
You will be asked some questions, please read them carefully and answer honestly
Put an
xinto all the boxes [ ] relevant to your pull request (like that [x])Use Preview tab to see how your pull request will actually look like
Searched for similar pull requests
Followed the coding style (
make pylint,make mypy,make isort)make testpasses, and a test case covers the changeAdded a changelog entry under
docs/source/changelog/and regeneratedCHANGELOG.md, if the change is user-visible — N/A — centralised in docs(changelog): shared 1.5.0 changelog — long-lived, merges last (#610, #616, #617, #618, #620) #657What is the purpose of your pull request?
Tick the commit type your subject line carries.
fix— corrects a defectfeat— adds a featureperf— changes performance, not behaviourrefactor— changes neither behaviour nor performancetest— tests onlydocs— documentation onlyci— workflows or build toolingrelease— bumps the version or rolls up a distributionchore— anything elseDescription of your pull request and other information
MultiInfo/OrderedMultiInfo(corekit/infoclass.py) areInfosubclasses that also derive fromMultiDict/OrderedMultiDict, via a private_MultiInfobase. They inheritfrom_dict,__init_subclass__and the finalisation rules; the mapping protocol is bound back to the multi-mapping's own, sinceInfoandMappingprecede it in the MRO. Mutators raiseUnsupportedCall, keys read as attributes, repeated keys keep every value, andlistvalues()hands out copies. The carve-out stays in those classes:__new__/__update__fill the multi-mapping,__setattr__admits only its bookkeeping, andinfo_finalgenerates no__init__for them.Infostores everyMultiDict/OrderedMultiDictvalue as one of them; PCAP-NG's journal and TLS entries are frozen where built; HTTP/2Settingsis anOrderedMultiInfo. Inprotocols/data, the 54 attribute annotations andSettings' base areOrderedMultiInfoand the 51__init__stubs keepOrderedMultiDict; 2MultiDict[...]attributes areMultiInfo.to_dict()returns anOrderedMultiDictat every level, as the private subclass_OrderedMultiDict, whose!=negates==(the owner's option 3;multidict.pystays verbatim Werkzeug).OrderedMultiInfogets the same__ne__, andMultiInfo's==/!=defer to an ordered operand, so==is symmetric and!=its negation across every kind (bar a bare WerkzeugOrderedMultiDicton the left of!=, or right of a bareMultiDict); copies, deep copies and pickles keep the class.from_dict()restores the*Infotypes. Dumpers write a repeated field as a list; the PCAP / PCAP-NG engines hand them theInfo.Breaking.
InfoDict(which compared like adict) is gone:to_dict() == {...}isFalseand!=True;dict(d),{**d}andjson.dumps(d)keep only the first value of a repeated key.type(d) is OrderedMultiDictisFalse(isinstanceholds)..copy(),copy.copyanddeepcopy, are immutable: useOrderedMultiDict(opts)orinfo.to_dict().type(opts) is OrderedMultiDictisFalse, andisinstance(opts, Info)is nowTrue.opts.to_dict()returns the plain multi-mapping (to_dict(flat=True)is the olddict);Settings().add()raises.to_dict()instead of theInfowrites nested fields as lists of single-key mappings.Ran one at a time: the #1484 modules,
tests/corekit,tests/dumpkit,tests/protocols/{misc,transport,internet}, the capture round trip andtests/test_final_enforcement.pyon 3.14, the last plus the #1484 modules on 3.11 — all green.==/!=are pinned across all 64 pairs of kinds, equal and reordered, both ways round. 6,823 layers across 23 captures rebuild byte-exactly frominfoandinfo.to_dict(); 277 frames and 261 option lists compare!=False; canonicalto_dict()output and all 69 dumps matchmain.Closes #1484