Skip to content

refactor!: hold mapping values in Info or Data, not dict subclasses (#2726) - #2734

Merged
JarryShaw merged 1 commit into
mainfrom
refactor/2726-dict-to-info
Nov 3, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
refactor/2726-dict-to-info

Conversation

@JarryShaw

@JarryShaw JarryShaw commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

What is the purpose of your pull request?

  • refactor — changes neither behaviour nor performance

This applies the owner's ruling against direct dict subclasses: use Info or Data where they fit, especially in protocols.data.

  • FrameRecord, a dict subclass shipped in 1.5.x, becomes an @info_final Info. It still maps the engine's dissection by key, with packet, frame_info and time_epoch as attributes. It is immutable, and its to_dict() exports only the mapping. Pickles written by 1.5.x still load.
  • The PCAP-NG Decryption Secrets Block's TLS entries, a plain dict, becomes TLSKeyLogEntries(Data), re-exported as PCAPNG_TLSKeyLogEntries. A plain mapping converts on construction.
  • to_dict() gives OrderedMultiDict containers for both, because the info round-trip test requires every export level to be one. Keys, values, the JSON, plist and tree dumps, and byte-exact from_data are unchanged.

MultiDict stays, per the owner. _Registries moves in #2729, the same file. _EnumRegistry waits on the decision in #2726. Pickles load across 1.5.1, main and this PR, apart from records that main pickled after #2722, which no release wrote.

Part of #2726

…2726)

- FrameRecord is an Info rather than a slotted dict subclass, so it is
  immutable and no dict. Its mapping is the engine's dissection; packet,
  frame_info and time_epoch sit under hidden dunder keys, read through
  __getattribute__, so a mapping key of the same name never shadows them.
  It pickles through _frame_record, as the 1.5 releases do, and to_dict()
  exports the mapping alone.
- TLSKeyLog.entries is a TLSKeyLogEntries data model keyed by label, not a
  plain dict, and a mapping given for it is stored as one. to_dict()
  exports it as an OrderedMultiDict, as #1484 requires of every level;
  TLSKeyLog pickles hold the entries as a dict and restore the model.
- The traced Packet's frame annotation names FrameRecord, and its
  versionchanged notes what from_dict(to_dict()) gives back; the pickle
  docs drop FrameRecord as their slotted-dict example.

Pickles load across main and 1.5.1 and this change both ways at protocols
0, 1, 2 and 5, except main's own FrameRecord pickles, a format no release
wrote. Dumps and from_data rebuilds match main. New tests fail on main.
@JarryShaw JarryShaw added this to the PyPCAPKit v1.6 milestone Nov 3, 2026
@JarryShaw JarryShaw added breaking Breaks public-facing behaviour or API (apply alongside the type label) refactor Restructuring for its own sake — neither a fix nor a new capability (refactor: prefix) review: good-to-go Cross-review at the current head says ready; CI state is separate labels Nov 3, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

GOOD TO GO at 0ffa3ca71, from a Sonnet review of 1fec46d74. Its suggestions are folded in: the version notes for the dropped to_dict attributes and for Packet.frame, and dropping the main-era-only pickle hooks. The commit is rebased onto ab7be2fb0.

@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Coverage: 94.45% (unit tier, Python 3.15, 0ffa3ca71, Unit Tests run success)

Package Statements Missed Branches Partial Cover
pcapkit (top level) 104 4 20 2 95.16%
pcapkit/const 21062 175 2914 156 98.58%
pcapkit/corekit 2861 76 916 37 96.80%
pcapkit/dumpkit 282 3 100 3 98.43%
pcapkit/foundation 3505 27 1216 32 98.75%
pcapkit/interface 138 4 52 3 96.32%
pcapkit/protocols 22632 150 5866 124 99.02%
pcapkit/toolkit 961 26 342 8 96.62%
pcapkit/utilities 533 7 144 5 98.23%
pcapkit/vendor 5590 2286 1280 214 55.75%

Per-file detail: the coverage-html artifact of this run.

@JarryShaw
JarryShaw merged commit 07ceaf7 into main Nov 3, 2026
66 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in PyPCAPKit Nov 3, 2026
@JarryShaw
JarryShaw deleted the refactor/2726-dict-to-info branch November 3, 2026 16:26
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Nov 3, 2026
JarryShaw added a commit that referenced this pull request Nov 3, 2026
- Breaking: FrameRecord is an Info and TLSKeyLog.entries a TLSKeyLogEntries
  data model, not dicts (#2734); a new entry with 1.5.1's behaviour, and
  pickles checked loading both ways.
- Fixed: MH's CGA Parameters maker builds a data model's raw extension and a
  schema without public_key_test (#2732), into the makers' Fixed entry.
- Fixed: a capture cut inside or in front of an option area reads as a short
  read in MH, HOPOPT and IPv6-Opts, and an odd item list raises ProtocolError
  (#2731, ab7be2f, which the merge of 07ceaf7 also brings in); the
  short-read ruling into the conventions entry.
- Old values measured against v1.5.1.
- CHANGELOG.md regenerated; util/changelog_md.py --check passes.
JarryShaw added a commit that referenced this pull request Nov 3, 2026


- Breaking: a short CALIPSO, SMF_DPD or MPL Opt Data Len raises ProtocolError,
  where 1.5.x raised FieldValueError, and a cut after the type octet reads
  short (#2737), a new entry; AppType.__registries__ is an Info, into the
  #2734 entry (#2735).
- Changed: const packages import their enumerations lazily through
  pcapkit.utilities.lazy.lazy_exports (#2735); the docs extra pins
  sphinx-autodoc-typehints 3.17.4 (#2742), as 1.5.0 recorded its pin.
- Fixed: the dumps keep a field renamed for clashing with an Info builtin
  name (#2736).
- Folded: the GraalPy leg's timeout and shards into the CI-legs entry
  (#2741); the #2735 and #2737 rulings into the conventions entry.
- No entry for the docs-only #2744 and #2746.
- 1.6.0's :func:`bytes` role is :class:`bytes`, so the changelog pages build
  with no nitpicky warning. Old values measured against v1.5.1.
- CHANGELOG.md regenerated; util/changelog_md.py --check passes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Breaks public-facing behaviour or API (apply alongside the type label) refactor Restructuring for its own sake — neither a fix nor a new capability (refactor: prefix)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant